'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 { formatDateTime, formatNumber } from '@/lib/i18n/translate'
import { cn } from '@/lib/cn'

/**
 * The governed learning queue (§32, §33).
 *
 * Approving a candidate records a human decision and does nothing else. That is the whole
 * content of §32 — there is no path from this queue to a deployed model — and the notice
 * at the top says so rather than leaving a reader to assume approval means deployment.
 *
 * The confidence ceiling on simulated-only evidence is shown on the card, because a
 * pattern seen twenty times in simulation has been seen zero times in the world.
 */

export interface LearningCandidateView {
  code: string
  kind: string
  title: string
  titleAr: string
  reason: string
  reasonAr: string
  evidence: string
  evidenceAr: string
  eventCount: number
  confidence: number
  supportPct: number
  proposedChange: string
  proposedChangeAr: string
  status: string
  reviewedAt: number | null
  reviewNote: string
  createdAt: number
}

const STATUS_TONE: Record<string, 'brand' | 'info' | 'accent' | 'muted'> = {
  new: 'info',
  under_review: 'info',
  approved: 'brand',
  rejected: 'muted',
  applied: 'brand',
}

export function LearningQueue({
  initial,
  canReview,
}: {
  initial: LearningCandidateView[]
  canReview: boolean
}) {
  const { t, locale } = useI18n()
  const [candidates, setCandidates] = useState(initial)
  const [busy, setBusy] = useState<string | null>(null)
  const [error, setError] = useState<string | null>(null)

  const review = async (code: string, decision: 'approve' | 'reject') => {
    setBusy(code)
    setError(null)
    try {
      await api.patch('/api/learning', { code, decision })
      const refreshed = await api.get<{ candidates: LearningCandidateView[] }>('/api/learning')
      setCandidates(refreshed.candidates)
    } catch (caught) {
      setError(caught instanceof Error ? caught.message : t('common.error'))
    } finally {
      setBusy(null)
    }
  }

  return (
    <div className="space-y-4">
      <Notice tone="info">{t('learning.governance')}</Notice>
      {error ? <Notice tone="danger">{error}</Notice> : null}

      {candidates.length === 0 ? (
        <EmptyState title={t('uiState.empty')} body={t('learning.empty')} />
      ) : (
        <div className="grid gap-3 xl:grid-cols-2">
          {candidates.map((candidate) => {
            const pending = candidate.status === 'new' || candidate.status === 'under_review'
            return (
              <div key={candidate.code} className="min-w-0">
                <Panel>
                  <PanelHeader
                    title={locale === 'ar' ? candidate.titleAr : candidate.title}
                    action={
                      <div className="flex flex-wrap items-center gap-1.5">
                        <Badge tone="muted">{t(`learning.kind.${candidate.kind}`)}</Badge>
                        <Badge tone={STATUS_TONE[candidate.status] ?? 'muted'} dot>
                          {t(`learning.status.${candidate.status}`)}
                        </Badge>
                      </div>
                    }
                  />
                  <PanelBody className="space-y-3">
                    <p className="text-[12px] leading-relaxed text-text-muted">
                      {locale === 'ar' ? candidate.reasonAr : candidate.reason}
                    </p>

                    <div className="grid grid-cols-3 gap-2">
                      <div className="min-w-0">
                        <p className="truncate text-[10px] text-text-faint">
                          {t('common.confidence')}
                        </p>
                        <p
                          className={cn(
                            'font-mono text-sm font-semibold tabular-nums',
                            candidate.confidence >= 70 ? 'text-normal' : 'text-watch',
                          )}
                        >
                          {formatNumber(locale, candidate.confidence, { maximumFractionDigits: 0 })}%
                        </p>
                      </div>
                      <div className="min-w-0">
                        <p className="truncate text-[10px] text-text-faint">{t('learning.support')}</p>
                        <p className="font-mono text-sm font-semibold tabular-nums">
                          {formatNumber(locale, candidate.supportPct, { maximumFractionDigits: 0 })}%
                        </p>
                      </div>
                      <div className="min-w-0">
                        <p className="truncate text-[10px] text-text-faint">{t('learning.events')}</p>
                        <p className="font-mono text-sm font-semibold tabular-nums">
                          {candidate.eventCount}
                        </p>
                      </div>
                    </div>

                    <div className="rounded-lg border border-border bg-surface-2/50 px-3 py-2">
                      <p className="text-[10px] font-medium text-text-faint">
                        {t('learning.evidence')}
                      </p>
                      <p className="text-[11px] text-text-muted">
                        {locale === 'ar' ? candidate.evidenceAr : candidate.evidence}
                      </p>
                      {candidate.confidence <= 62 ? (
                        <p className="mt-1 text-[10px] leading-relaxed text-warning">
                          {t('learning.simulatedCeiling')}
                        </p>
                      ) : null}
                    </div>

                    <div>
                      <p className="text-[10px] font-medium text-text-faint">
                        {t('learning.proposed')}
                      </p>
                      <p className="text-[11px] leading-relaxed">
                        {locale === 'ar' ? candidate.proposedChangeAr : candidate.proposedChange}
                      </p>
                    </div>

                    {canReview && pending ? (
                      <div className="flex flex-wrap gap-2">
                        <Button
                          onClick={() => review(candidate.code, 'approve')}
                          disabled={busy !== null}
                        >
                          {t('learning.approve')}
                        </Button>
                        <Button
                          variant="secondary"
                          onClick={() => review(candidate.code, 'reject')}
                          disabled={busy !== null}
                        >
                          {t('learning.reject')}
                        </Button>
                      </div>
                    ) : candidate.reviewedAt ? (
                      <p className="text-[10px] text-text-faint">
                        {t('learning.reviewed')} · {formatDateTime(locale, candidate.reviewedAt)}
                      </p>
                    ) : null}
                  </PanelBody>
                </Panel>
              </div>
            )
          })}
        </div>
      )}
    </div>
  )
}
