"use client";

import { useState, useCallback } from "react";
import { Card } from "@/components/ui/card";
import { ClientOnly } from "@/components/ui/client-only";
import { StepControls } from "./step-controls";
import { MathDisplay } from "@/components/math/math-display";

interface Column {
  exponent: number;
  placeValue: number;
  digit: string;
  contrib: number;
}

interface Step {
  label: string;
  math: string;
  activeCol: number | null;
  revealed: number; // how many columns show their contribution
}

const PLACE_NAMES = ["ones", "tens", "hundreds", "thousands", "ten thousands", "hundred thousands"];

function columnsFor(n: number): Column[] {
  const str = `${n}`;
  const len = str.length;
  return str.split("").map((d, i) => {
    const exponent = len - 1 - i;
    return {
      exponent,
      placeValue: Math.pow(10, exponent),
      digit: d,
      contrib: parseInt(d, 10) * Math.pow(10, exponent),
    };
  });
}

function buildSteps(n: number): Step[] {
  const cols = columnsFor(n);
  const len = cols.length;
  const steps: Step[] = [
    {
      label: "In the denary (base 10) system, each digit has a place value that is a power of 10.",
      math: `${n}`,
      activeCol: null,
      revealed: 0,
    },
  ];

  cols.forEach((c, i) => {
    steps.push({
      label: `The ${PLACE_NAMES[c.exponent]} digit is ${c.digit}. Its place value is 10^${c.exponent} = ${c.placeValue.toLocaleString("en-US")}.`,
      math: `${c.digit} \\times 10^{${c.exponent}} = ${c.contrib.toLocaleString("en-US")}`,
      activeCol: i,
      revealed: i + 1,
    });
  });

  const expanded = cols.map((c) => `${c.digit} \\times 10^{${c.exponent}}`).join(" + ");
  steps.push({
    label: "Put it all together — this is the number in expanded form.",
    math: `${n} = ${expanded}`,
    activeCol: null,
    revealed: len,
  });

  const sumParts = cols.map((c) => c.contrib.toLocaleString("en-US")).join(" + ");
  steps.push({
    label: "Add every part back up and you return to the original number.",
    math: `${sumParts} = ${n.toLocaleString("en-US")}`,
    activeCol: null,
    revealed: len,
  });

  return steps;
}

function PlaceValueChart({ columns, step }: { columns: Column[]; step: Step }) {
  return (
    <div className="overflow-x-auto rounded-xl border-2 border-unit-6/30 bg-unit-6-light/40 p-3">
      <table className="mx-auto border-collapse font-mono">
        <tbody>
          <tr>
            {columns.map((c, i) => (
              <td
                key={`p-${i}`}
                className={`min-w-[64px] border-2 border-unit-6/40 px-3 py-2 text-center text-sm font-bold text-unit-6-dark ${
                  step.activeCol === i ? "bg-unit-6 text-white" : "bg-unit-6-light"
                }`}
              >
                10<sup>{c.exponent}</sup>
              </td>
            ))}
          </tr>
          <tr>
            {columns.map((c, i) => (
              <td
                key={`v-${i}`}
                className={`min-w-[64px] border-2 border-unit-6/40 px-3 py-2 text-center text-sm font-bold text-unit-6 ${
                  step.activeCol === i ? "bg-unit-6-light" : "bg-surface"
                }`}
              >
                {c.placeValue.toLocaleString("en-US")}
              </td>
            ))}
          </tr>
          <tr>
            {columns.map((c, i) => (
              <td
                key={`d-${i}`}
                className={`min-w-[64px] border-2 border-unit-6/40 px-3 py-2 text-center text-2xl font-extrabold ${
                  step.activeCol === i ? "bg-unit-6-light text-unit-6-dark" : "bg-surface text-foreground"
                }`}
              >
                {c.digit}
              </td>
            ))}
          </tr>
          <tr>
            {columns.map((c, i) => (
              <td
                key={`c-${i}`}
                className={`min-w-[64px] border-2 border-unit-6/40 px-3 py-2 text-center text-sm font-bold ${
                  i < step.revealed ? "bg-correct-light text-correct" : "bg-[#fafbfc] text-muted/50"
                }`}
              >
                {i < step.revealed ? c.contrib.toLocaleString("en-US") : "_"}
              </td>
            ))}
          </tr>
        </tbody>
      </table>
    </div>
  );
}

// ── Quick practice ───────────────────────────────────────────────────────────

interface PracticeQ {
  prompt: string;
  answer: number;
}

function randInt(min: number, max: number) {
  return Math.floor(Math.random() * (max - min + 1)) + min;
}

function makeQuestion(): PracticeQ {
  if (Math.random() < 0.5) {
    // value of a digit
    const n = randInt(1000, 99999);
    const cols = columnsFor(n);
    const nonZero = cols.filter((c) => c.digit !== "0");
    const pick = nonZero[Math.floor(Math.random() * nonZero.length)];
    return {
      prompt: `In ${n.toLocaleString("en-US")}, what is the VALUE of the digit ${pick.digit}?`,
      answer: pick.contrib,
    };
  }
  // exponent of a named column
  const exp = randInt(0, 5);
  return {
    prompt: `Which power of 10 is the ${PLACE_NAMES[exp]} column? Enter the exponent.`,
    answer: exp,
  };
}

function QuickPractice() {
  const [q, setQ] = useState<PracticeQ>(() => makeQuestion());
  const [val, setVal] = useState("");
  const [feedback, setFeedback] = useState<"correct" | "incorrect" | null>(null);
  const [score, setScore] = useState({ correct: 0, total: 0 });

  function check() {
    const parsed = parseInt(val, 10);
    if (isNaN(parsed)) return;
    const correct = parsed === q.answer;
    setFeedback(correct ? "correct" : "incorrect");
    setScore((s) => ({ correct: s.correct + (correct ? 1 : 0), total: s.total + 1 }));
  }

  function next() {
    setQ(makeQuestion());
    setVal("");
    setFeedback(null);
  }

  return (
    <Card className="space-y-4">
      <div className="flex items-center justify-between">
        <p className="text-xs font-bold uppercase tracking-wider text-unit-6">Quick Practice</p>
        <span className="rounded-full bg-unit-6-light px-3 py-1 text-xs font-bold text-unit-6-dark">
          {score.correct}/{score.total}
        </span>
      </div>
      <p className="text-center text-lg font-bold">{q.prompt}</p>
      <div className="flex flex-wrap items-center justify-center gap-3">
        <input
          type="number"
          value={val}
          onChange={(e) => {
            setVal(e.target.value);
            setFeedback(null);
          }}
          onKeyDown={(e) => {
            if (e.key === "Enter") {
              if (feedback !== null) next();
              else check();
            }
          }}
          className={`w-32 rounded-lg border-2 px-3 py-2 text-center text-xl font-bold outline-none transition-colors ${
            feedback === "correct"
              ? "border-correct bg-correct-light"
              : feedback === "incorrect"
                ? "border-incorrect bg-incorrect-light"
                : "border-border focus:border-unit-6"
          }`}
          placeholder="?"
          aria-label="Your answer"
        />
        {feedback === null ? (
          <button onClick={check} className="rounded-lg bg-unit-6 px-5 py-2.5 text-sm font-bold text-white hover:bg-unit-6-dark">
            Check
          </button>
        ) : (
          <button onClick={next} className="rounded-lg bg-foreground px-5 py-2.5 text-sm font-bold text-background hover:bg-foreground/80">
            Next →
          </button>
        )}
      </div>
      {feedback === "correct" && <p className="text-center text-sm font-bold text-correct">Correct!</p>}
      {feedback === "incorrect" && (
        <p className="text-center text-sm font-bold text-incorrect">Not quite — the answer is {q.answer.toLocaleString("en-US")}.</p>
      )}
    </Card>
  );
}

// ── Main explorer ────────────────────────────────────────────────────────────

export function PlaceValueExplorer() {
  const [input, setInput] = useState("983275");
  const [error, setError] = useState("");
  const [columns, setColumns] = useState<Column[] | null>(null);
  const [steps, setSteps] = useState<Step[] | null>(null);
  const [currentStep, setCurrentStep] = useState(0);
  const [isPlaying, setIsPlaying] = useState(false);

  const done = steps ? currentStep >= steps.length - 1 : false;

  const reset = useCallback(() => {
    setSteps(null);
    setColumns(null);
    setCurrentStep(0);
    setIsPlaying(false);
  }, []);

  function handleGo() {
    setError("");
    const cleaned = input.replace(/[,\s]/g, "");
    const n = parseInt(cleaned, 10);
    if (isNaN(n) || !/^\d+$/.test(cleaned)) return setError("Enter a whole number (digits only).");
    if (n < 1 || n > 999999) return setError("Use a whole number between 1 and 999,999.");
    setColumns(columnsFor(n));
    setSteps(buildSteps(n));
    setCurrentStep(0);
    setIsPlaying(false);
  }

  const stepForward = useCallback(() => {
    if (!steps || currentStep >= steps.length - 1) return;
    setCurrentStep((s) => s + 1);
    if (currentStep + 1 >= steps.length - 1) setIsPlaying(false);
  }, [steps, currentStep]);

  const stepBack = useCallback(() => {
    if (currentStep <= 0) return;
    setCurrentStep((s) => s - 1);
  }, [currentStep]);

  const togglePlay = useCallback(() => setIsPlaying((p) => !p), []);

  const step = steps ? steps[currentStep] : null;

  return (
    <div className="space-y-4">
      {/* Input card */}
      <Card>
        <p className="mb-3 text-xs font-bold uppercase tracking-wider text-unit-6">
          Enter a whole number (up to 999,999)
        </p>
        <div className="flex flex-wrap items-center gap-3">
          <input
            type="text"
            inputMode="numeric"
            value={input}
            onChange={(e) => setInput(e.target.value)}
            onKeyDown={(e) => {
              if (e.key === "Enter") handleGo();
            }}
            className="w-44 rounded-lg border-2 border-unit-6 bg-surface px-3 py-2 text-center font-mono text-2xl font-bold text-unit-6 outline-none focus:border-unit-6-dark"
            aria-label="Number input"
          />
          <button
            onClick={handleGo}
            className="rounded-lg bg-unit-6 px-6 py-2.5 text-sm font-bold text-white transition-colors hover:bg-unit-6-dark"
          >
            Break Down →
          </button>
        </div>
        {error && <p className="mt-2 text-sm text-incorrect">{error}</p>}
      </Card>

      {/* Display card */}
      <Card className="flex min-h-[280px] flex-col items-center justify-center gap-4 p-6">
        {!step || !columns ? (
          <p className="text-muted/50">
            Enter a number above and click <strong>Break Down</strong>
          </p>
        ) : (
          <>
            <p className="text-center text-sm font-medium text-muted">{step.label}</p>
            <MathDisplay math={step.math} className="text-xl" />
            <PlaceValueChart columns={columns} step={step} />
          </>
        )}
      </Card>

      {/* Controls */}
      <Card className="p-4">
        <StepControls
          currentStep={currentStep + 1}
          totalSteps={steps?.length ?? 0}
          isPlaying={isPlaying}
          onStepForward={stepForward}
          onStepBack={stepBack}
          onTogglePlay={togglePlay}
          onReset={reset}
          canStepForward={!!steps && !done}
          canStepBack={!!steps && currentStep > 0}
        />
      </Card>

      {/* Quick practice */}
      <ClientOnly fallback={<Card className="min-h-[220px]" />}>
        <QuickPractice />
      </ClientOnly>
    </div>
  );
}
