'use client'

import { useState } from 'react'

import { useI18n } from '@/components/providers/i18n-provider'
import { Button, Field, Input, Notice, Segmented } from '@/components/ui/controls'
import { Badge, Panel, PanelBody, PanelHeader, Meter } from '@/components/ui/display'
import { api, ApiClientError } from '@/lib/api/client'
import { cn } from '@/lib/cn'

type Objective = 'risk_below' | 'prevent_breach' | 'stability_above'

interface Dose {
  key: string
  actionType: string
  unit: string
  dose: number
  costSar: number
  durationMin: number
  label: string
  labelAr: string
  contribution: number
}

interface Outcome {
  assetCode: string
  objective: Objective
  targetValue: number
  riskBefore: number
  riskAfter: number
  confidence: number
  summary: string
  summaryAr: string
  levers: Array<{ key: string; maxDose: number; unit: string }>
  result: {
    achieved: boolean
    metricBefore: number
    metricAfter: number
    iterations: number
    totalMw: number
    totalCostSar: number
    doses: Dose[]
  }
}

/**
 * Counterfactual Explorer (§10).
 *
 * The operator states a target and the server searches for the smallest set of doses
 * that reaches it. The result deliberately shows how much of the available headroom each
 * dose spends: a solution that uses 95 % of the transfer capacity is technically a
 * solution and practically a warning.
 */
export function CounterfactualRunner({
  assetCode,
  initial,
}: {
  assetCode: string
  initial?: Outcome | null
}) {
  const { t, locale, n } = useI18n()
  const ar = locale === 'ar'

  const [objective, setObjective] = useState<Objective>('risk_below')
  const [target, setTarget] = useState('12')
  const [outcome, setOutcome] = useState<Outcome | null>(initial ?? null)
  const [error, setError] = useState<string | null>(null)
  const [busy, setBusy] = useState(false)

  const defaults: Record<Objective, string> = {
    risk_below: '12',
    prevent_breach: '0',
    stability_above: '90',
  }

  const run = async () => {
    setBusy(true)
    setError(null)
    try {
      const value = Number.parseFloat(target)
      const result = await api.post<Outcome>('/api/counterfactual', {
        assetCode,
        objective,
        targetValue: Number.isFinite(value) ? value : 0,
        persist: true,
      })
      setOutcome(result)
    } 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('counterfactual.question')} subtitle={t('counterfactual.pruningHint')} />
        <PanelBody className="space-y-4 pt-0">
          <Field label={t('counterfactual.objective')}>
            <Segmented
              ariaLabel={t('counterfactual.objective')}
              value={objective}
              onChange={(next) => {
                setObjective(next)
                setTarget(defaults[next])
              }}
              options={[
                { value: 'risk_below' as Objective, label: t('counterfactual.objectiveKey.risk_below') },
                { value: 'prevent_breach' as Objective, label: t('counterfactual.objectiveKey.prevent_breach') },
                { value: 'stability_above' as Objective, label: t('counterfactual.objectiveKey.stability_above') },
              ]}
            />
          </Field>

          <div className="flex flex-wrap items-end gap-3">
            {objective !== 'prevent_breach' ? (
              <Field label={t('counterfactual.targetValue')} htmlFor="cf-target" className="w-32">
                <Input
                  id="cf-target"
                  type="number"
                  min={0}
                  max={100}
                  value={target}
                  onChange={(event) => setTarget(event.target.value)}
                />
              </Field>
            ) : null}
            <Button onClick={run} loading={busy}>
              {busy ? t('counterfactual.searching') : t('counterfactual.search')}
            </Button>
          </div>

          {error ? <Notice tone="danger">{error}</Notice> : null}
        </PanelBody>
      </Panel>

      {outcome ? (
        <Panel>
          <PanelHeader
            title={t('counterfactual.minimum')}
            subtitle={ar ? outcome.summaryAr : outcome.summary}
            action={
              <Badge tone={outcome.result.achieved ? 'brand' : 'accent'}>
                {outcome.result.achieved ? t('counterfactual.achieved') : t('counterfactual.notAchieved')}
              </Badge>
            }
          />
          <PanelBody className="pt-0">
            <div className="flex flex-wrap items-baseline gap-x-6 gap-y-2 border-b border-border/70 pb-3">
              <div>
                <p className="text-[10px] uppercase tracking-wide text-text-faint">
                  {t('counterfactual.before')}
                </p>
                <p className="tnum text-2xl font-semibold text-critical">
                  {n(outcome.riskBefore, { maximumFractionDigits: 1 })}%
                </p>
              </div>
              <span aria-hidden className="text-text-faint">
                →
              </span>
              <div>
                <p className="text-[10px] uppercase tracking-wide text-text-faint">
                  {t('counterfactual.after')}
                </p>
                <p className="tnum text-2xl font-semibold text-normal">
                  {n(outcome.riskAfter, { maximumFractionDigits: 1 })}%
                </p>
              </div>
              <div className="ms-auto text-end">
                <p className="text-[10px] uppercase tracking-wide text-text-faint">
                  {t('counterfactual.evaluations')}
                </p>
                <p className="tnum text-sm font-medium text-text">{n(outcome.result.iterations)}</p>
              </div>
            </div>

            {outcome.result.doses.length === 0 ? (
              <p className="py-4 text-xs text-text-muted">{t('counterfactual.noLevers')}</p>
            ) : (
              <ul className="mt-3 space-y-3">
                {outcome.result.doses.map((dose) => {
                  const lever = outcome.levers.find((entry) => entry.key === dose.key)
                  const utilisation = lever && lever.maxDose > 0 ? (dose.dose / lever.maxDose) * 100 : 0
                  return (
                    <li key={dose.key} className="rounded-lg border border-border bg-surface-2/40 p-3">
                      <div className="flex flex-wrap items-baseline justify-between gap-x-4 gap-y-1">
                        <p className="text-xs font-medium text-text">{ar ? dose.labelAr : dose.label}</p>
                        <p className="tnum text-[11px] text-text-muted">
                          {t('counterfactual.contribution')}{' '}
                          <span className="font-medium text-normal">
                            {n(dose.contribution, { maximumFractionDigits: 1 })}
                          </span>
                        </p>
                      </div>
                      <Meter
                        className="mt-2"
                        value={utilisation}
                        state={utilisation > 85 ? 'critical' : utilisation > 60 ? 'warning' : 'normal'}
                        label={t('counterfactual.utilisation')}
                        showValue
                      />
                    </li>
                  )
                })}
              </ul>
            )}

            <div className="mt-3 flex flex-wrap gap-x-6 gap-y-1 border-t border-border/70 pt-3 text-[11px] text-text-muted">
              <span className="tnum">
                {t('counterfactual.totalCost')} {n(outcome.result.totalCostSar)} {t('common.sar')}
              </span>
              <span className="tnum">
                {t('confidence.title')} {n(outcome.confidence, { maximumFractionDigits: 0 })}%
              </span>
              <span className={cn('tnum', outcome.result.achieved ? 'text-normal' : 'text-watch')}>
                {t('counterfactual.dose')} {n(outcome.result.totalMw, { maximumFractionDigits: 2 })} MW
              </span>
            </div>
          </PanelBody>
        </Panel>
      ) : null}
    </div>
  )
}
