'use client'

import { useMemo, useState } from 'react'
import Link from 'next/link'

import { NationalMap, type MapAsset, type MapRegion } from '@/components/map/national-map'
import { useI18n } from '@/components/providers/i18n-provider'
import { useLiveGrid } from '@/components/providers/live-grid-provider'
import { Panel, PanelHeader, StateBadge } from '@/components/ui/display'
import { Segmented, Switch } from '@/components/ui/controls'
import { styleForRisk } from '@/lib/ui/state-styles'

/**
 * The map panel used on the Command Center and the map page.
 *
 * Asset geometry and identity come from the server render (they change on the order of
 * days); risk and loading are patched from the live stream on every tick. Re-sending
 * 250 asset records every three seconds to update one number each would be wasteful.
 */
export function LiveMapPanel({
  assets,
  regions,
  height = 460,
  showControls = true,
  showAside = true,
  title,
}: {
  assets: MapAsset[]
  regions: MapRegion[]
  height?: number
  showControls?: boolean
  /** Hidden where the page supplies its own, richer, side panel (§11). */
  showAside?: boolean
  title?: string
}) {
  const { t, locale, n, mw } = useI18n()
  const { snapshot } = useLiveGrid()
  const [selected, setSelected] = useState<MapAsset | null>(null)
  const [heatmap, setHeatmap] = useState(true)
  const [lines, setLines] = useState(true)
  const [labels, setLabels] = useState(true)
  const [layer, setLayer] = useState<'risk' | 'load' | 'prediction' | 'maintenance'>('risk')

  const liveAssets = useMemo(() => {
    if (!snapshot) return assets
    const patch = new Map(snapshot.topAssets.map((asset) => [asset.code, asset]))
    return assets.map((asset) => {
      const live = patch.get(asset.code)
      if (!live) return asset
      return {
        ...asset,
        risk: live.risk,
        state: live.state,
        loadPct: live.loadPct,
        tempC: live.tempC,
      }
    })
  }, [assets, snapshot])

  const liveRegions = useMemo(() => {
    if (!snapshot) return regions
    const patch = new Map(snapshot.regions.map((region) => [region.code, region]))
    return regions.map((region) => {
      const live = patch.get(region.code)
      if (!live) return region
      return { ...region, peakRisk: live.peakRisk, state: live.state, loadMw: live.loadMw }
    })
  }, [regions, snapshot])

  return (
    <Panel className="overflow-hidden">
      <PanelHeader
        title={title ?? t('commandCenter.liveMap')}
        subtitle={t('map.offlineNote')}
        action={
          showControls ? (
            <div className="flex flex-wrap items-center gap-4">
              <Segmented
                ariaLabel={t('twin.layers')}
                size="sm"
                value={layer}
                onChange={setLayer}
                options={[
                  { value: 'risk' as const, label: t('twin.layer.risk') },
                  { value: 'load' as const, label: t('twin.layer.load') },
                  { value: 'prediction' as const, label: t('twin.layer.prediction') },
                  { value: 'maintenance' as const, label: t('twin.layer.maintenance') },
                ]}
              />
              <Switch checked={heatmap} onChange={setHeatmap} label={t('map.heatmap')} />
              <Switch checked={lines} onChange={setLines} label={t('twin.layer.flow')} />
              <Switch checked={labels} onChange={setLabels} label={t('map.showLabels')} />
            </div>
          ) : null
        }
      />

      <div className={showAside ? 'grid lg:grid-cols-[1fr_280px]' : 'grid'}>
        <NationalMap
          assets={liveAssets}
          regions={liveRegions}
          selectedCode={selected?.code ?? null}
          onSelect={setSelected}
          showHeatmap={heatmap}
          showLines={lines}
          showLabels={labels}
          layer={layer}
          className={showAside ? 'border-e border-border' : undefined}
          compact={!showControls}
        />

        {showAside ? (
        <aside className="max-h-[520px] overflow-y-auto p-4" style={{ minHeight: height * 0.5 }}>
          {selected ? (
            <div className="nabdh-enter">
              <div className="flex items-start justify-between gap-2">
                <div className="min-w-0">
                  <p className="font-mono text-xs text-brand">{selected.code}</p>
                  <h3 className="mt-1 text-sm font-semibold text-text">
                    {locale === 'ar' ? selected.nameAr : selected.name}
                  </h3>
                </div>
                <StateBadge
                  state={selected.state}
                  label={t(`states.${selected.state}`)}
                  size="sm"
                  pulse={selected.risk >= 75}
                />
              </div>

              <dl className="mt-4 space-y-1.5 text-xs">
                <Row label={t('common.type')} value={t(`assetType.${selected.typeKey}`)} />
                <Row label={t('common.region')} value={selected.regionCode} />
                <Row
                  label={t('common.capacity')}
                  value={`${mw(selected.capacityMw)} ${t('common.units.mw')}`}
                />
                <Row
                  label={t('assets.columns.load')}
                  value={`${n(selected.loadPct, { maximumFractionDigits: 1 })}%`}
                />
                <Row
                  label={t('assets.columns.temperature')}
                  value={`${n(selected.tempC, { maximumFractionDigits: 1 })} ${t('common.units.celsius')}`}
                />
                <Row
                  label={t('common.riskScore')}
                  value={
                    <span className={styleForRisk(selected.risk).text}>
                      {n(selected.risk, { maximumFractionDigits: 0 })}%
                    </span>
                  }
                />
              </dl>

              <Link
                href={`/assets/${encodeURIComponent(selected.code)}`}
                className="mt-4 block rounded-lg border border-brand/40 bg-brand/10 px-3 py-2 text-center text-xs font-medium text-brand transition-colors hover:bg-brand/18"
              >
                {t('commandCenter.openAsset')}
              </Link>
            </div>
          ) : (
            <div>
              <p className="text-xs leading-relaxed text-text-muted">{t('map.selectAsset')}</p>

              <div className="mt-5 space-y-1.5">
                <p className="text-[10px] font-semibold uppercase tracking-wide text-text-faint">
                  {t('grid.regionTable')}
                </p>
                {[...liveRegions]
                  .sort((a, b) => b.peakRisk - a.peakRisk)
                  .map((region) => (
                    <div
                      key={region.code}
                      className="flex items-center justify-between gap-2 rounded-lg border border-border bg-surface-2/40 px-2.5 py-2"
                    >
                      <span className="truncate text-xs text-text">
                        {locale === 'ar' ? region.nameAr : region.name}
                      </span>
                      <span className="flex shrink-0 items-center gap-2">
                        <span className="tnum text-[11px] text-text-muted">
                          {mw(region.loadMw)}
                        </span>
                        <span
                          className={`tnum text-[11px] font-medium ${styleForRisk(region.peakRisk).text}`}
                        >
                          {n(region.peakRisk, { maximumFractionDigits: 0 })}%
                        </span>
                      </span>
                    </div>
                  ))}
              </div>
            </div>
          )}
        </aside>
        ) : null}
      </div>
    </Panel>
  )
}

function Row({ label, value }: { label: string; value: React.ReactNode }) {
  return (
    <div className="flex items-baseline justify-between gap-3">
      <dt className="text-text-muted">{label}</dt>
      <dd className="tnum text-end font-medium text-text">{value}</dd>
    </div>
  )
}
