'use client'

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 physics validator's report (§10, §11) and the operating envelope (§12, §13).
 *
 * Two components that belong together on screen: the envelope says where the asset is
 * allowed to be, and the validator says whether a proposed action keeps it there.
 *
 * The envelope is drawn as a single track with the five bands laid out along it and the
 * current position marked. That is the shape an engineer already has in their head, and
 * it makes "you are 8.8 points past the adjusted ceiling" a thing you can see rather than
 * a number you have to hold.
 */

export interface PhysicsCheckView {
  constraintCode: string
  label: string
  labelAr: string
  observedValue: number
  limitValue: number
  unit: string
  headroom: number
  passed: boolean
  severity: string
  reason: string
  reasonAr: string
}

export interface EnvelopeView {
  assetCode: string
  currentPct: number
  normalMaxPct: number
  recommendedMaxPct: number
  warningPct: number
  criticalPct: number
  physicalLimitPct: number
  adjustedMaxPct: number
  headroomPct: number
  ambientC: number
  band: string
  penalties: Array<{ key: string; points: number; label: string; labelAr: string }>
}

const BAND_TONE: Record<string, string> = {
  normal: 'text-normal',
  recommended: 'text-watch',
  warning: 'text-warning',
  critical: 'text-critical',
  beyond: 'text-emergency',
}

export function OperatingEnvelopePanel({ envelope }: { envelope: EnvelopeView }) {
  const { t, locale } = useI18n()
  const num = (value: number, digits = 1) =>
    formatNumber(locale, value, { maximumFractionDigits: digits })

  // The track runs from 60 % to nameplate; below 60 there is nothing to say and the
  // detail at the top is what matters.
  const FLOOR = 60
  const scale = (pct: number) =>
    Math.max(0, Math.min(100, ((pct - FLOOR) / (envelope.physicalLimitPct - FLOOR)) * 100))

  const segments = [
    { to: envelope.normalMaxPct, tone: 'bg-normal/45', key: 'normal' },
    { to: envelope.recommendedMaxPct, tone: 'bg-watch/45', key: 'recommended' },
    { to: envelope.warningPct, tone: 'bg-warning/45', key: 'warning' },
    { to: envelope.criticalPct, tone: 'bg-critical/45', key: 'critical' },
    { to: envelope.physicalLimitPct, tone: 'bg-emergency/50', key: 'beyond' },
  ]

  return (
    <Panel>
      <PanelHeader
        title={t('physics.envelopeTitle')}
        subtitle={t('physics.envelopeSubtitle')}
        action={
          <Badge tone={envelope.headroomPct < 0 ? 'accent' : 'brand'}>
            {t(`physics.band.${envelope.band}`)}
          </Badge>
        }
      />
      <PanelBody className="space-y-4">
        <div className="grid gap-3 sm:grid-cols-3">
          <div className="min-w-0">
            <p className="text-[11px] text-text-muted">{t('physics.current')}</p>
            <p className={cn('font-mono text-xl font-semibold tabular-nums', BAND_TONE[envelope.band])}>
              {num(envelope.currentPct)}%
            </p>
          </div>
          <div className="min-w-0">
            <p className="text-[11px] text-text-muted">{t('physics.adjustedCeiling')}</p>
            <p className="font-mono text-xl font-semibold tabular-nums">
              {num(envelope.adjustedMaxPct)}%
            </p>
          </div>
          <div className="min-w-0">
            <p className="text-[11px] text-text-muted">{t('physics.headroom')}</p>
            <p
              className={cn(
                'font-mono text-xl font-semibold tabular-nums',
                envelope.headroomPct < 0 ? 'text-critical' : 'text-normal',
              )}
            >
              {envelope.headroomPct >= 0 ? '+' : ''}
              {num(envelope.headroomPct)}
            </p>
          </div>
        </div>

        {/* ── The track ─────────────────────────────────────────────────────── */}
        <div>
          <div className="relative h-6 overflow-hidden rounded-lg border border-border bg-surface-3">
            {segments.map((segment, index) => {
              const from = index === 0 ? 0 : scale(segments[index - 1].to)
              const to = scale(segment.to)
              return (
                <div
                  key={segment.key}
                  className={cn('absolute inset-y-0', segment.tone)}
                  style={{ insetInlineStart: `${from}%`, width: `${Math.max(0, to - from)}%` }}
                  aria-hidden
                />
              )
            })}

            {/* The adjusted ceiling: today's limit, which is not a band edge. */}
            <div
              className="absolute inset-y-0 w-0.5 bg-text"
              style={{ insetInlineStart: `${scale(envelope.adjustedMaxPct)}%` }}
              aria-hidden
            />
            {/* Where the asset actually is. */}
            <div
              className="absolute inset-y-0 w-1 rounded-full bg-text shadow-[0_0_0_2px_var(--color-surface)]"
              style={{ insetInlineStart: `${scale(envelope.currentPct)}%` }}
              aria-hidden
            />
          </div>

          <div className="mt-1.5 flex items-center justify-between text-[10px] text-text-faint">
            <span className="font-mono tabular-nums">{FLOOR}%</span>
            <span>{t('physics.trackLegend')}</span>
            <span className="font-mono tabular-nums">{envelope.physicalLimitPct}%</span>
          </div>
        </div>

        {/* ── Why the ceiling moved (§13) ───────────────────────────────────── */}
        {envelope.penalties.length ? (
          <div>
            <p className="text-[11px] font-medium text-text-muted">{t('physics.whyCeiling')}</p>
            <ul className="mt-1.5 space-y-1">
              {envelope.penalties.map((penalty) => (
                <li key={penalty.key} className="flex items-start gap-2 text-[11px]">
                  <span className="mt-0.5 shrink-0 font-mono tabular-nums text-warning">
                    −{num(penalty.points)}
                  </span>
                  <span className="min-w-0 leading-relaxed text-text-muted">
                    {locale === 'ar' ? penalty.labelAr : penalty.label}
                  </span>
                </li>
              ))}
            </ul>
          </div>
        ) : (
          <p className="text-[11px] text-text-faint">{t('physics.noPenalties')}</p>
        )}
      </PanelBody>
    </Panel>
  )
}

export function PhysicsValidationPanel({
  verdict,
  checks,
  summary,
  summaryAr,
  confidence,
}: {
  verdict: string
  checks: PhysicsCheckView[]
  summary: string
  summaryAr: string
  confidence: number
}) {
  const { t, locale } = useI18n()
  const num = (value: number, digits = 1) =>
    formatNumber(locale, value, { maximumFractionDigits: digits })

  const tone = verdict === 'rejected' ? 'accent' : verdict === 'valid' ? 'brand' : 'info'

  return (
    <Panel>
      <PanelHeader
        title={t('physics.validationTitle')}
        subtitle={t('physics.validationSubtitle')}
        action={<Badge tone={tone} dot>{t(`physics.verdict.${verdict}`)}</Badge>}
      />
      <PanelBody className="space-y-3">
        <p
          className={cn(
            'rounded-lg border px-3 py-2 text-[12px] leading-relaxed',
            verdict === 'rejected'
              ? 'border-critical/30 bg-critical/8 text-critical'
              : 'border-border bg-surface-2/50 text-text-muted',
          )}
        >
          {locale === 'ar' ? summaryAr : summary}
        </p>

        {checks.length === 0 ? (
          <p className="text-[11px] text-text-faint">{t('physics.noChecks')}</p>
        ) : (
          <ul className="space-y-1.5">
            {[...checks]
              // Failures first: the reason a strategy was rejected should not need
              // scrolling to.
              .sort((a, b) => Number(a.passed) - Number(b.passed))
              .map((check) => (
                <li
                  key={check.constraintCode}
                  className={cn(
                    'min-w-0 rounded-lg border px-3 py-2',
                    check.passed
                      ? 'border-border bg-surface-2/40'
                      : check.severity === 'hard'
                        ? 'border-critical/30 bg-critical/8'
                        : 'border-warning/30 bg-warning/8',
                  )}
                >
                  <div className="flex items-start justify-between gap-2">
                    <span className="min-w-0 text-[11px] font-medium">
                      {locale === 'ar' ? check.labelAr : check.label}
                    </span>
                    <span
                      className={cn(
                        'shrink-0 font-mono text-[11px] tabular-nums',
                        check.passed ? 'text-normal' : 'text-critical',
                      )}
                    >
                      {check.passed ? '✓' : '✕'} {num(check.observedValue)}
                      {check.unit === '%' ? '%' : ` ${check.unit}`}
                    </span>
                  </div>
                  <p className="mt-0.5 text-[10px] leading-relaxed text-text-faint">
                    {locale === 'ar' ? check.reasonAr : check.reason}
                  </p>
                </li>
              ))}
          </ul>
        )}

        <p className="text-[11px] text-text-faint">
          {t('physics.tightest')}: <span className="font-mono tabular-nums">{num(confidence)}%</span>
          {' · '}
          {t('physics.constraintSource')}
        </p>
      </PanelBody>
    </Panel>
  )
}
