"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 = "number-line" | "rules";

interface Step {
  label: string;
  math: string;
  numberLineHighlight?: {
    start: number;
    end: number;
    direction: "left" | "right";
    moves: number;
  };
}

function buildAddSubtractSteps(a: number, b: number, op: "add" | "subtract"): Step[] {
  const steps: Step[] = [];
  const opSymbol = op === "add" ? "+" : "-";
  const expression = `${a} ${opSymbol} ${b < 0 ? `(${b})` : b}`;

  // Step 0: Show the original expression
  steps.push({
    label: "Start with the expression",
    math: expression,
    numberLineHighlight: { start: a, end: a, direction: "right", moves: 0 },
  });

  if (op === "add") {
    // Adding
    steps.push({
      label: `Place your finger on ${a} on the number line`,
      math: `\\text{Start at } ${a}`,
      numberLineHighlight: { start: a, end: a, direction: "right", moves: 0 },
    });

    if (b >= 0) {
      steps.push({
        label: `Adding a positive number: move ${b} steps to the RIGHT`,
        math: `${a} + ${b} \\longrightarrow \\text{move right } ${b}`,
        numberLineHighlight: { start: a, end: a + b, direction: "right", moves: b },
      });
    } else {
      steps.push({
        label: `Adding a negative number: move ${Math.abs(b)} steps to the LEFT`,
        math: `${a} + (${b}) \\longrightarrow \\text{move left } ${Math.abs(b)}`,
        numberLineHighlight: { start: a, end: a + b, direction: "left", moves: Math.abs(b) },
      });
    }

    const result = a + b;
    steps.push({
      label: `You land on ${result}`,
      math: `${expression} = ${result}`,
      numberLineHighlight: { start: a, end: result, direction: b >= 0 ? "right" : "left", moves: Math.abs(b) },
    });

    // Sign rule explanation
    if (a >= 0 && b >= 0) {
      steps.push({
        label: "Rule: Positive + Positive = Positive",
        math: `(+) + (+) = (+) \\quad \\Rightarrow \\quad ${expression} = ${result}`,
        numberLineHighlight: { start: a, end: result, direction: "right", moves: Math.abs(b) },
      });
    } else if (a < 0 && b < 0) {
      steps.push({
        label: "Rule: Negative + Negative = Negative (add magnitudes, keep negative sign)",
        math: `(-) + (-) = (-) \\quad \\Rightarrow \\quad ${expression} = ${result}`,
        numberLineHighlight: { start: a, end: result, direction: "left", moves: Math.abs(b) },
      });
    } else {
      steps.push({
        label: "Rule: Different signs? Subtract the smaller from the larger, keep the sign of the larger",
        math: `|${Math.abs(a)}| - |${Math.abs(b)}| = ${Math.abs(Math.abs(a) - Math.abs(b))} \\quad \\Rightarrow \\quad ${expression} = ${result}`,
        numberLineHighlight: { start: a, end: result, direction: result >= a ? "right" : "left", moves: Math.abs(b) },
      });
    }
  } else {
    // Subtracting
    steps.push({
      label: `Place your finger on ${a} on the number line`,
      math: `\\text{Start at } ${a}`,
      numberLineHighlight: { start: a, end: a, direction: "right", moves: 0 },
    });

    if (b >= 0) {
      steps.push({
        label: `Subtracting a positive number: move ${b} steps to the LEFT`,
        math: `${a} - ${b} \\longrightarrow \\text{move left } ${b}`,
        numberLineHighlight: { start: a, end: a - b, direction: "left", moves: b },
      });
    } else {
      steps.push({
        label: `Subtracting a negative number is the same as ADDING a positive! Move ${Math.abs(b)} steps RIGHT`,
        math: `${a} - (${b}) = ${a} + ${Math.abs(b)} \\longrightarrow \\text{move right } ${Math.abs(b)}`,
        numberLineHighlight: { start: a, end: a - b, direction: "right", moves: Math.abs(b) },
      });
    }

    const result = a - b;
    steps.push({
      label: `You land on ${result}`,
      math: `${expression} = ${result}`,
      numberLineHighlight: { start: a, end: result, direction: result >= a ? "right" : "left", moves: Math.abs(b) },
    });

    // Two like/unlike signs rule
    if (b >= 0) {
      steps.push({
        label: "Two unlike signs (+ -) becomes negative: subtract means move left",
        math: `+(-)\\text{ becomes } - \\quad \\Rightarrow \\quad ${expression} = ${result}`,
        numberLineHighlight: { start: a, end: result, direction: "left", moves: Math.abs(b) },
      });
    } else {
      steps.push({
        label: "Two like signs (- -) becomes positive: subtracting a negative means move right!",
        math: `-(-) \\text{ becomes } + \\quad \\Rightarrow \\quad ${expression} = ${result}`,
        numberLineHighlight: { start: a, end: result, direction: "right", moves: Math.abs(b) },
      });
    }
  }

  return steps;
}

function NumberLine({
  highlight,
  animate,
}: {
  highlight?: Step["numberLineHighlight"];
  animate: boolean;
}) {
  const minVal = -15;
  const maxVal = 15;
  const range = maxVal - minVal;

  const start = highlight?.start ?? 0;
  const end = highlight?.end ?? 0;

  const startX = ((start - minVal) / range) * 100;
  const endX = ((end - minVal) / range) * 100;

  const leftX = Math.min(startX, endX);
  const width = Math.abs(endX - startX);

  return (
    <div className="mx-auto w-full max-w-2xl select-none">
      <div className="relative h-24 px-4">
        {/* Arrow path highlight */}
        {highlight && highlight.moves > 0 && (
          <div
            className="absolute top-5 h-3 rounded-full transition-all duration-700"
            style={{
              left: `calc(${leftX}% + 16px)`,
              width: `${width}%`,
              backgroundColor: highlight.direction === "right"
                ? "rgba(124, 58, 237, 0.25)"
                : "rgba(220, 38, 38, 0.25)",
            }}
          />
        )}

        {/* Direction arrow */}
        {highlight && highlight.moves > 0 && (
          <div
            className="absolute top-1 text-xs font-bold transition-all duration-500"
            style={{
              left: `calc(${(startX + endX) / 2}% + 16px)`,
              transform: "translateX(-50%)",
              color: highlight.direction === "right" ? "var(--unit-5)" : "var(--incorrect)",
            }}
          >
            {highlight.direction === "right" ? "→ right →" : "← left ←"}
            <div className="text-center text-[10px] font-semibold opacity-70">
              {highlight.moves} step{highlight.moves !== 1 ? "s" : ""}
            </div>
          </div>
        )}

        {/* Number line */}
        <div className="absolute bottom-8 left-4 right-4">
          <div className="h-0.5 bg-foreground/40" />
          {/* Tick marks */}
          {Array.from({ length: range + 1 }, (_, i) => {
            const val = minVal + i;
            const x = (i / range) * 100;
            const isZero = val === 0;
            const isHighlighted = highlight && (val === start || val === end);
            const isInRange = highlight && highlight.moves > 0 &&
              val >= Math.min(start, end) && val <= Math.max(start, end);

            return (
              <div
                key={val}
                className="absolute -translate-x-1/2"
                style={{ left: `${x}%` }}
              >
                <div
                  className={`h-3 w-0.5 -translate-y-1.5 transition-colors duration-300 ${
                    isHighlighted
                      ? "bg-unit-5 h-4"
                      : isZero
                        ? "bg-foreground"
                        : isInRange
                          ? "bg-unit-5/50"
                          : "bg-foreground/30"
                  }`}
                />
                {(val % 5 === 0 || isHighlighted) && (
                  <span
                    className={`mt-1 block text-center text-[10px] transition-all duration-300 ${
                      isHighlighted
                        ? "text-xs font-extrabold text-unit-5"
                        : isZero
                          ? "font-bold text-foreground"
                          : "text-muted/70"
                    }`}
                  >
                    {val}
                  </span>
                )}
              </div>
            );
          })}
        </div>

        {/* Start marker */}
        {highlight && (
          <div
            className="absolute bottom-16 -translate-x-1/2 transition-all duration-500"
            style={{ left: `calc(${startX}% + 16px)` }}
          >
            <div className="flex flex-col items-center">
              <span className="rounded-full bg-unit-5 px-2 py-0.5 text-[10px] font-bold text-white shadow-md">
                Start
              </span>
              <div className="h-3 w-0.5 bg-unit-5" />
            </div>
          </div>
        )}

        {/* End marker */}
        {highlight && highlight.moves > 0 && animate && (
          <div
            className="absolute bottom-16 -translate-x-1/2 transition-all duration-700"
            style={{ left: `calc(${endX}% + 16px)` }}
          >
            <div className="flex flex-col items-center">
              <span className="rounded-full bg-correct px-2 py-0.5 text-[10px] font-bold text-white shadow-md">
                End: {end}
              </span>
              <div className="h-3 w-0.5 bg-correct" />
            </div>
          </div>
        )}
      </div>

      {/* Arrows on edges */}
      <div className="flex justify-between px-2 text-xs text-muted/50">
        <span>← negative</span>
        <span>positive →</span>
      </div>
    </div>
  );
}

function SignRuleCard({ rule, active }: { rule: string; active: boolean }) {
  return (
    <div
      className={`rounded-xl border-2 px-3 py-2 text-center text-sm font-semibold transition-all duration-300 ${
        active
          ? "border-unit-5 bg-unit-5-light text-unit-5-dark scale-105 shadow-md"
          : "border-border/40 bg-surface text-muted"
      }`}
    >
      {rule}
    </div>
  );
}

function generateProblem() {
  const ops = ["+", "-"] as const;
  const op = ops[Math.floor(Math.random() * ops.length)];
  const a = Math.floor(Math.random() * 21) - 10;
  const b = Math.floor(Math.random() * 21) - 10;
  const answer = op === "+" ? a + b : a - b;
  return { a, b, op, answer };
}

function QuickPractice() {
  const [problem, setProblem] = useState(() => generateProblem());
  const [userAnswer, setUserAnswer] = useState("");
  const [feedback, setFeedback] = useState<"correct" | "incorrect" | null>(null);
  const [score, setScore] = useState({ correct: 0, total: 0 });

  function checkAnswer() {
    const parsed = parseInt(userAnswer);
    if (isNaN(parsed)) return;
    const isCorrect = parsed === problem.answer;
    setFeedback(isCorrect ? "correct" : "incorrect");
    setScore((prev) => ({
      correct: prev.correct + (isCorrect ? 1 : 0),
      total: prev.total + 1,
    }));
  }

  function nextProblem() {
    setProblem(generateProblem());
    setUserAnswer("");
    setFeedback(null);
  }

  const displayB = problem.b < 0 ? `(${problem.b})` : `${problem.b}`;

  return (
    <Card className="space-y-4">
      <div className="flex items-center justify-between">
        <p className="text-xs font-bold uppercase tracking-wider text-unit-5">Quick Practice</p>
        <span className="rounded-full bg-unit-5-light px-3 py-1 text-xs font-bold text-unit-5-dark">
          {score.correct}/{score.total}
        </span>
      </div>

      <div className="flex flex-wrap items-center justify-center gap-3">
        <span className="text-2xl font-extrabold">
          {problem.a} {problem.op} {displayB} =
        </span>
        <input
          type="number"
          value={userAnswer}
          onChange={(e) => {
            setUserAnswer(e.target.value);
            setFeedback(null);
          }}
          onKeyDown={(e) => {
            if (e.key === "Enter") {
              if (feedback !== null) nextProblem();
              else checkAnswer();
            }
          }}
          className={`w-20 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-5"
          }`}
          placeholder="?"
          aria-label="Your answer"
        />
        {feedback === null ? (
          <button
            onClick={checkAnswer}
            className="rounded-lg bg-unit-5 px-5 py-2.5 text-sm font-bold text-white transition-colors hover:bg-unit-5-dark"
          >
            Check
          </button>
        ) : (
          <button
            onClick={nextProblem}
            className="rounded-lg bg-foreground px-5 py-2.5 text-sm font-bold text-background transition-colors hover:bg-foreground/80"
          >
            Next →
          </button>
        )}
      </div>

      {feedback === "correct" && (
        <p className="text-center text-sm font-bold text-correct">Correct! Well done!</p>
      )}
      {feedback === "incorrect" && (
        <p className="text-center text-sm font-bold text-incorrect">
          Not quite. The answer is {problem.answer}. Try the next one!
        </p>
      )}
    </Card>
  );
}

export function IntegerAddSubtractExplorer() {
  const [mode, setMode] = useState<Mode>("number-line");
  const [op, setOp] = useState<"add" | "subtract">("add");
  const [inputA, setInputA] = useState("-3");
  const [inputB, setInputB] = useState("5");
  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;

  function handleGo() {
    setError("");
    const a = parseInt(inputA);
    const b = parseInt(inputB);
    if (isNaN(a) || isNaN(b)) {
      setError("Enter valid integers.");
      return;
    }
    if (Math.abs(a) > 15 || Math.abs(b) > 15) {
      setError("Keep numbers between -15 and 15 for the number line.");
      return;
    }
    const result = op === "add" ? a + b : a - b;
    if (Math.abs(result) > 15) {
      setError("Result goes off the number line. Try smaller numbers.");
      return;
    }
    try {
      const s = buildAddSubtractSteps(a, b, op);
      setSteps(s);
      setCurrentStep(0);
      setIsPlaying(false);
    } catch {
      setError("Could not compute. Check your inputs.");
    }
  }

  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 reset = useCallback(() => {
    setSteps(null);
    setCurrentStep(0);
    setIsPlaying(false);
  }, []);

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

  const addRules = [
    { rule: "(+) + (+) = (+)", active: step?.label.includes("Positive + Positive") ?? false },
    { rule: "(-) + (-) = (-)", active: step?.label.includes("Negative + Negative") ?? false },
    { rule: "Different signs? Subtract, keep sign of larger", active: step?.label.includes("Different signs") ?? false },
  ];

  const subRules = [
    { rule: "+(−) becomes −", active: step?.label.includes("unlike signs") ?? false },
    { rule: "−(−) becomes +", active: step?.label.includes("like signs") ?? false },
  ];

  return (
    <div className="space-y-4">
      {/* Mode toggle */}
      <div className="flex flex-wrap gap-2">
        {(["number-line", "rules"] as Mode[]).map((m) => (
          <button
            key={m}
            onClick={() => {
              setMode(m);
              reset();
            }}
            className={`rounded-full border-2 px-4 py-2 text-sm font-semibold transition-colors ${
              mode === m
                ? "border-unit-5 bg-unit-5 text-white"
                : "border-unit-5/40 text-unit-5 hover:bg-unit-5-light"
            }`}
          >
            {m === "number-line" ? "Number Line" : "Sign Rules"}
          </button>
        ))}
      </div>

      {/* Operation tabs */}
      <div className="flex flex-wrap gap-2">
        {(["add", "subtract"] as const).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-5-dark bg-unit-5-dark text-white"
                : "border-unit-5/30 text-unit-5-dark hover:bg-unit-5-light"
            }`}
          >
            {o === "add" ? "Add (+)" : "Subtract (−)"}
          </button>
        ))}
      </div>

      {/* Input Card */}
      <Card>
        <p className="mb-3 text-xs font-bold uppercase tracking-wider text-unit-5">
          Enter two integers
        </p>
        <div className="flex flex-wrap items-center gap-3">
          <input
            type="number"
            value={inputA}
            onChange={(e) => setInputA(e.target.value)}
            className="w-20 rounded-lg border-2 border-border bg-surface px-3 py-2 text-center text-lg font-bold outline-none focus:border-unit-5"
            aria-label="First integer"
          />
          <span className="text-xl font-bold text-muted">
            {op === "add" ? "+" : "−"}
          </span>
          <input
            type="number"
            value={inputB}
            onChange={(e) => setInputB(e.target.value)}
            className="w-20 rounded-lg border-2 border-border bg-surface px-3 py-2 text-center text-lg font-bold outline-none focus:border-unit-5"
            aria-label="Second integer"
          />
          <button
            onClick={handleGo}
            className="rounded-lg bg-unit-5 px-6 py-2.5 text-sm font-bold text-white transition-colors hover:bg-unit-5-dark"
          >
            Go →
          </button>
        </div>
        {error && <p className="mt-2 text-sm text-incorrect">{error}</p>}
      </Card>

      {/* Sign Rules Reference */}
      {mode === "rules" && (
        <div className="grid grid-cols-2 gap-2 sm:grid-cols-3">
          {(op === "add" ? addRules : subRules).map((r) => (
            <SignRuleCard key={r.rule} rule={r.rule} active={r.active} />
          ))}
        </div>
      )}

      {/* Display Card with Number Line */}
      <Card className="flex min-h-[280px] flex-col items-center justify-center gap-4 p-6">
        {!step ? (
          <p className="text-muted/50">
            Enter integers above and click <strong>Go</strong>
          </p>
        ) : (
          <>
            <p className="text-sm font-medium text-muted">{step.label}</p>
            <MathDisplay math={step.math} className="text-2xl" />
            {mode === "number-line" && (
              <NumberLine
                highlight={step.numberLineHighlight}
                animate={currentStep > 0}
              />
            )}
          </>
        )}
      </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>

      {/* Result */}
      <Card className="flex min-h-[80px] flex-col items-center justify-center gap-1.5 text-center">
        {!done || !steps ? (
          <p className="text-sm text-muted/40">Result will appear here when steps are complete</p>
        ) : (
          <>
            <p className="text-xs uppercase tracking-wider text-muted">Answer</p>
            <div className="text-3xl font-extrabold max-sm:text-2xl">
              <MathDisplay math={steps[steps.length - 1].math} />
            </div>
          </>
        )}
      </Card>

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