'use client'

import { useState } from 'react'

import { Button, Notice, Segmented, Select } from '@/components/ui/controls'
import { Badge, EmptyState, Meter, Panel, PanelBody, PanelHeader } from '@/components/ui/display'
import { useI18n } from '@/components/providers/i18n-provider'
import { api } from '@/lib/api/client'
import { cn } from '@/lib/cn'
import { formatDateTime, formatNumber } from '@/lib/i18n/translate'

/**
 * The Autonomous Risk Hunter (4.1).
 *
 * Every other search in the platform answers a question somebody asked. This one starts
 * from the observation that people ask about the failures they already imagine, and goes
 * looking for the ones they do not.
 *
 * Two disciplines are visible on the screen rather than hidden behind it. The budget line
 * reports what the search actually spent, so a search cut short can never be read as an
 * exhaustive sweep. And a prevention is labelled POTENTIAL FAILURE PREVENTED — SIMULATED,
 * never "failure prevented": nothing here has been applied to a grid.
 */

export interface HuntFindingView {
  code: string
  assetCode: string
  regionCode: string
  narrative: string
  narrativeAr: string
  riskBefore: number
  riskAfter: number
  probability: number
  confidence: number
  noveltyScore: number
  severity: number
  reproducibility: number
  cascadeProbability: number
  cascadeDepth: number
  assetsAffected: number
  conditions: Array<{
    leverKey: string
    label: string
    labelAr: string
    magnitude: number
    unit: string
    plausibility: number
  }>
  failurePath?: string[]
  prevention: PreventionViewModel | null
}

export interface PreventionViewModel {
  achieved: boolean
  riskBefore: number
  riskAfter: number
  targetRisk: number
  totalMw: number
  totalCostSar: number
  evidenceKind: string
  summary: string
  summaryAr: string
  doses: Array<{ key: string; label: string; labelAr: string; amount: number; unit: string; utilisation: number }>
}

export interface WeakestLinkViewModel {
  assetCode: string
  assetName: string
  assetNameAr: string
  criticality: number
  currentPct: number
  safeCeilingPct: number
  breakingPointPct: number | null
  dependants: number
  cascadeExposure: number
  recoveryDifficulty: number
}

export interface HuntRunView {
  code: string
  mode: string
  objective: string
  simulationsRun: number
  maxSimulations: number
  durationMs: number
  discovered: number
  summary: string
  summaryAr: string
  createdAt: number
  findings: HuntFindingView[]
}

interface HuntResultView {
  runCode: string | null
  kind: string
  mode: string
  findings: HuntFindingView[]
  weakestLink: WeakestLinkViewModel | null
  breakpoints: Array<{
    assetCode: string
    riskReduction: number
    action: string
    actionAr: string
  }>
  simulationsRun: number
  budgetSimulations: number
  budgetExhausted: boolean
  skippedImplausible: number
  durationMs: number
  summary: string
  summaryAr: string
  evidenceKind: string
}

const KINDS = [
  'hidden_risk',
  'weakest_link',
  'cascade_trigger',
  'breaking_point',
  'minimum_failure',
] as const

const MODES = ['quick', 'balanced', 'deep'] as const

function scoreTone(value: number): string {
  if (value >= 75) return 'text-critical'
  if (value >= 55) return 'text-warning'
  if (value >= 35) return 'text-watch'
  return 'text-text-muted'
}

export function RiskHunter({
  initialRuns,
  regions,
  canRun,
}: {
  initialRuns: HuntRunView[]
  regions: Array<{ code: string; name: string; nameAr: string }>
  canRun: boolean
}) {
  const { t, locale } = useI18n()
  const [runs, setRuns] = useState(initialRuns)
  const [result, setResult] = useState<HuntResultView | null>(null)
  const [mode, setMode] = useState<(typeof MODES)[number]>('balanced')
  const [scope, setScope] = useState('')
  const [busy, setBusy] = useState<string | null>(null)
  const [preventions, setPreventions] = useState<Record<string, PreventionViewModel>>({})
  const [error, setError] = useState<string | null>(null)

  const num = (value: number, digits = 0) =>
    formatNumber(locale, value, { maximumFractionDigits: digits })

  const findings = result ? result.findings : runs[0]?.findings ?? []

  const hunt = async (kind: string) => {
    setBusy(kind)
    setError(null)
    try {
      const next = await api.post<HuntResultView>('/api/risk-hunter/run', {
        kind,
        mode,
        regionCode: scope || null,
        persist: true,
      })
      setResult(next)
      const refreshed = await api.get<{ hunts: HuntRunView[] }>('/api/risk-hunter/discoveries?limit=8')
      setRuns(refreshed.hunts)
    } catch (caught) {
      setError(caught instanceof Error ? caught.message : t('common.error'))
    } finally {
      setBusy(null)
    }
  }

  const prevent = async (code: string) => {
    setBusy(`prevent:${code}`)
    setError(null)
    try {
      const prevention = await api.post<PreventionViewModel>(
        `/api/risk-hunter/discoveries/${code}/prevent`,
        {},
      )
      setPreventions((current) => ({ ...current, [code]: prevention }))
    } catch (caught) {
      setError(caught instanceof Error ? caught.message : t('common.error'))
    } finally {
      setBusy(null)
    }
  }

  return (
    <div className="space-y-4" data-testid="risk-hunter">
      <Notice tone="info">{t('riskHunter.sandbox')}</Notice>

      {canRun ? (
        <Panel>
          <PanelHeader title={t('riskHunter.kind')} subtitle={t('riskHunter.subtitle')} />
          <PanelBody className="space-y-3">
            <div className="flex flex-wrap items-end gap-3">
              <label className="block">
                <span className="mb-1 block text-[11px] text-text-muted">{t('riskHunter.mode')}</span>
                <Segmented
                  value={mode}
                  onChange={setMode}
                  ariaLabel={t('riskHunter.mode')}
                  options={MODES.map((key) => ({
                    value: key,
                    label: t(`riskHunter.mode${key[0].toUpperCase()}${key.slice(1)}`),
                    title: t(`riskHunter.mode${key[0].toUpperCase()}${key.slice(1)}Note`),
                  }))}
                />
              </label>

              <label className="block max-w-xs grow">
                <span className="mb-1 block text-[11px] text-text-muted">{t('riskHunter.scope')}</span>
                <Select value={scope} onChange={(event) => setScope(event.target.value)}>
                  <option value="">{t('riskHunter.national')}</option>
                  {regions.map((region) => (
                    <option key={region.code} value={region.code}>
                      {locale === 'ar' ? region.nameAr : region.name}
                    </option>
                  ))}
                </Select>
              </label>
            </div>

            <div className="flex flex-wrap gap-2">
              {KINDS.map((kind) => (
                <Button
                  key={kind}
                  variant={kind === 'hidden_risk' ? 'primary' : 'secondary'}
                  onClick={() => hunt(kind)}
                  disabled={busy !== null}
                  data-hunt={kind}
                >
                  {busy === kind ? t('riskHunter.hunting') : t(`riskHunter.${kind}`)}
                </Button>
              ))}
            </div>

            {result ? (
              <p className="text-[11px] leading-relaxed text-text-muted" data-testid="hunt-budget">
                {t('riskHunter.budget')
                  .replace('{run}', num(result.simulationsRun))
                  .replace('{budget}', num(result.budgetSimulations))
                  .replace('{ms}', num(result.durationMs))}
                {' · '}
                {num(result.skippedImplausible)} {t('riskHunter.skipped')}.{' '}
                <span className={result.budgetExhausted ? 'text-warning' : 'text-normal'}>
                  {result.budgetExhausted ? t('riskHunter.exhausted') : t('riskHunter.complete')}
                </span>
              </p>
            ) : null}

            {error ? <p className="text-[11px] text-critical">{error}</p> : null}
          </PanelBody>
        </Panel>
      ) : null}

      {/* ── The weakest link, when the search looked for one ─────────────────── */}
      {result?.weakestLink ? (
        <Panel>
          <PanelHeader
            title={t('riskHunter.weakestLink')}
            action={<Badge tone="accent">{t('riskHunter.simulatedBadge')}</Badge>}
          />
          <PanelBody className="space-y-3">
            <p className="text-sm font-medium">
              {locale === 'ar' ? result.weakestLink.assetNameAr : result.weakestLink.assetName}{' '}
              <span className="font-mono text-[11px] text-text-faint">{result.weakestLink.assetCode}</span>
            </p>
            <div className="grid gap-2 sm:grid-cols-2">
              <Meter label={t('riskHunter.criticality')} value={result.weakestLink.criticality} max={100} />
              <Meter label={t('riskHunter.recovery')} value={result.weakestLink.recoveryDifficulty} max={100} />
            </div>
            <dl className="grid grid-cols-2 gap-2 text-[11px] sm:grid-cols-4">
              <Figure label={t('riskHunter.headroom')} value={`${num(result.weakestLink.safeCeilingPct - result.weakestLink.currentPct, 1)} pp`} />
              <Figure
                label={t('riskHunter.breakingPoint')}
                value={
                  result.weakestLink.breakingPointPct === null
                    ? t('riskHunter.breakingPointNone')
                    : `+${num(result.weakestLink.breakingPointPct, 1)}%`
                }
              />
              <Figure label={t('riskHunter.dependants')} value={num(result.weakestLink.dependants)} />
              <Figure label={t('riskHunter.cascadeRisk')} value={`${num(result.weakestLink.cascadeExposure, 1)}%`} />
            </dl>
          </PanelBody>
        </Panel>
      ) : null}

      {/* ── Break points ─────────────────────────────────────────────────────── */}
      {result && result.breakpoints.length > 0 ? (
        <Panel>
          <PanelHeader title={t('riskHunter.breakpoints')} subtitle={t('riskHunter.breakpointNote')} />
          <PanelBody>
            <ul className="space-y-1.5">
              {result.breakpoints.map((breakpoint) => (
                <li
                  key={breakpoint.assetCode}
                  className="flex flex-wrap items-baseline justify-between gap-2 rounded-lg border border-border bg-surface-2/40 px-3 py-2 text-[12px]"
                >
                  <span>
                    <span className="font-mono text-[11px] text-text-faint">{breakpoint.assetCode}</span>{' '}
                    {locale === 'ar' ? breakpoint.actionAr : breakpoint.action}
                  </span>
                  <span className="font-mono tabular-nums text-normal">
                    −{num(breakpoint.riskReduction, 1)}
                  </span>
                </li>
              ))}
            </ul>
          </PanelBody>
        </Panel>
      ) : null}

      {/* ── Findings ─────────────────────────────────────────────────────────── */}
      {findings.length === 0 ? (
        <EmptyState
          title={t('uiState.empty')}
          body={result ? t('riskHunter.noFindings') : t('riskHunter.empty')}
        />
      ) : (
        <div className="grid gap-3 xl:grid-cols-2">
          {findings.map((finding) => {
            const prevention = preventions[finding.code] ?? finding.prevention
            return (
              <Panel key={finding.code}>
                <PanelHeader
                  title={
                    <span className="font-mono text-[12px]">
                      {finding.assetCode} · {finding.regionCode}
                    </span>
                  }
                  action={<Badge tone="accent">{t('riskHunter.simulatedBadge')}</Badge>}
                />
                <PanelBody className="space-y-3">
                  <p className="text-[12px] leading-relaxed" data-finding={finding.code}>
                    {locale === 'ar' ? finding.narrativeAr : finding.narrative}
                  </p>

                  <ul className="flex flex-wrap gap-1.5">
                    {finding.conditions.map((condition) => (
                      <li key={condition.leverKey}>
                        <Badge tone="neutral">
                          {locale === 'ar' ? condition.labelAr : condition.label}{' '}
                          <span className="tabular-nums">
                            {condition.magnitude > 0 ? '+' : ''}
                            {num(condition.magnitude, 1)}
                            {condition.unit}
                          </span>
                          <span className="text-text-faint">
                            · {t('riskHunter.plausibility')} {num(condition.plausibility, 0)}%
                          </span>
                        </Badge>
                      </li>
                    ))}
                  </ul>

                  <dl className="grid grid-cols-3 gap-2 text-[11px]">
                    <Figure label={t('riskHunter.novelty')} value={num(finding.noveltyScore)} tone={scoreTone(finding.noveltyScore)} />
                    <Figure label={t('riskHunter.severity')} value={num(finding.severity)} tone={scoreTone(finding.severity)} />
                    <Figure label={t('riskHunter.confidence')} value={`${num(finding.confidence)}%`} />
                    <Figure label={t('riskHunter.cascadeRisk')} value={`${num(finding.cascadeProbability, 1)}%`} />
                    <Figure label={t('riskHunter.assetsAffected')} value={num(finding.assetsAffected)} />
                    <Figure label={t('riskHunter.reproducibility')} value={`${num(finding.reproducibility)}%`} />
                  </dl>

                  {finding.failurePath && finding.failurePath.length > 0 ? (
                    <p className="font-mono text-[11px] text-text-muted">
                      {t('riskHunter.failurePath')}: {finding.failurePath.join(' → ')}
                    </p>
                  ) : null}

                  {prevention ? (
                    <Prevention prevention={prevention} />
                  ) : canRun ? (
                    <Button
                      size="sm"
                      variant="secondary"
                      onClick={() => prevent(finding.code)}
                      disabled={busy !== null}
                      data-prevent={finding.code}
                    >
                      {busy === `prevent:${finding.code}` ? t('riskHunter.preventing') : t('riskHunter.prevent')}
                    </Button>
                  ) : null}
                </PanelBody>
              </Panel>
            )
          })}
        </div>
      )}

      {/* ── Previous hunts ───────────────────────────────────────────────────── */}
      {runs.length > 0 ? (
        <Panel>
          <PanelHeader title={t('riskHunter.history')} />
          <PanelBody>
            <ul className="space-y-1.5">
              {runs.map((run) => (
                <li
                  key={run.code}
                  className="flex flex-wrap items-baseline justify-between gap-2 rounded-lg border border-border bg-surface-2/40 px-3 py-2 text-[11px]"
                >
                  <span className="text-text-muted">{locale === 'ar' ? run.summaryAr : run.summary}</span>
                  <span className="font-mono tabular-nums text-text-faint">
                    {run.mode} · {num(run.simulationsRun)}/{num(run.maxSimulations)} ·{' '}
                    {formatDateTime(locale, run.createdAt)}
                  </span>
                </li>
              ))}
            </ul>
          </PanelBody>
        </Panel>
      ) : null}
    </div>
  )

  function Prevention({ prevention }: { prevention: PreventionViewModel }) {
    return (
      <div
        className={cn(
          'rounded-lg border p-3',
          prevention.achieved ? 'border-normal/30 bg-normal/8' : 'border-watch/30 bg-watch/8',
        )}
        data-prevention={prevention.achieved ? 'achieved' : 'partial'}
      >
        <p className={cn('text-[11px] font-medium', prevention.achieved ? 'text-normal' : 'text-watch')}>
          {prevention.achieved ? t('riskHunter.preventionAchieved') : t('riskHunter.preventionPartial')}
        </p>
        <p className="mt-1.5 text-[12px] leading-relaxed">
          {locale === 'ar' ? prevention.summaryAr : prevention.summary}
        </p>

        <dl className="mt-2 grid grid-cols-3 gap-2 text-[11px]">
          <Figure label={t('riskHunter.riskBefore')} value={num(prevention.riskBefore, 1)} />
          <Figure label={t('riskHunter.riskAfter')} value={num(prevention.riskAfter, 1)} tone="text-normal" />
          <Figure label={t('riskHunter.cost')} value={num(prevention.totalCostSar)} />
        </dl>

        {prevention.doses.length > 0 ? (
          <ul className="mt-2 space-y-1">
            {prevention.doses.map((dose) => (
              <li key={dose.key} className="flex items-baseline justify-between gap-2 text-[11px]">
                <span className="text-text-muted">{locale === 'ar' ? dose.labelAr : dose.label}</span>
                <span className="font-mono tabular-nums">
                  {num(dose.amount, 1)} {dose.unit}
                  <span className="ms-1.5 text-text-faint">
                    ({num(dose.utilisation, 0)}% {t('riskHunter.utilisation')})
                  </span>
                </span>
              </li>
            ))}
          </ul>
        ) : null}

        <p className="mt-2 text-[10px] leading-relaxed text-text-faint">{t('riskHunter.preventionNote')}</p>
      </div>
    )
  }

  function Figure({ label, value, tone }: { label: string; value: string; tone?: string }) {
    return (
      <div>
        <dt className="text-text-faint">{label}</dt>
        <dd className={cn('font-mono tabular-nums', tone ?? 'text-text')}>{value}</dd>
      </div>
    )
  }
}
