'use client'

import { useState } from 'react'

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

export interface DecisionView {
  code: string
  assetCode: string
  title: string
  titleAr: string
  rationale: string
  rationaleAr: string
  status: string
  riskBefore: number
  riskAfter: number
  createdAt: number
  outcome: string
  outcomeAr: string
  confidence: { overall: number; band: string; isLowData: boolean }
  approvals: Array<{
    step: string
    decision: string
    userName: string
    userNameAr: string
    comment: string
    commentAr: string
    decidedAt: number | null
  }>
}

const STATUS_TONE: Record<string, string> = {
  pending: 'border-watch/35 bg-watch/8 text-watch',
  operator_approved: 'border-info/35 bg-info/8 text-info',
  approved: 'border-normal/35 bg-normal/8 text-normal',
  rejected: 'border-critical/35 bg-critical/8 text-critical',
  simulated: 'border-brand/35 bg-brand/8 text-brand',
  withdrawn: 'border-border bg-surface-2 text-text-muted',
}

/**
 * Human-in-the-loop approvals (§13).
 *
 * Two signatures, in order, by named people — and an execute button that says, in the
 * label itself, that what it runs is a simulation. The permissions are checked again on
 * the server; hiding a button here is a courtesy, not the control (§34).
 */
export function DecisionBoard({
  decisions,
  canApprove,
  canSupervise,
}: {
  decisions: DecisionView[]
  canApprove: boolean
  canSupervise: boolean
}) {
  const { t, locale, n, dateTime } = useI18n()
  const ar = locale === 'ar'

  const [records, setRecords] = useState(decisions)
  const [comments, setComments] = useState<Record<string, string>>({})
  const [busy, setBusy] = useState<string | null>(null)
  const [error, setError] = useState<string | null>(null)
  const [notice, setNotice] = useState<string | null>(null)

  const refresh = async () => {
    const data = await api.get<{ decisions: DecisionView[] }>('/api/decisions?limit=25')
    setRecords(data.decisions)
  }

  const act = async (
    code: string,
    step: 'operator' | 'supervisor',
    decision: 'approved' | 'rejected' | 'modified',
  ) => {
    setBusy(`${code}-${step}`)
    setError(null)
    setNotice(null)
    try {
      await api.post('/api/approvals', {
        decisionCode: code,
        step,
        decision,
        comment: comments[code] ?? undefined,
      })
      await refresh()
    } catch (cause) {
      setError(cause instanceof ApiClientError ? (ar ? cause.failure.messageAr : cause.failure.message) : String(cause))
    } finally {
      setBusy(null)
    }
  }

  const execute = async (code: string) => {
    setBusy(`${code}-execute`)
    setError(null)
    try {
      const result = await api.put<{ outcome: string; outcomeAr: string }>('/api/approvals', {
        decisionCode: code,
      })
      setNotice(ar ? result.outcomeAr : result.outcome)
      await refresh()
    } catch (cause) {
      setError(cause instanceof ApiClientError ? (ar ? cause.failure.messageAr : cause.failure.message) : String(cause))
    } finally {
      setBusy(null)
    }
  }

  if (records.length === 0) {
    return (
      <Panel>
        <PanelHeader title={t('decisions.title')} subtitle={t('decisions.workflow')} />
        <EmptyState title={t('decisions.empty')} body={t('decisions.workflow')} />
      </Panel>
    )
  }

  return (
    <div className="space-y-3">
      {error ? <Notice tone="danger">{error}</Notice> : null}
      {notice ? <Notice tone="success">{notice}</Notice> : null}

      {records.map((record) => {
        const operator = record.approvals.find((entry) => entry.step === 'operator')
        const supervisor = record.approvals.find((entry) => entry.step === 'supervisor')

        return (
          <Panel key={record.code}>
            <PanelHeader
              title={ar ? record.titleAr : record.title}
              subtitle={`${record.code} · ${record.assetCode} · ${dateTime(record.createdAt)}`}
              action={
                <span
                  className={cn(
                    'inline-flex shrink-0 items-center rounded-full border px-2.5 py-0.5 text-[11px] font-medium',
                    STATUS_TONE[record.status] ?? STATUS_TONE.pending,
                  )}
                >
                  {t(`decisions.status.${record.status}`)}
                </span>
              }
            />
            <PanelBody className="space-y-3 pt-0">
              <p className="text-[11px] leading-relaxed text-text-muted">
                {ar ? record.rationaleAr : record.rationale}
              </p>

              <div className="flex flex-wrap gap-x-6 gap-y-1 border-y border-border/70 py-2 text-[11px]">
                <span className="tnum text-text-muted">
                  {t('decisions.riskChange')}{' '}
                  <span className="text-critical">{n(record.riskBefore, { maximumFractionDigits: 0 })}%</span>
                  {' → '}
                  <span className="text-normal">{n(record.riskAfter, { maximumFractionDigits: 0 })}%</span>
                </span>
                <span className="tnum text-text-muted">
                  {t('confidence.overall')} {n(record.confidence.overall, { maximumFractionDigits: 0 })}%
                </span>
                {record.confidence.isLowData ? (
                  <Badge tone="accent">{t('confidence.lowData')}</Badge>
                ) : null}
              </div>

              <div>
                <p className="text-[10px] uppercase tracking-wide text-text-faint">
                  {t('decisions.approvals')}
                </p>
                <ul className="mt-1.5 space-y-1">
                  {record.approvals.map((approval) => (
                    <li key={approval.step} className="flex flex-wrap items-baseline gap-x-2 text-[11px]">
                      <span className="font-medium text-text">{t(`decisions.step.${approval.step}`)}</span>
                      <span className="text-text-muted">{t(`decisions.decision.${approval.decision}`)}</span>
                      {approval.userName ? (
                        <span className="text-text-faint">
                          — {ar ? approval.userNameAr : approval.userName}
                        </span>
                      ) : null}
                      {approval.decidedAt ? (
                        <span className="tnum ms-auto text-text-faint">{dateTime(approval.decidedAt)}</span>
                      ) : null}
                    </li>
                  ))}
                </ul>
              </div>

              {record.outcome ? (
                <Notice tone="success">{ar ? record.outcomeAr : record.outcome}</Notice>
              ) : null}

              {record.status !== 'simulated' && record.status !== 'rejected' ? (
                <div className="space-y-2 border-t border-border/70 pt-3">
                  <Textarea
                    rows={2}
                    value={comments[record.code] ?? ''}
                    onChange={(event) =>
                      setComments((current) => ({ ...current, [record.code]: event.target.value }))
                    }
                    placeholder={t('decisions.commentPlaceholder')}
                    aria-label={t('decisions.comment')}
                  />
                  <div className="flex flex-wrap gap-2">
                    {canApprove && operator?.decision === 'pending' ? (
                      <>
                        <Button
                          size="sm"
                          onClick={() => act(record.code, 'operator', 'approved')}
                          loading={busy === `${record.code}-operator`}
                        >
                          {t('decisions.approve')} — {t('decisions.step.operator')}
                        </Button>
                        <Button
                          size="sm"
                          variant="ghost"
                          onClick={() => act(record.code, 'operator', 'rejected')}
                        >
                          {t('decisions.reject')}
                        </Button>
                      </>
                    ) : null}

                    {canSupervise && operator?.decision === 'approved' && supervisor?.decision === 'pending' ? (
                      <>
                        <Button
                          size="sm"
                          onClick={() => act(record.code, 'supervisor', 'approved')}
                          loading={busy === `${record.code}-supervisor`}
                        >
                          {t('decisions.approve')} — {t('decisions.step.supervisor')}
                        </Button>
                        <Button
                          size="sm"
                          variant="ghost"
                          onClick={() => act(record.code, 'supervisor', 'modified')}
                        >
                          {t('decisions.modify')}
                        </Button>
                      </>
                    ) : null}

                    {canApprove && record.status === 'approved' ? (
                      <Button
                        size="sm"
                        variant="secondary"
                        onClick={() => execute(record.code)}
                        loading={busy === `${record.code}-execute`}
                      >
                        {t('decisions.execute')}
                      </Button>
                    ) : null}

                    {!canApprove && !canSupervise ? (
                      <p className="text-[11px] text-text-faint">{t('decisions.noPermission')}</p>
                    ) : null}
                  </div>
                </div>
              ) : null}
            </PanelBody>
          </Panel>
        )
      })}
    </div>
  )
}
