import { 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((_, 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>
  );
}
