/**
 * ComparisonMode — Feature 3.6
 *
 * Side-by-side comparison of two prediction scenarios (Before/After).
 * Users pick two mock patients (or two sets of parameters) and the component
 * runs both predictions and highlights the differences.
 *
 * Works with Engineering Mode style (no auth required) so it uses the
 * public /predict endpoint via the existing api utility.
 */

import { useState, useCallback } from 'react'
import {
  BarChart, Bar, XAxis, YAxis, CartesianGrid, Tooltip, Legend, Cell, ResponsiveContainer,
} from 'recharts'
import {
  ArrowLeftRight, TrendingUp, TrendingDown, Minus, Loader2, AlertCircle,
  ChevronDown, CheckCircle2, XCircle,
} from 'lucide-react'
import { api } from '../api'
import { useDisease } from '../context/DiseaseContext'
import { useDiseaseSchema } from '../hooks/useDiseaseSchema'
import { getPatientsForDisease } from '../mockPatients'

// ── Helpers ───────────────────────────────────────────────────────────────────

function riskScore(result) {
  if (!result) return null
  return result.prediction === 1 ? result.confidence : 1 - result.confidence
}

function DeltaBadge({ before, after }) {
  if (before == null || after == null) return null
  const delta = after - before
  const pct = Math.round(Math.abs(delta) * 100)
  if (pct === 0) return <span className="text-xs text-gray-400 flex items-center gap-0.5"><Minus className="w-3 h-3" /> No change</span>
  const improving = delta < 0
  return (
    <span className={`text-xs font-semibold flex items-center gap-0.5 ${improving ? 'text-green-600' : 'text-red-600'}`}>
      {improving ? <TrendingDown className="w-3.5 h-3.5" /> : <TrendingUp className="w-3.5 h-3.5" />}
      {improving ? '↓' : '↑'}{pct}% risk
    </span>
  )
}

// ── Patient picker ────────────────────────────────────────────────────────────

function PatientPicker({ label, patients, selected, onSelect, color }) {
  const [open, setOpen] = useState(false)

  return (
    <div className="relative">
      <p className={`text-xs font-semibold uppercase tracking-wide mb-1 ${color}`}>{label}</p>
      <button
        onClick={() => setOpen(o => !o)}
        className="w-full flex items-center justify-between gap-2 p-3 bg-gray-50 border border-clinical-border rounded-lg hover:bg-gray-100 transition-colors text-left"
      >
        <div className="flex items-center gap-2 min-w-0">
          <div className="w-8 h-8 rounded-full bg-primary-100 text-primary-700 flex items-center justify-center text-xs font-bold flex-shrink-0">
            {selected?.avatar}
          </div>
          <div className="min-w-0">
            <p className="text-sm font-medium text-gray-900 truncate">{selected?.name ?? 'Select patient'}</p>
            {selected && <p className="text-[10px] text-gray-500">{selected.age}yrs · {selected.sex}</p>}
          </div>
        </div>
        <ChevronDown className={`w-4 h-4 text-gray-400 flex-shrink-0 transition-transform ${open ? 'rotate-180' : ''}`} />
      </button>
      {open && (
        <>
          <div className="fixed inset-0 z-10" onClick={() => setOpen(false)} />
          <div className="absolute top-full left-0 right-0 mt-1 bg-white border border-clinical-border rounded-lg shadow-lg z-20 overflow-hidden">
            {patients.map(p => (
              <button
                key={p.id}
                onClick={() => { onSelect(p); setOpen(false) }}
                className={`w-full flex items-center gap-3 px-3 py-2.5 text-left hover:bg-gray-50 transition-colors ${selected?.id === p.id ? 'bg-primary-50' : ''}`}
              >
                <div className="w-7 h-7 rounded-full bg-gray-100 text-gray-600 flex items-center justify-center text-xs font-bold flex-shrink-0">
                  {p.avatar}
                </div>
                <div>
                  <p className="text-sm font-medium text-gray-900">{p.name}</p>
                  <p className="text-[10px] text-gray-500">{p.age}yrs · {p.sex}</p>
                </div>
              </button>
            ))}
          </div>
        </>
      )}
    </div>
  )
}

// ── Result column ─────────────────────────────────────────────────────────────

function ResultColumn({ label, result, loading, error, color, colorLight }) {
  if (loading) return (
    <div className="flex-1 flex items-center justify-center py-12">
      <Loader2 className={`w-6 h-6 animate-spin ${color}`} />
    </div>
  )
  if (error) return (
    <div className="flex-1 flex items-center gap-2 py-8 px-4">
      <AlertCircle className="w-4 h-4 text-red-500 flex-shrink-0" />
      <p className="text-xs text-red-600">{error}</p>
    </div>
  )
  if (!result) return (
    <div className="flex-1 flex items-center justify-center py-12 text-gray-300 text-sm">
      No result yet
    </div>
  )

  const isPositive = result.prediction === 1
  const conf = Math.round((result.confidence ?? 0) * 100)

  return (
    <div className="flex-1 space-y-4 p-4">
      {/* Badge */}
      <div className={`rounded-xl p-4 text-center ${isPositive ? 'bg-red-50 border border-red-200' : 'bg-green-50 border border-green-200'}`}>
        <div className="flex items-center justify-center gap-2 mb-2">
          {isPositive
            ? <XCircle className="w-5 h-5 text-red-600" />
            : <CheckCircle2 className="w-5 h-5 text-green-600" />}
          <span className={`text-base font-bold ${isPositive ? 'text-red-700' : 'text-green-700'}`}>
            {result.diagnosis ?? (isPositive ? 'Positive' : 'Negative')}
          </span>
        </div>
        <p className="text-xs text-gray-500">Confidence</p>
        <p className={`text-2xl font-black ${isPositive ? 'text-red-600' : 'text-green-600'}`}>{conf}%</p>
        <div className="mt-2 h-2 bg-gray-200 rounded-full overflow-hidden">
          <div
            className={`h-full rounded-full ${isPositive ? 'bg-red-500' : 'bg-green-500'}`}
            style={{ width: `${conf}%` }}
          />
        </div>
      </div>

      {/* Risk score */}
      <div className="text-center">
        <p className="text-xs text-gray-500 uppercase tracking-wide">Risk Score</p>
        <p className={`text-3xl font-black mt-1 ${colorLight}`}>
          {Math.round(riskScore(result) * 100)}%
        </p>
      </div>
    </div>
  )
}

// ── Feature diff table ────────────────────────────────────────────────────────

function FeatureDiffTable({ beforePatient, afterPatient, fields }) {
  if (!beforePatient || !afterPatient) return null

  const b = beforePatient.data || {}
  const a = afterPatient.data || {}

  const diffs = fields
    .filter(f => String(b[f.name]) !== String(a[f.name]))
    .map(f => ({ name: f.name, label: f.label || f.name, before: b[f.name], after: a[f.name] }))

  if (diffs.length === 0) {
    return (
      <div className="text-center py-6 text-sm text-gray-400">
        Both patients have identical feature values.
      </div>
    )
  }

  return (
    <div className="overflow-x-auto rounded-xl border border-clinical-border">
      <table className="w-full text-xs">
        <thead className="bg-slate-50">
          <tr>
            <th className="text-left px-4 py-2.5 text-gray-500 font-medium uppercase tracking-wide text-[10px]">Feature</th>
            <th className="text-left px-4 py-2.5 text-blue-600 font-medium uppercase tracking-wide text-[10px]">Before</th>
            <th className="text-left px-4 py-2.5 text-violet-600 font-medium uppercase tracking-wide text-[10px]">After</th>
            <th className="text-left px-4 py-2.5 text-gray-500 font-medium uppercase tracking-wide text-[10px]">Change</th>
          </tr>
        </thead>
        <tbody className="divide-y divide-clinical-border">
          {diffs.map(d => {
            const numBefore = parseFloat(d.before)
            const numAfter = parseFloat(d.after)
            const isNumeric = !isNaN(numBefore) && !isNaN(numAfter)
            const delta = isNumeric ? numAfter - numBefore : null
            return (
              <tr key={d.name} className="hover:bg-slate-50 transition-colors">
                <td className="px-4 py-2.5 font-medium text-gray-800">{d.label}</td>
                <td className="px-4 py-2.5 text-blue-700 font-mono">{String(d.before ?? '—')}</td>
                <td className="px-4 py-2.5 text-violet-700 font-mono">{String(d.after ?? '—')}</td>
                <td className="px-4 py-2.5">
                  {delta != null ? (
                    <span className={`font-semibold ${delta > 0 ? 'text-red-500' : delta < 0 ? 'text-green-600' : 'text-gray-400'}`}>
                      {delta > 0 ? `+${delta.toFixed(1)}` : delta < 0 ? delta.toFixed(1) : '='}
                    </span>
                  ) : (
                    <span className="text-gray-400">{d.before} → {d.after}</span>
                  )}
                </td>
              </tr>
            )
          })}
        </tbody>
      </table>
    </div>
  )
}

// ── Side-by-side confidence chart ─────────────────────────────────────────────

function ComparisonChart({ beforeResult, afterResult, beforeName, afterName }) {
  if (!beforeResult || !afterResult) return null

  const data = [
    {
      name: 'Risk Score',
      Before: Math.round(riskScore(beforeResult) * 100),
      After:  Math.round(riskScore(afterResult) * 100),
    },
    {
      name: 'Confidence',
      Before: Math.round((beforeResult.confidence ?? 0) * 100),
      After:  Math.round((afterResult.confidence ?? 0) * 100),
    },
  ]

  return (
    <div className="card">
      <div className="card-header">
        <h3 className="text-sm font-semibold text-gray-900">Side-by-Side Metrics</h3>
      </div>
      <div className="card-body">
        <ResponsiveContainer width="100%" height={180}>
          <BarChart data={data} margin={{ top: 4, right: 16, left: -20, bottom: 0 }}>
            <CartesianGrid strokeDasharray="3 3" stroke="#e2e8f0" />
            <XAxis dataKey="name" tick={{ fontSize: 11 }} />
            <YAxis domain={[0, 100]} tickFormatter={v => `${v}%`} tick={{ fontSize: 10 }} />
            <Tooltip formatter={(v) => [`${v}%`]} />
            <Legend />
            <Bar name={beforeName} dataKey="Before" fill="#2563eb" radius={[4, 4, 0, 0]} />
            <Bar name={afterName}  dataKey="After"  fill="#7c3aed" radius={[4, 4, 0, 0]} />
          </BarChart>
        </ResponsiveContainer>
      </div>
    </div>
  )
}

// ── Main ComparisonMode ───────────────────────────────────────────────────────

export default function ComparisonMode() {
  const { selectedDisease } = useDisease()
  const { fields } = useDiseaseSchema(selectedDisease)
  const patients = getPatientsForDisease(selectedDisease)

  const [beforePatient, setBeforePatient] = useState(patients[0] ?? null)
  const [afterPatient,  setAfterPatient]  = useState(patients[1] ?? patients[0] ?? null)
  const [beforeResult,  setBeforeResult]  = useState(null)
  const [afterResult,   setAfterResult]   = useState(null)
  const [beforeLoading, setBeforeLoading] = useState(false)
  const [afterLoading,  setAfterLoading]  = useState(false)
  const [beforeError,   setBeforeError]   = useState(null)
  const [afterError,    setAfterError]    = useState(null)
  const [ran, setRan] = useState(false)

  const runComparison = useCallback(async () => {
    if (!beforePatient || !afterPatient || !selectedDisease) return
    setRan(true)
    setBeforeResult(null)
    setAfterResult(null)
    setBeforeError(null)
    setAfterError(null)

    setBeforeLoading(true)
    setAfterLoading(true)

    const [bRes, aRes] = await Promise.allSettled([
      api.predict(selectedDisease, beforePatient.data),
      api.predict(selectedDisease, afterPatient.data),
    ])

    setBeforeLoading(false)
    setAfterLoading(false)

    if (bRes.status === 'fulfilled') setBeforeResult(bRes.value)
    else setBeforeError(bRes.reason?.message ?? 'Prediction failed')

    if (aRes.status === 'fulfilled') setAfterResult(aRes.value)
    else setAfterError(aRes.reason?.message ?? 'Prediction failed')
  }, [beforePatient, afterPatient, selectedDisease])

  const riskBefore = riskScore(beforeResult)
  const riskAfter  = riskScore(afterResult)

  return (
    <div className="space-y-6">
      {/* Header */}
      <div className="flex items-center justify-between">
        <div>
          <h2 className="text-lg font-bold text-gray-900 flex items-center gap-2">
            <ArrowLeftRight className="w-5 h-5 text-primary-600" /> Before / After Comparison
          </h2>
          <p className="text-sm text-gray-500 mt-0.5">
            Compare two patient profiles side by side to evaluate risk changes
          </p>
        </div>
      </div>

      {/* Patient selectors + compare button */}
      <div className="card">
        <div className="card-body">
          <div className="grid grid-cols-1 sm:grid-cols-2 gap-4 items-end">
            <PatientPicker
              label="Before"
              patients={patients}
              selected={beforePatient}
              onSelect={p => { setBeforePatient(p); setRan(false) }}
              color="text-blue-600"
            />
            <PatientPicker
              label="After"
              patients={patients}
              selected={afterPatient}
              onSelect={p => { setAfterPatient(p); setRan(false) }}
              color="text-violet-600"
            />
          </div>
          <div className="mt-4 flex justify-center">
            <button
              onClick={runComparison}
              disabled={!beforePatient || !afterPatient || beforeLoading || afterLoading}
              className="btn-primary text-sm flex items-center gap-2"
            >
              {(beforeLoading || afterLoading)
                ? <Loader2 className="w-4 h-4 animate-spin" />
                : <ArrowLeftRight className="w-4 h-4" />}
              {(beforeLoading || afterLoading) ? 'Running…' : 'Compare'}
            </button>
          </div>
        </div>
      </div>

      {/* Results panel */}
      {ran && (
        <>
          {/* Side-by-side result columns */}
          <div className="card">
            <div className="card-header flex items-center justify-between">
              <h3 className="text-sm font-semibold text-gray-900">Prediction Results</h3>
              {riskBefore != null && riskAfter != null && (
                <DeltaBadge before={riskBefore} after={riskAfter} />
              )}
            </div>
            <div className="flex divide-x divide-clinical-border">
              <div className="flex-1">
                <p className="text-xs font-semibold text-blue-600 uppercase tracking-wide text-center pt-4 px-4">
                  Before — {beforePatient?.name}
                </p>
                <ResultColumn
                  label="Before"
                  result={beforeResult}
                  loading={beforeLoading}
                  error={beforeError}
                  color="text-blue-600"
                  colorLight="text-blue-700"
                />
              </div>
              <div className="flex-1">
                <p className="text-xs font-semibold text-violet-600 uppercase tracking-wide text-center pt-4 px-4">
                  After — {afterPatient?.name}
                </p>
                <ResultColumn
                  label="After"
                  result={afterResult}
                  loading={afterLoading}
                  error={afterError}
                  color="text-violet-600"
                  colorLight="text-violet-700"
                />
              </div>
            </div>
          </div>

          {/* Chart comparison */}
          <ComparisonChart
            beforeResult={beforeResult}
            afterResult={afterResult}
            beforeName={beforePatient?.name ?? 'Before'}
            afterName={afterPatient?.name ?? 'After'}
          />

          {/* Feature diff table */}
          <div className="card">
            <div className="card-header">
              <h3 className="text-sm font-semibold text-gray-900">Changed Features</h3>
            </div>
            <div className="card-body">
              <FeatureDiffTable
                beforePatient={beforePatient}
                afterPatient={afterPatient}
                fields={fields ?? []}
              />
            </div>
          </div>
        </>
      )}

      {/* Empty state */}
      {!ran && (
        <div className="flex flex-col items-center justify-center py-20 text-center">
          <ArrowLeftRight className="w-12 h-12 text-gray-200 mb-4" />
          <p className="text-gray-500 text-sm">Select two patients and click Compare to see the results.</p>
        </div>
      )}
    </div>
  )
}
