import React, { useState } from 'react';
import { CheckCircle2, XCircle, RotateCcw } from 'lucide-react';

// ── Types ──────────────────────────────────────────────────────────────────

export type Verdict = 'supported' | 'contradicted' | 'neither';

export interface ChartSeries {
  name: string;
  data: { label: string; value: number }[];
}

export interface ChartData {
  type: 'bar' | 'line';
  title: string;
  yLabel?: string;
  xLabel?: string;
  source?: string;
  unit?: string;          // e.g. '%', '°C', 'min'
  series: ChartSeries[];
}

export interface DataClaim {
  text: string;
  verdict: Verdict;
  explanation: string;
}

export interface DataExercise {
  title: string;
  chart: ChartData;
  claims: DataClaim[];
}

// ── Chart palette ──────────────────────────────────────────────────────────

const PALETTE = ['#3b82f6', '#8b5cf6', '#f97316', '#10b981', '#ef4444', '#ec4899'];

// ── BarChart ───────────────────────────────────────────────────────────────

function BarChart({ chart }: { chart: ChartData }) {
  const [hovered, setHovered] = useState<{ si: number; pi: number } | null>(null);

  const labels = chart.series[0].data.map(d => d.label);
  const allValues = chart.series.flatMap(s => s.data.map(d => d.value));
  const maxVal = Math.max(...allValues);
  // Round up max to nearest 10 for cleaner y-axis
  const yMax = Math.ceil(maxVal / 10) * 10;
  const yTicks = [0, yMax * 0.25, yMax * 0.5, yMax * 0.75, yMax];

  const chartH = 180; // px height of bar area

  return (
    <div className="px-2">
      <p className="text-xs font-semibold text-gray-600 text-center mb-4">{chart.title}</p>

      <div className="flex gap-2">
        {/* Y-axis */}
        <div className="flex flex-col-reverse justify-between items-end pr-1" style={{ height: chartH, minWidth: 32 }}>
          {yTicks.map(t => (
            <span key={t} className="text-[10px] text-gray-400 leading-none">{t}{chart.unit ?? ''}</span>
          ))}
        </div>

        {/* Bar groups */}
        <div className="flex-1 flex items-end gap-2 border-b border-l border-gray-300" style={{ height: chartH }}>
          {labels.map((label, pi) => (
            <div key={pi} className="flex-1 flex flex-col items-center gap-0">
              {/* Bar group */}
              <div className="w-full flex items-end gap-0.5" style={{ height: chartH - 2 }}>
                {chart.series.map((s, si) => {
                  const val = s.data[pi].value;
                  const heightPct = (val / yMax) * 100;
                  const isHov = hovered?.si === si && hovered?.pi === pi;
                  return (
                    <div
                      key={si}
                      className="relative flex-1 rounded-t-sm transition-all duration-150 cursor-pointer"
                      style={{
                        height: `${heightPct}%`,
                        backgroundColor: isHov
                          ? PALETTE[si % PALETTE.length] + 'dd'
                          : PALETTE[si % PALETTE.length] + 'cc',
                        outline: isHov ? `2px solid ${PALETTE[si % PALETTE.length]}` : 'none',
                      }}
                      onMouseEnter={() => setHovered({ si, pi })}
                      onMouseLeave={() => setHovered(null)}
                    >
                      {/* Value label on hover */}
                      {isHov && (
                        <div
                          className="absolute bottom-full left-1/2 -translate-x-1/2 mb-1 px-1.5 py-0.5 rounded text-[10px] font-bold text-white whitespace-nowrap z-10 pointer-events-none"
                          style={{ backgroundColor: PALETTE[si % PALETTE.length] }}
                        >
                          {val}{chart.unit ?? ''}
                        </div>
                      )}
                    </div>
                  );
                })}
              </div>
            </div>
          ))}
        </div>
      </div>

      {/* X-axis labels */}
      <div className="flex gap-2 ml-10 mt-1">
        {labels.map((label, i) => (
          <div key={i} className="flex-1 text-center text-[10px] text-gray-500 leading-tight">{label}</div>
        ))}
      </div>
      {chart.xLabel && <p className="text-[10px] text-gray-400 text-center mt-1">{chart.xLabel}</p>}

      {/* Legend */}
      {chart.series.length > 1 && (
        <div className="flex flex-wrap gap-3 mt-3 justify-center">
          {chart.series.map((s, si) => (
            <div key={si} className="flex items-center gap-1.5 text-xs text-gray-600">
              <div className="w-3 h-3 rounded-sm" style={{ backgroundColor: PALETTE[si % PALETTE.length] }} />
              {s.name}
            </div>
          ))}
        </div>
      )}

      {/* Hover info bar */}
      {hovered && (
        <div className="mt-3 text-xs text-center text-gray-600 bg-gray-50 rounded-lg py-1.5 px-3">
          <span className="font-semibold" style={{ color: PALETTE[hovered.si % PALETTE.length] }}>
            {chart.series[hovered.si].name}
          </span>
          {' — '}
          {chart.series[0].data[hovered.pi].label}: <span className="font-semibold">
            {chart.series[hovered.si].data[hovered.pi].value}{chart.unit ?? ''}
          </span>
        </div>
      )}

      {chart.source && <p className="text-[10px] text-gray-400 text-center mt-2">Source: {chart.source}</p>}
    </div>
  );
}

// ── LineChart ──────────────────────────────────────────────────────────────

function LineChart({ chart }: { chart: ChartData }) {
  const [hovered, setHovered] = useState<{ si: number; pi: number } | null>(null);

  const W = 480, H = 200;
  const PAD = { top: 20, right: 20, bottom: 36, left: 48 };
  const cW = W - PAD.left - PAD.right;
  const cH = H - PAD.top - PAD.bottom;

  const allValues = chart.series.flatMap(s => s.data.map(d => d.value));
  const minVal = Math.min(...allValues);
  const maxVal = Math.max(...allValues);
  const spread = maxVal - minVal || 1;

  // Add 10% padding on y-axis
  const yPad = spread * 0.15;
  const yMin = minVal - yPad;
  const yMax = maxVal + yPad;
  const yRange = yMax - yMin;

  const labels = chart.series[0].data.map(d => d.label);
  const xStep = cW / (labels.length - 1);

  const xPos = (i: number) => PAD.left + i * xStep;
  const yPos = (v: number) => PAD.top + cH - ((v - yMin) / yRange) * cH;

  // Y-axis ticks: 5 evenly spaced
  const yTicks = Array.from({ length: 5 }, (_, i) => minVal + ((maxVal - minVal) / 4) * i);

  return (
    <div>
      <p className="text-xs font-semibold text-gray-600 text-center mb-2">{chart.title}</p>
      <div className="overflow-x-auto">
        <svg viewBox={`0 0 ${W} ${H}`} className="w-full" style={{ maxHeight: 220 }}>
          {/* Grid lines */}
          {yTicks.map((t, i) => {
            const y = yPos(t);
            return (
              <g key={i}>
                <line x1={PAD.left} x2={W - PAD.right} y1={y} y2={y} stroke="#e5e7eb" strokeWidth="1" />
                <text x={PAD.left - 4} y={y + 3.5} textAnchor="end" fontSize="9" fill="#9ca3af">
                  {t % 1 === 0 ? t : t.toFixed(2)}{chart.unit ?? ''}
                </text>
              </g>
            );
          })}

          {/* Lines + dots */}
          {chart.series.map((s, si) => {
            const color = PALETTE[si % PALETTE.length];
            const pts = s.data.map((d, i) => `${xPos(i)},${yPos(d.value)}`).join(' ');
            return (
              <g key={si}>
                <polyline points={pts} fill="none" stroke={color} strokeWidth="2.5" strokeLinejoin="round" />
                {s.data.map((d, pi) => {
                  const isHov = hovered?.si === si && hovered?.pi === pi;
                  const cx = xPos(pi);
                  const cy = yPos(d.value);
                  return (
                    <g key={pi}>
                      <circle
                        cx={cx} cy={cy} r={isHov ? 7 : 5}
                        fill={color} stroke="white" strokeWidth="2"
                        style={{ cursor: 'pointer', transition: 'r 0.1s' }}
                        onMouseEnter={() => setHovered({ si, pi })}
                        onMouseLeave={() => setHovered(null)}
                      />
                      {isHov && (
                        <>
                          <rect
                            x={cx - 28} y={cy - 26} width="56" height="18"
                            rx="4" fill="#1f2937"
                          />
                          <text x={cx} y={cy - 13} textAnchor="middle" fontSize="10" fill="white" fontWeight="bold">
                            {d.value}{chart.unit ?? ''}
                          </text>
                        </>
                      )}
                    </g>
                  );
                })}
              </g>
            );
          })}

          {/* X-axis labels */}
          {labels.map((label, i) => (
            <text key={i} x={xPos(i)} y={H - PAD.bottom + 14} textAnchor="middle" fontSize="9.5" fill="#6b7280">
              {label}
            </text>
          ))}

          {/* Axes */}
          <line x1={PAD.left} x2={PAD.left} y1={PAD.top} y2={H - PAD.bottom} stroke="#d1d5db" strokeWidth="1.5" />
          <line x1={PAD.left} x2={W - PAD.right} y1={H - PAD.bottom} y2={H - PAD.bottom} stroke="#d1d5db" strokeWidth="1.5" />

          {/* Y-axis label */}
          {chart.yLabel && (
            <text
              x={12} y={H / 2}
              transform={`rotate(-90, 12, ${H / 2})`}
              textAnchor="middle" fontSize="9" fill="#9ca3af"
            >
              {chart.yLabel}
            </text>
          )}
        </svg>
      </div>

      {/* Legend */}
      {chart.series.length > 1 && (
        <div className="flex flex-wrap gap-3 mt-1 justify-center">
          {chart.series.map((s, si) => (
            <div key={si} className="flex items-center gap-1.5 text-xs text-gray-600">
              <div className="w-5 h-0.5" style={{ backgroundColor: PALETTE[si % PALETTE.length] }} />
              {s.name}
            </div>
          ))}
        </div>
      )}

      {/* Hover tooltip */}
      {hovered && (
        <div className="mt-2 text-xs text-center text-gray-600 bg-gray-50 rounded-lg py-1.5 px-3">
          <span className="font-semibold" style={{ color: PALETTE[hovered.si % PALETTE.length] }}>
            {chart.series[hovered.si].name}
          </span>
          {' · '}
          {chart.series[0].data[hovered.pi].label}: <span className="font-semibold">
            {chart.series[hovered.si].data[hovered.pi].value}{chart.unit ?? ''}
          </span>
        </div>
      )}

      {chart.source && <p className="text-[10px] text-gray-400 text-center mt-2">Source: {chart.source}</p>}
    </div>
  );
}

// ── Main widget ────────────────────────────────────────────────────────────

const VERDICT_LABELS: Record<Verdict, string> = {
  supported: 'Supported by data',
  contradicted: 'Contradicted by data',
  neither: 'Neither proven nor disproven',
};

interface DataClaimWidgetProps {
  exercises: DataExercise[];
  accentColor?: string;
}

// Pre-resolved accent classes to avoid Tailwind purge issues
const ACCENT_CLASSES: Record<string, { tab: string; header: string; label: string; btn: string }> = {
  amber:   { tab: 'border-b-2 border-amber-600 text-amber-700',   header: 'bg-amber-50',   label: 'text-amber-600',   btn: 'bg-amber-600 hover:bg-amber-700' },
  teal:    { tab: 'border-b-2 border-teal-600 text-teal-700',     header: 'bg-teal-50',     label: 'text-teal-600',     btn: 'bg-teal-600 hover:bg-teal-700' },
  purple:  { tab: 'border-b-2 border-purple-600 text-purple-700', header: 'bg-purple-50',   label: 'text-purple-600',   btn: 'bg-purple-600 hover:bg-purple-700' },
  fuchsia: { tab: 'border-b-2 border-fuchsia-600 text-fuchsia-700', header: 'bg-fuchsia-50', label: 'text-fuchsia-600', btn: 'bg-fuchsia-600 hover:bg-fuchsia-700' },
};

export default function DataClaimWidget({ exercises, accentColor = 'amber' }: DataClaimWidgetProps) {
  const [activeEx, setActiveEx] = useState(0);
  const [answers, setAnswers] = useState<Record<number, Verdict>>({});
  const [submitted, setSubmitted] = useState(false);

  const exercise = exercises[activeEx];
  const allAnswered = exercise.claims.every((_, i) => answers[i] !== undefined);
  const score = submitted ? exercise.claims.filter((c, i) => answers[i] === c.verdict).length : 0;
  const c = ACCENT_CLASSES[accentColor] ?? ACCENT_CLASSES.amber;

  const reset = () => { setAnswers({}); setSubmitted(false); };
  const switchEx = (i: number) => { setActiveEx(i); setAnswers({}); setSubmitted(false); };

  return (
    <div className="rounded-2xl border border-gray-200 bg-white overflow-hidden shadow-sm">
      {/* Tabs */}
      {exercises.length > 1 && (
        <div className="flex border-b border-gray-200 bg-gray-50 overflow-x-auto">
          {exercises.map((ex, i) => (
            <button
              key={i}
              onClick={() => switchEx(i)}
              className={`px-4 py-2.5 text-sm font-medium whitespace-nowrap transition-colors bg-white ${
                i === activeEx ? c.tab : 'text-gray-500 hover:text-gray-700'
              }`}
            >
              {ex.title}
            </button>
          ))}
        </div>
      )}

      {/* Chart */}
      <div className={`px-5 pt-5 pb-4 border-b border-gray-200 ${c.header}`}>
        <p className={`text-xs font-bold uppercase tracking-wider mb-4 ${c.label}`}>Data Source</p>
        {exercise.chart.type === 'bar'
          ? <BarChart chart={exercise.chart} />
          : <LineChart chart={exercise.chart} />
        }
      </div>

      {/* Claims */}
      <div className="px-5 py-4">
        <p className="text-sm text-gray-600 mb-4">
          For each claim, decide if the data{' '}
          <strong className="text-green-700">supports</strong>,{' '}
          <strong className="text-red-600">contradicts</strong>, or{' '}
          <strong className="text-gray-600">neither proves nor disproves</strong> it:
        </p>
        <div className="space-y-4">
          {exercise.claims.map((claim, i) => {
            const userAnswer = answers[i];
            const isCorrect = submitted && userAnswer === claim.verdict;
            const isWrong = submitted && userAnswer !== undefined && userAnswer !== claim.verdict;
            return (
              <div
                key={i}
                className={`rounded-xl border p-4 transition-all ${
                  submitted
                    ? isCorrect ? 'border-green-300 bg-green-50'
                    : isWrong ? 'border-red-200 bg-red-50'
                    : 'border-gray-200'
                    : 'border-gray-200'
                }`}
              >
                <p className="text-sm text-gray-800 mb-3">
                  <span className="font-bold text-gray-400 mr-2">Claim {i + 1}:</span>
                  {claim.text}
                </p>
                <div className="flex flex-wrap gap-2">
                  {(['supported', 'contradicted', 'neither'] as Verdict[]).map(v => {
                    const isSelected = userAnswer === v;
                    const isCorrectOpt = submitted && v === claim.verdict;
                    let cls = 'border-gray-200 text-gray-600 hover:border-gray-400 hover:bg-gray-50';
                    if (isSelected && !submitted) cls = `border-amber-500 bg-amber-50 text-amber-800 font-semibold`;
                    if (submitted) {
                      if (isCorrectOpt) cls = 'border-green-400 bg-green-100 text-green-800 font-semibold';
                      else if (isSelected) cls = 'border-red-300 bg-red-100 text-red-700';
                      else cls = 'border-gray-100 text-gray-400';
                    }
                    return (
                      <button
                        key={v}
                        disabled={submitted}
                        onClick={() => setAnswers(prev => ({ ...prev, [i]: v }))}
                        className={`px-3 py-1.5 rounded-full border text-xs transition-all ${cls}`}
                      >
                        {VERDICT_LABELS[v]}
                      </button>
                    );
                  })}
                </div>
                {submitted && (
                  <div className="mt-3 pt-2 border-t border-gray-100 flex gap-2">
                    {isCorrect
                      ? <CheckCircle2 className="w-4 h-4 text-green-600 shrink-0 mt-0.5" />
                      : <XCircle className="w-4 h-4 text-red-500 shrink-0 mt-0.5" />
                    }
                    <p className="text-xs text-gray-600 leading-relaxed">
                      {!isCorrect && (
                        <span className="font-semibold text-red-700">Answer: {VERDICT_LABELS[claim.verdict]}. </span>
                      )}
                      {claim.explanation}
                    </p>
                  </div>
                )}
              </div>
            );
          })}
        </div>
      </div>

      {/* Footer */}
      <div className="px-5 pb-5">
        {!submitted ? (
          <button
            disabled={!allAnswered}
            onClick={() => setSubmitted(true)}
            className={`px-5 py-2.5 rounded-full text-sm font-bold text-white transition-colors ${
              allAnswered ? c.btn : 'bg-gray-200 text-gray-400 cursor-not-allowed'
            }`}
          >
            Check all answers
          </button>
        ) : (
          <div className="flex items-center gap-4">
            <p className="text-sm font-semibold text-gray-700">
              {score}/{exercise.claims.length} correct
            </p>
            <button onClick={reset} className="flex items-center gap-1.5 text-sm text-gray-500 hover:text-gray-700 transition-colors">
              <RotateCcw className="w-3.5 h-3.5" /> Try again
            </button>
          </div>
        )}
      </div>
    </div>
  );
}
