'use client'

import { useState } from 'react'

import { Button, Notice } from '@/components/ui/controls'
import { Badge, EmptyState, 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'

/**
 * The Pareto explorer (§35, §36, §37, §38).
 *
 * The 3.0 optimiser names a winner. This shows the options *around* that winner — the
 * ones where you cannot do better on one objective without doing worse on another — and,
 * for every option that is not the recommendation, why not.
 *
 * That last part is the point. A system that can only say why it picked A is
 * indistinguishable from one that picked A at random and rationalised afterwards.
 */

export interface ParetoEntryView {
  candidate: {
    id: string
    key: string
    label: string
    labelAr: string
    metrics: Record<string, number>
    physicsRejection?: { reason: string; reasonAr: string } | null
  }
  isOnFrontier: boolean
  dominatedBy: number
  corner: string
  crowdingDistance: number
  rank: number
  rejectionReason: string
  rejectionReasonAr: string
}

export interface ParetoViewData {
  assetCode: string
  result: {
    entries: ParetoEntryView[]
    frontier: ParetoEntryView[]
    recommended: ParetoEntryView | null
    matrix: Array<{ id: string; label: string; labelAr: string; values: Record<string, number> }>
  }
  metrics: Array<{ key: string; label: string; labelAr: string; unit: string; direction: string }>
  raw: Array<{ id: string; label: string; labelAr: string; values: Record<string, number> }>
  rejectedByPhysics: number
}

export function ParetoExplorer({
  assetCode,
  initial,
  canRun,
}: {
  assetCode: string
  initial: ParetoViewData | null
  canRun: boolean
}) {
  const { t, locale } = useI18n()
  const [view, setView] = useState(initial)
  const [busy, setBusy] = useState(false)
  const [error, setError] = useState<string | null>(null)

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

  const run = async () => {
    setBusy(true)
    setError(null)
    try {
      setView(await api.post<ParetoViewData>('/api/strategies/pareto', { assetCode }))
    } catch (caught) {
      setError(caught instanceof Error ? caught.message : t('common.error'))
    } finally {
      setBusy(false)
    }
  }

  if (!view) {
    return (
      <Panel>
        <PanelHeader title={t('pareto.title')} subtitle={t('pareto.subtitle')} />
        <PanelBody>
          {canRun ? (
            <Button onClick={run} disabled={busy}>
              {busy ? t('common.running') : t('common.run')}
            </Button>
          ) : (
            <EmptyState title={t('uiState.empty')} body={t('pareto.empty')} />
          )}
          {error ? <p className="mt-2 text-[11px] text-critical">{error}</p> : null}
        </PanelBody>
      </Panel>
    )
  }

  const recommendedId = view.result.recommended?.candidate.id
  const rawById = new Map(view.raw.map((row) => [row.id, row.values]))
  const normalisedById = new Map(view.result.matrix.map((row) => [row.id, row.values]))

  return (
    <div className="space-y-4">
      <Panel>
        <PanelHeader
          title={t('pareto.title')}
          subtitle={t('pareto.subtitle')}
          action={
            <div className="flex flex-wrap items-center gap-1.5">
              <Badge tone="brand">
                {view.result.frontier.length} {t('pareto.frontier').toLowerCase()}
              </Badge>
              {view.rejectedByPhysics > 0 ? (
                <Badge tone="accent">
                  {view.rejectedByPhysics} {t('pareto.rejected').toLowerCase()}
                </Badge>
              ) : null}
            </div>
          }
        />
        <PanelBody className="space-y-2">
          {view.result.entries.map((entry) => {
            const isRecommended = entry.candidate.id === recommendedId
            const rejected = Boolean(entry.candidate.physicsRejection)
            return (
              <div
                key={entry.candidate.id}
                className={cn(
                  'min-w-0 rounded-lg border px-3 py-2.5',
                  isRecommended
                    ? 'border-brand/45 bg-brand/8'
                    : rejected
                      ? 'border-critical/30 bg-critical/6'
                      : entry.isOnFrontier
                        ? 'border-border-strong bg-surface-2/50'
                        : 'border-border bg-surface-2/25',
                )}
              >
                <div className="flex flex-wrap items-baseline gap-2">
                  <span className="min-w-0 text-[12px] font-medium">
                    {locale === 'ar' ? entry.candidate.labelAr : entry.candidate.label}
                  </span>
                  {isRecommended ? (
                    <Badge tone="brand" dot>
                      {t('redBlue.recommended')}
                    </Badge>
                  ) : null}
                  {entry.corner && !isRecommended ? (
                    <Badge tone="info">{t(`pareto.corner.${entry.corner}`)}</Badge>
                  ) : null}
                  {rejected ? <Badge tone="accent">{t('pareto.rejected')}</Badge> : null}
                  {!entry.isOnFrontier && !rejected ? (
                    <Badge tone="muted">{t('pareto.dominated')}</Badge>
                  ) : null}
                </div>

                {/* The four figures an operator weighs first. */}
                <div className="mt-1.5 grid grid-cols-2 gap-2 sm:grid-cols-4">
                  {['risk_reduction', 'cost', 'execution_time', 'customer_impact'].map((key) => {
                    const metric = view.metrics.find((m) => m.key === key)
                    const value = rawById.get(entry.candidate.id)?.[key] ?? 0
                    return (
                      <div key={key} className="min-w-0">
                        <p className="truncate text-[10px] text-text-faint">
                          {metric ? (locale === 'ar' ? metric.labelAr : metric.label) : key}
                        </p>
                        <p className="font-mono text-[12px] font-semibold tabular-nums">
                          {num(value)}
                          <span className="ms-0.5 text-[9px] font-normal text-text-faint">
                            {metric?.unit}
                          </span>
                        </p>
                      </div>
                    )
                  })}
                </div>

                {/* Why not this one (§35). */}
                {!isRecommended && entry.rejectionReason ? (
                  <p className="mt-1.5 border-t border-border/60 pt-1.5 text-[10px] leading-relaxed text-text-muted">
                    <span className="font-medium text-text-faint">{t('pareto.whyNot')} </span>
                    {locale === 'ar' ? entry.rejectionReasonAr : entry.rejectionReason}
                  </p>
                ) : null}
              </div>
            )
          })}

          {canRun ? (
            <Button variant="secondary" onClick={run} disabled={busy}>
              {busy ? t('common.running') : t('common.run')}
            </Button>
          ) : null}
          {error ? <Notice tone="danger">{error}</Notice> : null}
        </PanelBody>
      </Panel>

      {/* ── The trade-off matrix (§36) ────────────────────────────────────────── */}
      <Panel>
        <PanelHeader title={t('pareto.tradeoffs')} subtitle={t('pareto.tradeoffHint')} />
        <PanelBody>
          <div className="overflow-x-auto">
            <table className="w-full min-w-[44rem] text-[11px]">
              <thead>
                <tr className="text-text-faint">
                  <th className="py-1.5 text-start font-medium">{t('common.aiStrategy')}</th>
                  {view.metrics.map((metric) => (
                    <th key={metric.key} className="py-1.5 text-center font-medium">
                      {locale === 'ar' ? metric.labelAr : metric.label}
                    </th>
                  ))}
                </tr>
              </thead>
              <tbody>
                {view.result.matrix.map((row) => (
                  <tr key={row.id} className="border-t border-border/60">
                    <td className="max-w-[10rem] truncate py-1.5">
                      {locale === 'ar' ? row.labelAr : row.label}
                    </td>
                    {view.metrics.map((metric) => {
                      const value = normalisedById.get(row.id)?.[metric.key] ?? 0
                      return (
                        <td key={metric.key} className="px-1 py-1.5">
                          <div
                            className="h-2 overflow-hidden rounded-full bg-surface-3"
                            title={`${num((rawById.get(row.id)?.[metric.key] ?? 0), 2)} ${metric.unit}`}
                          >
                            <div
                              className={cn(
                                'h-full rounded-full',
                                row.id === recommendedId ? 'bg-brand' : 'bg-info/60',
                              )}
                              style={{ width: `${Math.max(2, value * 100)}%` }}
                            />
                          </div>
                        </td>
                      )
                    })}
                  </tr>
                ))}
              </tbody>
            </table>
          </div>
        </PanelBody>
      </Panel>
    </div>
  )
}
