'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 { Segmented, Switch } from '@/components/ui/controls'
import { DataTable, type Column } from '@/components/ui/data-table'
import { Panel, PanelBody, PanelHeader, StateBadge } from '@/components/ui/display'
import { ASSET_TYPE_KEYS, GRID_STATES } from '@/lib/domain/enums'
import { styleForRisk } from '@/lib/ui/state-styles'

/**
 * The full-page map: filters, the map itself, and a sortable table of exactly the same
 * assets. The table is not a fallback — it is how the same information is reached
 * without a pointing device, and how it is read by a screen reader (§47).
 */
export function MapExplorer({
  assets,
  regions,
}: {
  assets: MapAsset[]
  regions: MapRegion[]
}) {
  const { t, locale, n, mw } = useI18n()
  const { snapshot } = useLiveGrid()

  const [typeFilter, setTypeFilter] = useState<string>('all')
  const [stateFilter, setStateFilter] = useState<string>('all')
  const [selected, setSelected] = useState<MapAsset | null>(null)
  const [heatmap, setHeatmap] = useState(true)
  const [lines, setLines] = useState(true)
  const [labels, setLabels] = useState(true)

  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)
      return live
        ? { ...asset, risk: live.risk, state: live.state, loadPct: live.loadPct, tempC: live.tempC }
        : asset
    })
  }, [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)
      return live ? { ...region, peakRisk: live.peakRisk, state: live.state, loadMw: live.loadMw } : region
    })
  }, [regions, snapshot])

  const filtered = useMemo(
    () =>
      liveAssets.filter(
        (asset) =>
          (typeFilter === 'all' || asset.typeKey === typeFilter) &&
          (stateFilter === 'all' || asset.state === stateFilter),
      ),
    [liveAssets, typeFilter, stateFilter],
  )

  const columns: Array<Column<MapAsset>> = [
    {
      key: 'code',
      header: t('assets.columns.code'),
      sortValue: (row) => row.code,
      cell: (row) => (
        <Link
          href={`/assets/${encodeURIComponent(row.code)}`}
          className="font-mono text-xs text-brand hover:underline"
        >
          {row.code}
        </Link>
      ),
    },
    {
      key: 'name',
      header: t('assets.columns.name'),
      sortValue: (row) => (locale === 'ar' ? row.nameAr : row.name),
      cell: (row) => (
        <span className="block max-w-64 truncate text-text">
          {locale === 'ar' ? row.nameAr : row.name}
        </span>
      ),
    },
    {
      key: 'type',
      header: t('assets.columns.type'),
      secondary: true,
      sortValue: (row) => row.typeKey,
      cell: (row) => <span className="text-text-muted">{t(`assetType.${row.typeKey}`)}</span>,
    },
    {
      key: 'region',
      header: t('assets.columns.region'),
      secondary: true,
      sortValue: (row) => row.regionCode,
      cell: (row) => <span className="font-mono text-xs text-text-muted">{row.regionCode}</span>,
    },
    {
      key: 'capacity',
      header: t('assets.columns.capacity'),
      align: 'end',
      secondary: true,
      sortValue: (row) => row.capacityMw,
      cell: (row) => <span className="tnum text-text-muted">{mw(row.capacityMw)}</span>,
    },
    {
      key: 'load',
      header: t('assets.columns.load'),
      align: 'end',
      sortValue: (row) => row.loadPct,
      cell: (row) => <span className="tnum">{n(row.loadPct, { maximumFractionDigits: 0 })}%</span>,
    },
    {
      key: 'risk',
      header: t('assets.columns.risk'),
      align: 'end',
      sortValue: (row) => row.risk,
      cell: (row) => (
        <span className={`tnum font-medium ${styleForRisk(row.risk).text}`}>
          {n(row.risk, { maximumFractionDigits: 0 })}%
        </span>
      ),
    },
    {
      key: 'state',
      header: t('map.filterState'),
      align: 'end',
      sortValue: (row) => row.risk,
      cell: (row) => (
        <StateBadge state={row.state} label={t(`states.${row.state}`)} size="sm" />
      ),
    },
  ]

  return (
    <div className="space-y-6">
      <Panel className="overflow-hidden">
        <PanelHeader
          title={t('map.layers')}
          action={
            <div className="flex flex-wrap items-center gap-4">
              <Switch checked={heatmap} onChange={setHeatmap} label={t('map.heatmap')} />
              <Switch checked={lines} onChange={setLines} label={t('map.showLines')} />
              <Switch checked={labels} onChange={setLabels} label={t('map.showLabels')} />
            </div>
          }
        />
        <PanelBody className="space-y-3 pb-0">
          <div className="flex flex-wrap items-center gap-3">
            <Segmented
              ariaLabel={t('map.filterState')}
              value={stateFilter}
              onChange={setStateFilter}
              size="sm"
              options={[
                { value: 'all', label: t('common.all') },
                ...GRID_STATES.map((state) => ({
                  value: state as string,
                  label: t(`states.${state}`),
                })),
              ]}
            />
            <Segmented
              ariaLabel={t('map.filterType')}
              value={typeFilter}
              onChange={setTypeFilter}
              size="sm"
              options={[
                { value: 'all', label: t('common.all') },
                ...ASSET_TYPE_KEYS.map((key) => ({
                  value: key as string,
                  label: t(`assetType.${key}`),
                })),
              ]}
            />
          </div>
        </PanelBody>

        <div className="mt-3">
          <NationalMap
            assets={filtered}
            regions={liveRegions}
            selectedCode={selected?.code ?? null}
            onSelect={setSelected}
            showHeatmap={heatmap}
            showLines={lines}
            showLabels={labels}
            className="h-[520px] border-t border-border"
          />
        </div>
      </Panel>

      <Panel>
        <PanelHeader
          title={t('common.assets')}
          subtitle={t('map.assetsShown', { count: filtered.length })}
        />
        <PanelBody>
          <DataTable
            rows={filtered}
            columns={columns}
            getRowKey={(row) => row.code}
            searchable={(row) => `${row.code} ${row.name} ${row.nameAr} ${row.regionCode}`}
            initialSort={{ key: 'risk', direction: 'desc' }}
            onRowClick={(row) => setSelected(row)}
            caption={t('map.title')}
            pageSize={20}
          />
        </PanelBody>
      </Panel>
    </div>
  )
}
