'use client'

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

import { useI18n } from '@/components/providers/i18n-provider'
import { KeyValue, Meter, Panel, PanelBody, PanelHeader } from '@/components/ui/display'
import { Notice } from '@/components/ui/controls'
import { api, ApiClientError } from '@/lib/api/client'
import { cn } from '@/lib/cn'
import { DependencyView, type DependencyNode } from './dependency-view'
import type { SceneAssetState } from './twin-scene-2d'

/**
 * The asset inspector (§17, §28).
 *
 * Opens on whatever is selected in the scene. The tabs the operator opens most — what it
 * is doing now and how healthy it is — are answered from data the page already has, so
 * they appear instantly; the deeper tabs fetch on demand, once, and keep what they
 * fetched. A panel that reloads the world every time a tab is clicked teaches people to
 * stop clicking tabs.
 */

const TABS = [
  'overview',
  'live',
  'health',
  'prediction',
  'dna',
  'dependencies',
  'simulations',
  'history',
] as const
type Tab = (typeof TABS)[number]

interface AssetDetail {
  asset: {
    code: string
    name: string
    nameAr: string
    type: string
    region: string
    capacityMw: number
    voltageKv: number
    ratedTempC: number
    customersServed: number
  }
  telemetry: Record<string, number | boolean>
  risk: { score: number; topFactors: Array<{ key: string; contribution: number; unit: string; rawValue: number }> }
  rulDays: number
  prediction: {
    probability: number
    confidence: number
    etaMinutes: number | null
    eventType: string
    breachReason: string | null
  }
  dnaMatches: Array<{ code: string; similarity: number }>
  actions: Array<{ key: string; title: string; titleAr: string; riskReduction: number }>
}

interface Dependencies {
  upstream: DependencyNode[]
  focus: DependencyNode | null
  downstream: DependencyNode[]
  downstreamCustomers: number
}

export function TwinInspector({
  twinCode,
  state,
  simulations,
  snapshots,
  className,
}: {
  twinCode: string
  state: SceneAssetState & { name: string; nameAr: string; assetTypeKey: string; capacityMw: number; customersServed: number; healthScore: number; voltageKv: number; currentA: number; powerFactor: number; thdPct: number; ambientC: number; voltageDeviationPct: number }
  simulations: Array<{ code: string; createdAt: number; riskBefore: number; riskAfter: number; summary: string; summaryAr: string }>
  snapshots: Array<{ code: string; ts: number; reason: string; peakRisk: number }>
  className?: string
}) {
  const { t, locale, n, dateTime } = useI18n()
  const ar = locale === 'ar'

  const [tab, setTab] = useState<Tab>('overview')
  const [detail, setDetail] = useState<AssetDetail | null>(null)
  const [dependencies, setDependencies] = useState<Dependencies | null>(null)
  const [error, setError] = useState<string | null>(null)
  const [loading, setLoading] = useState(false)

  // Reset when the selection changes: showing the previous asset's prediction under the
  // new asset's name would be worse than showing nothing.
  useEffect(() => {
    setDetail(null)
    setDependencies(null)
    setError(null)
  }, [state.code])

  useEffect(() => {
    const needsDetail = tab === 'prediction' || tab === 'dna'
    const needsDeps = tab === 'dependencies'
    if ((needsDetail && detail) || (needsDeps && dependencies) || (!needsDetail && !needsDeps)) return

    let cancelled = false
    setLoading(true)
    setError(null)
    ;(async () => {
      try {
        if (needsDetail) {
          const data = await api.get<AssetDetail>(`/api/assets/${encodeURIComponent(state.code)}`)
          if (!cancelled) setDetail(data)
        } else {
          const data = await api.get<{ dependencies: Dependencies }>(
            `/api/digital-twin/${encodeURIComponent(twinCode)}/topology?focus=${encodeURIComponent(state.code)}`,
          )
          if (!cancelled) setDependencies(data.dependencies)
        }
      } catch (cause) {
        if (!cancelled) {
          setError(
            cause instanceof ApiClientError
              ? ar
                ? cause.failure.messageAr
                : cause.failure.message
              : String(cause),
          )
        }
      } finally {
        if (!cancelled) setLoading(false)
      }
    })()

    return () => {
      cancelled = true
    }
  }, [tab, state.code, twinCode, detail, dependencies, ar])

  return (
    <Panel className={className}>
      <PanelHeader
        title={`${state.code} · ${ar ? state.nameAr : state.name}`}
        subtitle={t(`assetType.${state.assetTypeKey}`)}
        action={
          <Link
            href={`/assets/${encodeURIComponent(state.code)}`}
            className="shrink-0 text-[11px] font-medium text-brand hover:underline"
          >
            {t('assets.passport.title')}
          </Link>
        }
      />

      <div className="flex flex-wrap gap-1 border-b border-border px-4 pb-2">
        {TABS.map((entry) => (
          <button
            key={entry}
            type="button"
            onClick={() => setTab(entry)}
            aria-pressed={tab === entry}
            className={cn(
              'rounded-md px-2 py-1 text-[11px] font-medium transition-colors',
              tab === entry ? 'bg-brand/16 text-brand' : 'text-text-muted hover:bg-surface-2 hover:text-text',
            )}
          >
            {t(`twin.tab.${entry}`)}
          </button>
        ))}
      </div>

      <PanelBody className="pt-3">
        {error ? <Notice tone="danger">{error}</Notice> : null}
        {loading ? <p className="text-xs text-text-muted">{t('uiState.loading')}</p> : null}

        {tab === 'overview' ? (
          <div className="grid gap-x-6 gap-y-1 sm:grid-cols-2">
            <KeyValue label={t('assets.columns.load')} value={`${n(state.loadPct, { maximumFractionDigits: 1 })}%`} mono />
            <KeyValue label={t('assets.columns.temperature')} value={`${n(state.tempC, { maximumFractionDigits: 1 })} °C`} mono />
            <KeyValue label={t('common.riskScore')} value={`${n(state.riskScore, { maximumFractionDigits: 0 })}%`} mono />
            <KeyValue label={t('assets.passport.currentHealth')} value={`${n(state.healthScore, { maximumFractionDigits: 0 })}%`} mono />
            <KeyValue label={t('grid.columns.capacity')} value={`${n(state.capacityMw)} MW`} mono />
            <KeyValue label={t('futures.customers')} value={n(state.customersServed)} mono />
          </div>
        ) : null}

        {tab === 'live' ? (
          <div className="grid gap-x-6 gap-y-1 sm:grid-cols-2">
            <KeyValue label={t('assets.columns.voltage')} value={`${n(state.voltageKv, { maximumFractionDigits: 2 })} kV`} mono />
            <KeyValue label={t('weakSignals.key.voltage')} value={`${n(state.voltageDeviationPct, { maximumFractionDigits: 2 })}%`} mono />
            <KeyValue label={t('assets.columns.current')} value={`${n(state.currentA, { maximumFractionDigits: 0 })} A`} mono />
            <KeyValue label={t('assets.columns.powerFactor')} value={n(state.powerFactor, { maximumFractionDigits: 3 })} mono />
            <KeyValue label="THD" value={`${n(state.thdPct, { maximumFractionDigits: 2 })}%`} mono />
            <KeyValue label={t('map.ambient')} value={`${n(state.ambientC, { maximumFractionDigits: 1 })} °C`} mono />
          </div>
        ) : null}

        {tab === 'health' ? (
          <div className="space-y-3">
            <Meter
              value={state.healthScore}
              state={state.healthScore >= 80 ? 'normal' : state.healthScore >= 60 ? 'watch' : 'critical'}
              label={t('assets.passport.currentHealth')}
              showValue
            />
            <Meter
              value={state.thermalStress * 100}
              state={state.thermalStress > 0.75 ? 'critical' : state.thermalStress > 0.5 ? 'warning' : 'normal'}
              label={t('twin.view.thermal')}
              showValue
            />
            <Meter
              value={Math.min(Math.abs(state.loadPct), 130)}
              max={130}
              state={Math.abs(state.loadPct) >= 100 ? 'critical' : Math.abs(state.loadPct) >= 85 ? 'warning' : 'normal'}
              label={t('assets.columns.load')}
              showValue
            />
          </div>
        ) : null}

        {tab === 'prediction' && detail ? (
          <div className="space-y-2">
            <div className="grid gap-x-6 gap-y-1 sm:grid-cols-2">
              <KeyValue
                label={t('preventionWindow.eventIn')}
                value={
                  detail.prediction.etaMinutes === null
                    ? t('common.notAvailable')
                    : `${n(detail.prediction.etaMinutes)} ${t('common.minutes')}`
                }
                mono
              />
              <KeyValue label={t('predictions.columns.probability')} value={`${n(detail.prediction.probability * 100, { maximumFractionDigits: 0 })}%`} mono />
              <KeyValue label={t('confidence.title')} value={`${n(detail.prediction.confidence, { maximumFractionDigits: 0 })}%`} mono />
              <KeyValue label={t('predictions.columns.eventType')} value={t(`eventType.${detail.prediction.eventType}`)} />
            </div>
            <div className="border-t border-border/60 pt-2">
              <p className="text-[10px] uppercase tracking-wide text-text-faint">{t('rootCause.evidence')}</p>
              <ul className="mt-1.5 space-y-1">
                {detail.risk.topFactors.slice(0, 4).map((factor) => (
                  <li key={factor.key} className="flex items-baseline justify-between gap-3 text-[11px]">
                    <span className="text-text-muted">{t(`riskFactor.${factor.key}`)}</span>
                    <span className="tnum text-text">
                      +{n(factor.contribution, { maximumFractionDigits: 1 })}
                    </span>
                  </li>
                ))}
              </ul>
            </div>
          </div>
        ) : null}

        {tab === 'dna' && detail ? (
          detail.dnaMatches.length === 0 ? (
            <p className="text-xs text-text-muted">{t('uiState.empty')}</p>
          ) : (
            <ul className="space-y-2">
              {detail.dnaMatches.map((match) => (
                <li key={match.code} className="flex items-center justify-between gap-3">
                  <span className="font-mono text-[11px] text-text">{match.code}</span>
                  <div className="flex flex-1 items-center gap-2">
                    <Meter value={match.similarity} state={match.similarity >= 75 ? 'critical' : 'watch'} />
                    <span className="tnum shrink-0 text-[11px] text-text">
                      {n(match.similarity, { maximumFractionDigits: 0 })}%
                    </span>
                  </div>
                </li>
              ))}
            </ul>
          )
        ) : null}

        {tab === 'dependencies' && dependencies ? (
          <DependencyView
            upstream={dependencies.upstream}
            focus={dependencies.focus}
            downstream={dependencies.downstream}
            downstreamCustomers={dependencies.downstreamCustomers}
          />
        ) : null}

        {tab === 'simulations' ? (
          simulations.length === 0 ? (
            <p className="text-xs text-text-muted">{t('uiState.empty')}</p>
          ) : (
            <ul className="divide-y divide-border/60">
              {simulations.map((simulation) => (
                <li key={simulation.code} className="py-2">
                  <div className="flex items-baseline justify-between gap-2">
                    <span className="font-mono text-[10px] text-text-faint">{simulation.code}</span>
                    <span className="tnum text-[11px]">
                      <span className="text-critical">{n(simulation.riskBefore, { maximumFractionDigits: 0 })}%</span>
                      {' → '}
                      <span className="text-normal">{n(simulation.riskAfter, { maximumFractionDigits: 0 })}%</span>
                    </span>
                  </div>
                  <p className="mt-0.5 text-[11px] leading-relaxed text-text-muted">
                    {ar ? simulation.summaryAr : simulation.summary}
                  </p>
                </li>
              ))}
            </ul>
          )
        ) : null}

        {tab === 'history' ? (
          snapshots.length === 0 ? (
            <p className="text-xs text-text-muted">{t('uiState.empty')}</p>
          ) : (
            <ul className="divide-y divide-border/60">
              {snapshots.map((snapshot) => (
                <li key={snapshot.code} className="flex items-baseline justify-between gap-3 py-2 text-[11px]">
                  <span className="font-mono text-text-faint">{snapshot.code}</span>
                  <span className="text-text-muted">{t(`twin.snapshot`)} · {snapshot.reason}</span>
                  <span className="tnum text-text-faint">{dateTime(snapshot.ts)}</span>
                </li>
              ))}
            </ul>
          )
        ) : null}

        {(tab === 'prediction' || tab === 'dna') && !detail && !loading && !error ? (
          <p className="text-xs text-text-muted">{t('uiState.loading')}</p>
        ) : null}
      </PanelBody>
    </Panel>
  )
}
