'use client'

import { useState } from 'react'

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

/**
 * Two questions a person can ask the twin directly (§106, §107).
 *
 * They are grouped because they are the same gesture pointed in opposite directions:
 * "what will happen" walks the twin forward under current conditions, and "what breaks
 * this" searches backwards for the conditions that would break it. Both run in the
 * sandbox and both report their own uncertainty rather than an answer alone.
 */

interface UncertaintyPayload {
  probability: number
  expectedMinutes: number | null
  windowLowMinutes: number | null
  windowHighMinutes: number | null
  predictionConfidence: number
}

interface EnvelopePayload {
  currentPct: number
  adjustedMaxPct: number
  headroomPct: number
  band: string
}

interface AdversarialPayload {
  found: boolean
  metric: number
  target: number
  riskBefore: number
  plausibilityCost: number
  evaluations: number
  summary: string
  summaryAr: string
  doses: Array<{ key: string; label: string; labelAr: string; amount: number; unit: string }>
}

export function AskTheFuture({ assetCode }: { assetCode: string }) {
  const { t, locale } = useI18n()
  const [result, setResult] = useState<{
    uncertainty: UncertaintyPayload
    envelope: EnvelopePayload
    physics: { verdict: string; summary: string; summaryAr: string }
  } | null>(null)
  const [busy, setBusy] = useState(false)
  const [error, setError] = useState<string | null>(null)

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

  const ask = async () => {
    setBusy(true)
    setError(null)
    try {
      setResult(
        await api.get(`/api/uncertainty?asset=${encodeURIComponent(assetCode)}`),
      )
    } catch (caught) {
      setError(caught instanceof Error ? caught.message : t('common.error'))
    } finally {
      setBusy(false)
    }
  }

  return (
    <Panel>
      <PanelHeader title={t('askFuture.title')} subtitle={t('askFuture.subtitle')} />
      <PanelBody className="space-y-3">
        <Button onClick={ask} disabled={busy}>
          {busy ? t('askFuture.asking') : t('askFuture.ask')}
        </Button>

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

        {result ? (
          <div className="space-y-2">
            <div className="rounded-lg border border-border bg-surface-2/50 px-3 py-2">
              <p className="text-[11px] text-text-muted">{t('askFuture.expected')}</p>
              <p className="mt-0.5 text-[12px] leading-relaxed">
                {result.uncertainty.expectedMinutes === null ? (
                  t('uncertainty.noCrossing')
                ) : (
                  <>
                    <span className="font-mono font-semibold tabular-nums">
                      ~{num(result.uncertainty.expectedMinutes)} {t('common.minShort')}
                    </span>{' '}
                    <span className="text-text-muted">
                      ({num(result.uncertainty.windowLowMinutes ?? 0)}–
                      {num(result.uncertainty.windowHighMinutes ?? 0)})
                    </span>
                    {' · '}
                    {t('uncertainty.probability')}{' '}
                    <span className="font-mono tabular-nums">
                      {num(result.uncertainty.probability)}%
                    </span>
                  </>
                )}
              </p>
              <p className="mt-1 text-[10px] text-text-faint">
                {t('uncertainty.predictionConfidence')}:{' '}
                {num(result.uncertainty.predictionConfidence)}%
              </p>
            </div>

            <div className="rounded-lg border border-border bg-surface-2/50 px-3 py-2">
              <p className="text-[11px] text-text-muted">{t('physics.envelopeTitle')}</p>
              <p className="mt-0.5 text-[12px]">
                <span className="font-mono font-semibold tabular-nums">
                  {num(result.envelope.currentPct, 1)}%
                </span>{' '}
                <span className="text-text-muted">
                  / {num(result.envelope.adjustedMaxPct, 1)}% ·{' '}
                  {t(`physics.band.${result.envelope.band}`)}
                </span>
              </p>
            </div>

            <p className="text-[10px] leading-relaxed text-text-faint">
              {locale === 'ar' ? result.physics.summaryAr : result.physics.summary}
            </p>
          </div>
        ) : null}
      </PanelBody>
    </Panel>
  )
}

export function WhatBreaksFirst({ assetCode }: { assetCode: string }) {
  const { t, locale } = useI18n()
  const [result, setResult] = useState<AdversarialPayload | null>(null)
  const [busy, setBusy] = useState(false)
  const [error, setError] = useState<string | null>(null)

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

  const run = async () => {
    setBusy(true)
    setError(null)
    try {
      setResult(
        await api.post<AdversarialPayload>('/api/adversarial-twin', {
          assetCode,
          targetRisk: 90,
        }),
      )
    } catch (caught) {
      setError(caught instanceof Error ? caught.message : t('common.error'))
    } finally {
      setBusy(false)
    }
  }

  // Reported as ordinariness rather than raw cost, so a higher number always means "more
  // likely to actually happen" the way it does everywhere else in the product.
  const ordinariness = result ? Math.max(0, 100 - result.plausibilityCost) : 0

  return (
    <Panel>
      <PanelHeader
        title={t('adversarial.title')}
        subtitle={t('adversarial.subtitle')}
        action={<Badge tone="muted">{t('common.simulated')}</Badge>}
      />
      <PanelBody className="space-y-3">
        <Button onClick={run} disabled={busy}>
          {busy ? t('common.running') : t('adversarial.whatBreaksFirst')}
        </Button>

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

        {result ? (
          <div className="space-y-2">
            <p
              className={cn(
                'rounded-lg border px-3 py-2 text-[12px] leading-relaxed',
                result.found
                  ? 'border-warning/30 bg-warning/8'
                  : 'border-border bg-surface-2/50 text-text-muted',
              )}
            >
              {locale === 'ar' ? result.summaryAr : result.summary}
            </p>

            {result.doses.length ? (
              <ul className="flex flex-wrap gap-1.5">
                {result.doses.map((dose) => (
                  <li
                    key={dose.key}
                    className="rounded-full border border-border bg-surface-2 px-2 py-0.5 text-[10px]"
                  >
                    {locale === 'ar' ? dose.labelAr : dose.label}{' '}
                    <span className="font-mono tabular-nums">
                      +{num(dose.amount, 1)} {dose.unit}
                    </span>
                  </li>
                ))}
              </ul>
            ) : null}

            <div className="flex flex-wrap gap-x-4 gap-y-1 text-[10px] text-text-faint">
              <span title={t('adversarial.ordinarinessHint')}>
                {t('adversarial.ordinariness')}:{' '}
                <span className="font-mono tabular-nums text-text-muted">{num(ordinariness)}</span>
              </span>
              <span>
                {t('adversarial.evaluations')}:{' '}
                <span className="font-mono tabular-nums text-text-muted">{result.evaluations}</span>
              </span>
              <span>
                {t('common.before')} → {t('common.after')}:{' '}
                <span className="font-mono tabular-nums text-text-muted">
                  {num(result.riskBefore)}% → {num(result.metric)}%
                </span>
              </span>
            </div>
          </div>
        ) : null}
      </PanelBody>
    </Panel>
  )
}
