"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";

type Mode = "identity" | "inverse" | "zero";
type Op = "add" | "multiply";

interface Step {
  label: string;
  math: string;
  danger?: boolean;
}

function buildIdentitySteps(n: number, op: Op): Step[] {
  if (op === "add") {
    return [
      { label: "The identity for addition is 0 — it leaves a number unchanged.", math: `${n} + 0` },
      { label: "Adding 0 changes nothing.", math: `${n} + 0 = ${n}` },
      { label: "So 0 is the identity element for addition.", math: `n + 0 = n` },
    ];
  }
  return [
    { label: "The identity for multiplication is 1 — it leaves a number unchanged.", math: `${n} \\times 1` },
    { label: "Multiplying by 1 changes nothing.", math: `${n} \\times 1 = ${n}` },
    { label: "So 1 is the identity element for multiplication.", math: `n \\times 1 = n` },
  ];
}

function buildInverseSteps(n: number, op: Op): Step[] {
  if (op === "add") {
    const inv = -n;
    const invText = inv < 0 ? `(${inv})` : `${inv}`;
    return [
      { label: "The additive inverse is the number that brings you back to the identity, 0.", math: `${n} + \\square = 0` },
      { label: `Flip the sign of ${n} to get its additive inverse.`, math: `\\text{inverse of } ${n} = ${inv}` },
      { label: "Check: adding a number and its inverse gives 0.", math: `${n} + ${invText} = 0` },
    ];
  }
  // multiplicative inverse (reciprocal)
  const absN = Math.abs(n);
  const recip = n < 0 ? `-\\frac{1}{${absN}}` : `\\frac{1}{${absN}}`;
  const recipParen = n < 0 ? `\\left(-\\frac{1}{${absN}}\\right)` : `\\frac{1}{${absN}}`;
  return [
    { label: "The multiplicative inverse (reciprocal) brings you back to the identity, 1.", math: `${n} \\times \\square = 1` },
    { label: `Write ${n} as a fraction and flip it. The sign stays in front.`, math: `\\text{inverse of } ${n} = ${recip}` },
    { label: "Check: a number times its reciprocal gives 1.", math: `${n} \\times ${recipParen} = 1` },
  ];
}

function buildZeroSteps(n: number): Step[] {
  return [
    { label: "Multiplying any number by zero always gives zero.", math: `${n} \\times 0 = 0` },
    { label: "Zero shared into any number of groups is still zero.", math: `0 \\div ${n === 0 ? 5 : n} = 0` },
    {
      label: "But you can never divide BY zero — there is no answer. It is undefined.",
      math: `${n} \\div 0 = \\text{undefined}`,
      danger: true,
    },
  ];
}

// ── 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 {
  const roll = Math.floor(Math.random() * 5);
  if (roll === 0) {
    const n = randInt(-12, 12) || 3;
    return { prompt: `What is the additive inverse of ${n}?`, answer: -n };
  }
  if (roll === 1) {
    const n = randInt(1, 20);
    return { prompt: `What is ${n} × 0?`, answer: 0 };
  }
  if (roll === 2) {
    return { prompt: `What number is the identity for addition?`, answer: 0 };
  }
  if (roll === 3) {
    return { prompt: `What number is the identity for multiplication?`, answer: 1 };
  }
  const n = randInt(2, 12);
  return { prompt: `The multiplicative inverse of ${n} is 1 over what number?`, answer: n };
}

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-8">Quick Practice</p>
        <span className="rounded-full bg-unit-8-light px-3 py-1 text-xs font-bold text-unit-8-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-24 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-8"
          }`}
          placeholder="?"
          aria-label="Your answer"
        />
        {feedback === null ? (
          <button onClick={check} className="rounded-lg bg-unit-8 px-5 py-2.5 text-sm font-bold text-white hover:bg-unit-8-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}.</p>
      )}
    </Card>
  );
}

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

export function IdentityInverseExplorer() {
  const [mode, setMode] = useState<Mode>("identity");
  const [op, setOp] = useState<Op>("add");
  const [input, setInput] = useState("3");
  const [error, setError] = useState("");

  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);
    setCurrentStep(0);
    setIsPlaying(false);
  }, []);

  function switchMode(m: Mode) {
    setMode(m);
    setError("");
    reset();
  }

  function handleGo() {
    setError("");
    const n = parseInt(input, 10);
    if (isNaN(n)) return setError("Enter a valid whole number.");
    if (Math.abs(n) > 100) return setError("Keep the number between -100 and 100.");
    if (mode === "inverse" && op === "multiply" && n === 0) {
      return setError("Zero has no multiplicative inverse — try another number.");
    }
    if (mode === "identity") setSteps(buildIdentitySteps(n, op));
    else if (mode === "inverse") setSteps(buildInverseSteps(n, op));
    else setSteps(buildZeroSteps(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;
  const showOp = mode !== "zero";

  return (
    <div className="space-y-4">
      {/* Mode toggle */}
      <div className="flex flex-wrap gap-2">
        {(["identity", "inverse", "zero"] as Mode[]).map((m) => (
          <button
            key={m}
            onClick={() => switchMode(m)}
            className={`rounded-full border-2 px-4 py-2 text-sm font-semibold transition-colors ${
              mode === m
                ? "border-unit-8 bg-unit-8 text-white"
                : "border-unit-8/40 text-unit-8 hover:bg-unit-8-light"
            }`}
          >
            {m === "identity" ? "Identity" : m === "inverse" ? "Inverse" : "Zero Facts"}
          </button>
        ))}
      </div>

      {/* Operation tabs */}
      {showOp && (
        <div className="flex flex-wrap gap-2">
          {(["add", "multiply"] as Op[]).map((o) => (
            <button
              key={o}
              onClick={() => {
                setOp(o);
                reset();
              }}
              className={`rounded-full border-2 px-4 py-2 text-sm font-semibold transition-colors ${
                op === o
                  ? "border-unit-8-dark bg-unit-8-dark text-white"
                  : "border-unit-8/30 text-unit-8-dark hover:bg-unit-8-light"
              }`}
            >
              {o === "add" ? "Addition" : "Multiplication"}
            </button>
          ))}
        </div>
      )}

      {/* Input card */}
      <Card>
        <p className="mb-3 text-xs font-bold uppercase tracking-wider text-unit-8">
          {mode === "identity"
            ? "See how the identity leaves a number unchanged"
            : mode === "inverse"
              ? "Find the inverse of a number"
              : "Explore what happens with zero"}
        </p>
        <div className="flex flex-wrap items-center gap-3">
          <input
            type="number"
            value={input}
            onChange={(e) => setInput(e.target.value)}
            className="w-24 rounded-lg border-2 border-border bg-surface px-3 py-2 text-center text-lg font-bold outline-none focus:border-unit-8"
            aria-label="Number"
          />
          <button
            onClick={handleGo}
            className="rounded-lg bg-unit-8 px-6 py-2.5 text-sm font-bold text-white transition-colors hover:bg-unit-8-dark"
          >
            Go →
          </button>
        </div>
        {error && <p className="mt-2 text-sm text-incorrect">{error}</p>}
      </Card>

      {/* Display card */}
      <Card className="flex min-h-[220px] flex-col items-center justify-center gap-4 p-6">
        {!step ? (
          <p className="text-muted/50">
            Enter a number above and click <strong>Go</strong>
          </p>
        ) : (
          <>
            <p className="text-center text-sm font-medium text-muted">{step.label}</p>
            <MathDisplay
              math={step.math}
              className={`text-3xl ${step.danger ? "text-incorrect" : ""}`}
            />
          </>
        )}
      </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>
  );
}
