'use client'

import { useState } from 'react'

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

/**
 * The evidence chain (§49, §50, §51).
 *
 * Drawn as a vertical spine with one node per stage, each expandable to the value it
 * contributed and where that value came from. A judge pressing PROVE IT is asking a
 * specific question — "how did you get here?" — and the answer has to be walkable rather
 * than a wall of numbers.
 *
 * Two things are deliberately prominent: the provenance chip on every node, and the
 * weakest link. A chain that is 96 % confident in nine places and 45 % in one is a 45 %
 * chain, and saying so is more useful than an average that hides it.
 */

export interface EvidenceNodeView {
  key: string
  stage: string
  title: string
  titleAr: string
  detail: string
  detailAr: string
  sourceType: string
  sourceId: string
  value: number | null
  unit: string
  confidence: number
  freshnessMin: number
  modelVersion: string
  orderIndex: number
}

export interface EvidenceEdgeView {
  fromKey: string
  toKey: string
  relation: string
  label: string
  labelAr: string
}

export interface EvidenceBundleView {
  code: string
  assetCode: string
  nodes: EvidenceNodeView[]
  edges: EvidenceEdgeView[]
  weakestLink: { key: string; title: string; titleAr: string; confidence: number } | null
  missingStages: string[]
  measuredSharePct: number
}

const SOURCE_TONE: Record<string, string> = {
  live: 'border-normal/35 bg-normal/12 text-normal',
  simulated: 'border-simulation/35 bg-simulation/12 text-simulation',
  predicted: 'border-ai/35 bg-ai/12 text-ai',
  estimated: 'border-accent/35 bg-accent/12 text-accent',
  synthetic: 'border-border-strong bg-surface-2 text-text-muted',
  manual: 'border-border-strong bg-surface-2 text-text-muted',
}

const RELATION_TONE: Record<string, string> = {
  supports: 'text-normal',
  derives: 'text-text-faint',
  contradicts: 'text-critical',
  constrains: 'text-watch',
}

export function EvidenceChain({ bundle }: { bundle: EvidenceBundleView }) {
  const { t, locale } = useI18n()
  const [expanded, setExpanded] = useState<string | null>(null)
  const num = (value: number, digits = 1) =>
    formatNumber(locale, value, { maximumFractionDigits: digits })

  // Incoming edges by target, so each node can show what it was derived from and how.
  const incoming = new Map<string, EvidenceEdgeView[]>()
  for (const edge of bundle.edges) {
    const list = incoming.get(edge.toKey) ?? []
    list.push(edge)
    incoming.set(edge.toKey, list)
  }

  return (
    <Panel>
      <PanelHeader
        title={t('evidence.chainTitle')}
        subtitle={t('evidence.chainSubtitle')}
        action={
          <span title={t('evidence.measuredTooltip')}>
            <Badge tone="muted">
              {t('evidence.measured')}: {num(bundle.measuredSharePct)}%
            </Badge>
          </span>
        }
      />
      <PanelBody className="space-y-3">
        {bundle.weakestLink ? (
          <div className="rounded-lg border border-warning/30 bg-warning/8 px-3 py-2">
            <p className="text-[11px] font-medium text-warning">{t('evidence.weakestLink')}</p>
            <p className="mt-0.5 text-[11px] leading-relaxed text-text-muted">
              {locale === 'ar' ? bundle.weakestLink.titleAr : bundle.weakestLink.title} —{' '}
              <span className="font-mono tabular-nums">{num(bundle.weakestLink.confidence)}%</span>
              {'. '}
              {t('evidence.weakestNote')}
            </p>
          </div>
        ) : null}

        {bundle.missingStages.length ? (
          <p className="rounded-lg border border-border bg-surface-2/50 px-3 py-2 text-[11px] leading-relaxed text-text-muted">
            {t('evidence.missingStages')}:{' '}
            {bundle.missingStages.map((stage) => t(`evidence.stage.${stage}`)).join('، ')}
          </p>
        ) : null}

        {/* ── The spine ─────────────────────────────────────────────────────── */}
        <ol className="relative space-y-1.5">
          {/* The connecting line, behind the nodes. Logical inset so it lands on the
              correct side under RTL without a second rule. */}
          <span
            className="absolute inset-y-2 w-px bg-border"
            style={{ insetInlineStart: '0.6875rem' }}
            aria-hidden
          />

          {bundle.nodes.map((node) => {
            const isOpen = expanded === node.key
            const links = incoming.get(node.key) ?? []
            return (
              <li key={node.key} className="relative">
                <button
                  type="button"
                  onClick={() => setExpanded(isOpen ? null : node.key)}
                  aria-expanded={isOpen}
                  className="flex w-full min-w-0 items-start gap-3 rounded-lg px-2 py-1.5 text-start transition-colors hover:bg-surface-2"
                >
                  <span
                    className={cn(
                      'relative z-10 mt-0.5 grid size-6 shrink-0 place-items-center rounded-full border text-[10px] font-mono',
                      bundle.weakestLink?.key === node.key
                        ? 'border-warning bg-warning/15 text-warning'
                        : 'border-border-strong bg-surface text-text-faint',
                    )}
                  >
                    {node.orderIndex + 1}
                  </span>

                  <span className="min-w-0 flex-1">
                    <span className="flex flex-wrap items-center gap-2">
                      <span className="min-w-0 truncate text-[12px] font-medium">
                        {locale === 'ar' ? node.titleAr : node.title}
                      </span>
                      <span
                        className={cn(
                          'shrink-0 rounded-full border px-1.5 py-0.5 text-[9px] font-medium',
                          SOURCE_TONE[node.sourceType] ?? SOURCE_TONE.synthetic,
                        )}
                      >
                        {t(`source.${node.sourceType}`)}
                      </span>
                    </span>
                    <span className="mt-0.5 block truncate text-[11px] text-text-muted">
                      {locale === 'ar' ? node.detailAr : node.detail}
                    </span>
                  </span>

                  <span className="shrink-0 font-mono text-[11px] tabular-nums text-text-faint">
                    {num(node.confidence)}%
                  </span>
                </button>

                {isOpen ? (
                  <div
                    className="mt-1 space-y-1 rounded-lg border border-border bg-surface-2/50 px-3 py-2 text-[11px]"
                    style={{ marginInlineStart: '2.25rem' }}
                  >
                    <p className="leading-relaxed text-text-muted">
                      {locale === 'ar' ? node.detailAr : node.detail}
                    </p>
                    <dl className="grid gap-x-3 gap-y-0.5 sm:grid-cols-2">
                      <div className="flex justify-between gap-2">
                        <dt className="text-text-faint">{t('evidence.source')}</dt>
                        <dd className="truncate font-mono text-text-muted">{node.sourceId || '—'}</dd>
                      </div>
                      <div className="flex justify-between gap-2">
                        <dt className="text-text-faint">{t('evidence.stageLabel')}</dt>
                        <dd className="text-text-muted">{t(`evidence.stage.${node.stage}`)}</dd>
                      </div>
                      {node.value !== null ? (
                        <div className="flex justify-between gap-2">
                          <dt className="text-text-faint">{t('evidence.value')}</dt>
                          <dd className="font-mono tabular-nums text-text-muted">
                            {num(node.value, 2)} {node.unit}
                          </dd>
                        </div>
                      ) : null}
                      {node.modelVersion ? (
                        <div className="flex justify-between gap-2">
                          <dt className="text-text-faint">{t('evidence.model')}</dt>
                          <dd className="truncate font-mono text-text-muted">{node.modelVersion}</dd>
                        </div>
                      ) : null}
                    </dl>

                    {links.length ? (
                      <p className="pt-1 text-[10px] text-text-faint">
                        {t('evidence.derivedFrom')}:{' '}
                        {links.map((edge, index) => (
                          <span key={`${edge.fromKey}-${index}`}>
                            {index > 0 ? '، ' : ''}
                            <span className={RELATION_TONE[edge.relation] ?? ''}>
                              {t(`evidence.relation.${edge.relation}`)}
                            </span>{' '}
                            {edge.fromKey}
                          </span>
                        ))}
                      </p>
                    ) : null}
                  </div>
                ) : null}
              </li>
            )
          })}
        </ol>
      </PanelBody>
    </Panel>
  )
}
