'use client'

import { useState } from 'react'

import { useI18n } from '@/components/providers/i18n-provider'
import { Button, Field, Notice, Select } from '@/components/ui/controls'
import { Badge, Panel, PanelBody, PanelHeader, StatCard } from '@/components/ui/display'
import { api, ApiClientError } from '@/lib/api/client'
import { cn } from '@/lib/cn'

interface StressStep {
  loadDeltaPct: number
  peakRisk: number
  stabilityIndex: number
  assetsOverLimit: number
  worstAssetCode: string
  worstAssetLoadPct: number
  totalLoadMw: number
}

interface StressResult {
  regionCode: string | null
  steps: StressStep[]
  weakestAssetCode: string | null
  weakestAssetName: string
  weakestAssetNameAr: string
  breakingPointPct: number | null
  maximumSafeLoadMw: number
  headroomPct: number
  failureSequence: Array<{ assetCode: string; offsetMin: number; outcome: string; probability: number }>
}

/**
 * Grid stress test (§29).
 *
 * Demand is raised in steps until something gives. The chart is a plain table of steps
 * rather than a plotted curve because the interesting reading is discrete: the step at
 * which the first asset crosses its limit, and which asset it was.
 */
export function StressTestRunner({
  regions,
}: {
  regions: Array<{ code: string; name: string; nameAr: string }>
}) {
  const { t, locale, n } = useI18n()
  const ar = locale === 'ar'
  const [region, setRegion] = useState('')
  const [result, setResult] = useState<StressResult | null>(null)
  const [error, setError] = useState<string | null>(null)
  const [busy, setBusy] = useState(false)

  const run = async () => {
    setBusy(true)
    setError(null)
    try {
      setResult(
        await api.post<StressResult>('/api/stress-test', {
          regionCode: region || null,
          maxDeltaPct: 45,
          stepPct: 5,
        }),
      )
    } catch (cause) {
      setError(cause instanceof ApiClientError ? (ar ? cause.failure.messageAr : cause.failure.message) : String(cause))
    } finally {
      setBusy(false)
    }
  }

  return (
    <div className="space-y-4">
      <Panel>
        <PanelHeader title={t('stressTest.title')} subtitle={t('stressTest.subtitle')} />
        <PanelBody className="pt-0">
          <div className="flex flex-wrap items-end gap-3">
            <Field label={t('stressTest.scope')} htmlFor="stress-region" className="w-56">
              <Select
                id="stress-region"
                value={region}
                onChange={(event) => setRegion(event.target.value)}
              >
                <option value="">{t('stressTest.national')}</option>
                {regions.map((entry) => (
                  <option key={entry.code} value={entry.code}>
                    {ar ? entry.nameAr : entry.name}
                  </option>
                ))}
              </Select>
            </Field>
            <Button onClick={run} loading={busy}>
              {busy ? t('stressTest.running') : t('stressTest.run')}
            </Button>
          </div>
          {error ? <Notice tone="danger" className="mt-3">{error}</Notice> : null}
        </PanelBody>
      </Panel>

      {result ? (
        <>
          <div className="grid gap-3 sm:grid-cols-2 lg:grid-cols-4">
            <StatCard
              label={t('stressTest.breakingPoint')}
              value={result.breakingPointPct === null ? '—' : `+${n(result.breakingPointPct)}%`}
              state={result.breakingPointPct === null ? 'normal' : result.breakingPointPct <= 15 ? 'critical' : 'warning'}
              hint={result.breakingPointPct === null ? t('stressTest.noBreakingPoint') : undefined}
            />
            <StatCard
              label={t('stressTest.maxSafeLoad')}
              value={n(result.maximumSafeLoadMw)}
              unit="MW"
            />
            <StatCard
              label={t('stressTest.weakestAsset')}
              value={result.weakestAssetCode ?? '—'}
              hint={ar ? result.weakestAssetNameAr : result.weakestAssetName}
            />
            <StatCard
              label={t('cascade.affectedAssets')}
              value={n(result.failureSequence.filter((step) => step.outcome === 'failed').length)}
            />
          </div>

          <Panel>
            <PanelHeader
              title={t('stressTest.step')}
              action={<Badge tone="accent">{t('common.simulated')}</Badge>}
            />
            <PanelBody className="pt-0">
              <div className="overflow-x-auto">
                <table className="w-full min-w-[32rem] text-xs">
                  <thead>
                    <tr className="border-b border-border text-[10px] uppercase tracking-wide text-text-faint">
                      <th className="py-2 text-start font-medium">{t('stressTest.step')}</th>
                      <th className="py-2 text-end font-medium">{t('commandCenter.cards.totalLoad')}</th>
                      <th className="py-2 text-end font-medium">{t('common.riskScore')}</th>
                      <th className="py-2 text-end font-medium">{t('commandCenter.cards.gridStability')}</th>
                      <th className="py-2 text-end font-medium">{t('stressTest.assetsOverLimit')}</th>
                    </tr>
                  </thead>
                  <tbody>
                    {result.steps.map((step) => (
                      <tr
                        key={step.loadDeltaPct}
                        className={cn(
                          'border-b border-border/50 last:border-0',
                          result.breakingPointPct === step.loadDeltaPct && 'bg-critical/8',
                        )}
                      >
                        <td className="tnum py-2 text-text">+{n(step.loadDeltaPct)}%</td>
                        <td className="tnum py-2 text-end text-text-muted">{n(step.totalLoadMw)}</td>
                        <td className="tnum py-2 text-end text-text-muted">
                          {n(step.peakRisk, { maximumFractionDigits: 0 })}%
                        </td>
                        <td className="tnum py-2 text-end text-text-muted">
                          {n(step.stabilityIndex, { maximumFractionDigits: 1 })}
                        </td>
                        <td
                          className={cn(
                            'tnum py-2 text-end font-medium',
                            step.assetsOverLimit > 0 ? 'text-critical' : 'text-text-faint',
                          )}
                        >
                          {n(step.assetsOverLimit)}
                        </td>
                      </tr>
                    ))}
                  </tbody>
                </table>
              </div>
            </PanelBody>
          </Panel>

          {result.failureSequence.length > 0 ? (
            <Panel>
              <PanelHeader title={t('stressTest.sequence')} subtitle={result.weakestAssetCode ?? ''} />
              <PanelBody className="pt-0">
                <ol className="space-y-2">
                  {result.failureSequence.map((step, index) => (
                    <li key={`${step.assetCode}-${index}`} className="flex items-baseline gap-3 text-xs">
                      <span className="tnum w-12 shrink-0 text-end text-text-faint">
                        +{n(step.offsetMin)}
                      </span>
                      <span className="font-mono text-text">{step.assetCode}</span>
                      <span className="text-text-muted">{t(`cascade.outcome.${step.outcome}`)}</span>
                      <span className="tnum ms-auto text-text-faint">
                        {n(step.probability * 100, { maximumFractionDigits: 0 })}%
                      </span>
                    </li>
                  ))}
                </ol>
              </PanelBody>
            </Panel>
          ) : null}
        </>
      ) : null}
    </div>
  )
}
