'use client'

import { Badge, EmptyState, 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 cascade probability tree and its break points (§43, §44, §45).
 *
 * The 3.0 timeline answers "what happens, in what order". This answers the two questions
 * a timeline cannot: which *branch* is dangerous, and where can the chain be cut for the
 * least effort.
 *
 * Each hop shows two probabilities, deliberately: the conditional one ("if it reaches
 * L-22, it has a 44 % chance of reaching S-04") and the path one ("18 % chance of
 * reaching S-04 at all"). Showing only the second makes deep branches look harmless;
 * showing only the first makes them look inevitable.
 */

export interface TreeNodeView {
  assetCode: string
  assetName: string
  assetNameAr: string
  assetTypeKey: string
  depth: number
  offsetMin: number
  hopProbability: number
  probability: number
  confidence: number
  delayMin: number
  mechanism: string
  outcome: string
  loadPctAfter: number
  capacityMw: number
  unservedMw: number
  customers: number
  severity: string
  children: TreeNodeView[]
  subtreeCustomers: number
  subtreeUnservedMw: number
  subtreeNodes: number
}

export interface BreakpointView {
  assetCode: string
  assetName: string
  assetNameAr: string
  depth: number
  offsetMin: number
  riskReduction: number
  branchesStopped: number
  customersProtected: number
  interventionMw: number
  costIndex: number
  feasible: boolean
  isBest: boolean
  rationale: string
  rationaleAr: string
}

const SEVERITY_TONE: Record<string, string> = {
  low: 'border-border bg-surface-2',
  medium: 'border-watch/35 bg-watch/8',
  high: 'border-warning/35 bg-warning/8',
  critical: 'border-critical/35 bg-critical/8',
}

function TreeBranch({ node, depth = 0 }: { node: TreeNodeView; depth?: number }) {
  const { t, locale } = useI18n()
  const num = (value: number, digits = 0) =>
    formatNumber(locale, value, { maximumFractionDigits: digits })

  return (
    <li className="min-w-0">
      <div
        className={cn('min-w-0 rounded-lg border px-3 py-2', SEVERITY_TONE[node.severity] ?? SEVERITY_TONE.low)}
        // Indent by depth using a logical property so the tree reads correctly in Arabic.
        style={{ marginInlineStart: depth === 0 ? 0 : '1rem' }}
      >
        <div className="flex flex-wrap items-baseline gap-2">
          <span className="font-mono text-[12px] font-semibold">{node.assetCode}</span>
          <span className="min-w-0 truncate text-[11px] text-text-muted">
            {locale === 'ar' ? node.assetNameAr : node.assetName}
          </span>
          <span className="ms-auto shrink-0 font-mono text-[11px] tabular-nums text-text-faint">
            +{num(node.offsetMin)} {t('common.minShort')}
          </span>
        </div>

        <div className="mt-1 flex flex-wrap gap-x-3 gap-y-0.5 text-[10px] text-text-faint">
          {depth > 0 ? (
            <span>
              {t('cascadeTree.hopProbability')}:{' '}
              <span className="font-mono tabular-nums text-text-muted">
                {num(node.hopProbability * 100)}%
              </span>
            </span>
          ) : null}
          <span>
            {t('cascadeTree.pathProbability')}:{' '}
            <span className="font-mono tabular-nums text-text-muted">
              {num(node.probability * 100)}%
            </span>
          </span>
          <span>
            {t('common.confidence')}:{' '}
            <span className="font-mono tabular-nums text-text-muted">{num(node.confidence)}%</span>
          </span>
          {node.delayMin > 0 ? (
            <span>
              {t('cascadeTree.delay')}:{' '}
              <span className="font-mono tabular-nums text-text-muted">
                {num(node.delayMin)} {t('common.minShort')}
              </span>
            </span>
          ) : null}
        </div>
      </div>

      {node.children.length ? (
        <ul className="mt-1.5 space-y-1.5">
          {[...node.children]
            .sort((a, b) => b.probability - a.probability)
            .map((child) => (
              <TreeBranch key={child.assetCode} node={child} depth={depth + 1} />
            ))}
        </ul>
      ) : null}
    </li>
  )
}

export function CascadeTree({
  tree,
  breakpoints,
  contained,
}: {
  tree: TreeNodeView | null
  breakpoints: BreakpointView[]
  contained: boolean
}) {
  const { t, locale } = useI18n()
  const num = (value: number, digits = 1) =>
    formatNumber(locale, value, { maximumFractionDigits: digits })

  return (
    <div className="space-y-4">
      <Panel>
        <PanelHeader title={t('cascadeTree.title')} subtitle={t('cascadeTree.subtitle')} />
        <PanelBody>
          {!tree ? (
            <EmptyState title={t('uiState.empty')} body={t('cascadeTree.contained')} />
          ) : (
            <ul className="space-y-1.5">
              <TreeBranch node={tree} />
            </ul>
          )}
        </PanelBody>
      </Panel>

      <Panel>
        <PanelHeader
          title={t('cascadeTree.breakpoints')}
          subtitle={t('cascadeTree.breakpointsSubtitle')}
        />
        <PanelBody>
          {contained || breakpoints.filter((point) => point.feasible).length === 0 ? (
            <p className="rounded-lg border border-border bg-surface-2/50 px-3 py-2 text-[11px] leading-relaxed text-text-muted">
              {t('cascadeTree.contained')}
            </p>
          ) : (
            <ul className="space-y-2">
              {breakpoints.map((point) => (
                <li
                  key={point.assetCode}
                  className={cn(
                    'min-w-0 rounded-lg border px-3 py-2.5',
                    point.isBest
                      ? 'border-brand/45 bg-brand/8'
                      : point.feasible
                        ? 'border-border bg-surface-2/40'
                        : 'border-border bg-surface-2/20',
                  )}
                >
                  <div className="flex flex-wrap items-baseline gap-2">
                    <span className="font-mono text-[12px] font-semibold">{point.assetCode}</span>
                    <span className="min-w-0 truncate text-[11px] text-text-muted">
                      {locale === 'ar' ? point.assetNameAr : point.assetName}
                    </span>
                    {point.isBest ? (
                      <Badge tone="brand" dot>
                        {t('cascadeTree.bestBreak')}
                      </Badge>
                    ) : null}
                    {!point.feasible ? (
                      <Badge tone="muted">{t('cascadeTree.infeasible')}</Badge>
                    ) : null}
                  </div>

                  {point.feasible ? (
                    <div className="mt-1.5 grid grid-cols-2 gap-2 sm:grid-cols-4">
                      {(
                        [
                          ['cascadeTree.riskRemoved', `${num(point.riskReduction)}%`],
                          ['cascadeTree.intervention', `${num(point.interventionMw)} MW`],
                          ['cascadeTree.costIndex', num(point.costIndex)],
                          ['cascadeTree.branchesStopped', String(point.branchesStopped)],
                        ] as const
                      ).map(([key, value]) => (
                        <div key={key} className="min-w-0">
                          <p className="truncate text-[10px] text-text-faint">{t(key)}</p>
                          <p className="font-mono text-[12px] font-semibold tabular-nums">{value}</p>
                        </div>
                      ))}
                    </div>
                  ) : null}

                  <p className="mt-1.5 text-[10px] leading-relaxed text-text-muted">
                    {locale === 'ar' ? point.rationaleAr : point.rationale}
                  </p>
                </li>
              ))}
            </ul>
          )}
        </PanelBody>
      </Panel>
    </div>
  )
}
