"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 Tab = "multiply" | "divide" | "thermometer";

interface Step {
  label: string;
  math: string;
  signVisual?: { signA: "+" | "-"; signB: "+" | "-"; resultSign: "+" | "-" };
  thermometer?: { startTemp: number; change: number; endTemp: number };
}

function getSign(n: number): "+" | "-" {
  return n >= 0 ? "+" : "-";
}

function buildMultiplySteps(a: number, b: number): Step[] {
  const steps: Step[] = [];
  const result = a * b;
  const signA = getSign(a);
  const signB = getSign(b);
  const signR = getSign(result);

  steps.push({
    label: "Start with the multiplication",
    math: `${a < 0 ? `(${a})` : a} \\times ${b < 0 ? `(${b})` : b}`,
  });

  // Step: Multiply the absolute values
  steps.push({
    label: `First, multiply the absolute values: ${Math.abs(a)} × ${Math.abs(b)}`,
    math: `|${a}| \\times |${b}| = ${Math.abs(a)} \\times ${Math.abs(b)} = ${Math.abs(result)}`,
  });

  // Step: Determine the sign
  const sameSign = (a >= 0 && b >= 0) || (a < 0 && b < 0);
  if (sameSign) {
    steps.push({
      label: `Same signs (${signA} × ${signB}): the result is POSITIVE`,
      math: `(${signA}) \\times (${signB}) = (+)`,
      signVisual: { signA, signB, resultSign: "+" },
    });
  } else {
    steps.push({
      label: `Different signs (${signA} × ${signB}): the result is NEGATIVE`,
      math: `(${signA}) \\times (${signB}) = (-)`,
      signVisual: { signA, signB, resultSign: "-" },
    });
  }

  // Step: Combine
  steps.push({
    label: "Combine the magnitude and sign",
    math: `${a < 0 ? `(${a})` : a} \\times ${b < 0 ? `(${b})` : b} = ${result}`,
    signVisual: { signA, signB, resultSign: signR },
  });

  // Story time for negative × negative
  if (a < 0 && b < 0) {
    steps.push({
      label: "Why does negative × negative = positive? Think of it like a double-negative in English!",
      math: `\\text{\"Do NOT not eat!\"} = \\text{\"Eat!\"}  \\quad (-) \\times (-) = (+)`,
      signVisual: { signA: "-", signB: "-", resultSign: "+" },
    });
  }

  return steps;
}

function buildDivideSteps(a: number, b: number): Step[] {
  const steps: Step[] = [];
  const result = a / b;
  const signA = getSign(a);
  const signB = getSign(b);
  const signR = getSign(result);
  const isWhole = Number.isInteger(result);
  const displayResult = isWhole ? result.toString() : result.toFixed(2);

  steps.push({
    label: "Start with the division",
    math: `${a < 0 ? `(${a})` : a} \\div ${b < 0 ? `(${b})` : b}`,
  });

  steps.push({
    label: `First, divide the absolute values: ${Math.abs(a)} ÷ ${Math.abs(b)}`,
    math: `|${a}| \\div |${b}| = ${Math.abs(a)} \\div ${Math.abs(b)} = ${isWhole ? Math.abs(result) : Math.abs(result).toFixed(2)}`,
  });

  const sameSign = (a >= 0 && b >= 0) || (a < 0 && b < 0);
  if (sameSign) {
    steps.push({
      label: `Same signs (${signA} ÷ ${signB}): the result is POSITIVE`,
      math: `(${signA}) \\div (${signB}) = (+)`,
      signVisual: { signA, signB, resultSign: "+" },
    });
  } else {
    steps.push({
      label: `Different signs (${signA} ÷ ${signB}): the result is NEGATIVE`,
      math: `(${signA}) \\div (${signB}) = (-)`,
      signVisual: { signA, signB, resultSign: "-" },
    });
  }

  steps.push({
    label: "Combine the magnitude and sign",
    math: `${a < 0 ? `(${a})` : a} \\div ${b < 0 ? `(${b})` : b} = ${displayResult}`,
    signVisual: { signA, signB, resultSign: signR },
  });

  return steps;
}

function buildThermometerSteps(startTemp: number, change: number): Step[] {
  const steps: Step[] = [];
  const endTemp = startTemp + change;
  const direction = change >= 0 ? "rose" : "dropped";
  const absChange = Math.abs(change);

  steps.push({
    label: "Read the starting temperature on the thermometer",
    math: `\\text{Starting temperature: } ${startTemp}°C`,
    thermometer: { startTemp, change: 0, endTemp: startTemp },
  });

  steps.push({
    label: `The temperature ${direction} by ${absChange}°C`,
    math: change >= 0
      ? `${startTemp}°C + ${absChange}°C`
      : `${startTemp}°C - ${absChange}°C`,
    thermometer: { startTemp, change: 0, endTemp: startTemp },
  });

  steps.push({
    label: change >= 0 ? "Rising temperature means we ADD" : "Dropping temperature means we SUBTRACT",
    math: `${startTemp} + (${change}) = ${endTemp}`,
    thermometer: { startTemp, change, endTemp },
  });

  steps.push({
    label: `The new temperature is ${endTemp}°C`,
    math: `\\text{New temperature: } ${endTemp}°C`,
    thermometer: { startTemp, change, endTemp },
  });

  return steps;
}

function SignRuleGrid({ visual, operation }: { visual?: Step["signVisual"]; operation: "×" | "÷" }) {
  const rules = [
    { a: "+", b: "+", result: "+", example: operation === "×" ? "3 × 2 = 6" : "6 ÷ 2 = 3" },
    { a: "-", b: "-", result: "+", example: operation === "×" ? "(-3) × (-2) = 6" : "(-6) ÷ (-2) = 3" },
    { a: "+", b: "-", result: "-", example: operation === "×" ? "3 × (-2) = -6" : "6 ÷ (-2) = -3" },
    { a: "-", b: "+", result: "-", example: operation === "×" ? "(-3) × 2 = -6" : "(-6) ÷ 2 = -3" },
  ];

  return (
    <div className="grid grid-cols-2 gap-2 sm:grid-cols-4">
      {rules.map((r) => {
        const isActive = visual && visual.signA === r.a && visual.signB === r.b;
        return (
          <div
            key={`${r.a}${r.b}`}
            className={`rounded-xl border-2 p-3 text-center transition-all duration-300 ${
              isActive
                ? "border-unit-5 bg-unit-5-light shadow-md scale-105"
                : "border-border/40 bg-surface"
            }`}
          >
            <p className={`text-lg font-extrabold ${isActive ? "text-unit-5-dark" : "text-foreground"}`}>
              ({r.a}) {operation} ({r.b}) = ({r.result})
            </p>
            <p className={`mt-1 text-xs ${isActive ? "text-unit-5-dark/70" : "text-muted"}`}>
              {r.example}
            </p>
          </div>
        );
      })}
    </div>
  );
}

function Thermometer({ data }: { data?: Step["thermometer"] }) {
  const minTemp = -20;
  const maxTemp = 30;
  const range = maxTemp - minTemp;

  const startTemp = data?.startTemp ?? 0;
  const endTemp = data?.endTemp ?? 0;

  const fillY = ((endTemp - minTemp) / range) * 100;

  const ticks = [];
  for (let t = minTemp; t <= maxTemp; t += 5) {
    ticks.push(t);
  }

  return (
    <div className="mx-auto flex items-end gap-6">
      {/* Thermometer */}
      <div className="relative flex flex-col items-center">
        <div className="relative h-64 w-8 overflow-hidden rounded-t-full border-2 border-foreground/30 bg-gradient-to-b from-red-50 to-blue-50">
          {/* Mercury fill */}
          <div
            className="absolute bottom-0 left-0 right-0 rounded-t-sm transition-all duration-700"
            style={{
              height: `${Math.max(0, Math.min(100, fillY))}%`,
              background: endTemp >= 0
                ? `linear-gradient(to top, #dc2626, #f97316)`
                : `linear-gradient(to top, #2563eb, #60a5fa)`,
            }}
          />
          {/* Tick marks */}
          {ticks.map((t) => {
            const y = ((t - minTemp) / range) * 100;
            return (
              <div
                key={t}
                className="absolute left-0 right-0 flex items-center"
                style={{ bottom: `${y}%`, transform: "translateY(50%)" }}
              >
                <div className={`h-px flex-1 ${t === 0 ? "bg-foreground" : "bg-foreground/20"}`} />
              </div>
            );
          })}
        </div>
        {/* Bulb */}
        <div className="relative -mt-1 flex h-12 w-12 items-center justify-center rounded-full border-2 border-foreground/30 bg-red-500">
          <span className="text-[8px] font-bold text-white">°C</span>
        </div>
      </div>

      {/* Scale labels */}
      <div className="relative h-64">
        {ticks.map((t) => {
          const y = ((t - minTemp) / range) * 100;
          const isStart = t === startTemp;
          const isEnd = data && data.change !== 0 && t === endTemp;
          return (
            <div
              key={t}
              className="absolute flex items-center gap-1"
              style={{ bottom: `${y}%`, transform: "translateY(50%)" }}
            >
              <span
                className={`text-xs transition-all duration-300 ${
                  isEnd
                    ? "font-extrabold text-correct text-sm"
                    : isStart
                      ? "font-bold text-unit-5"
                      : t === 0
                        ? "font-semibold text-foreground"
                        : "text-muted/60"
                }`}
              >
                {t}°C
              </span>
              {isStart && (
                <span className="rounded bg-unit-5 px-1.5 py-0.5 text-[9px] font-bold text-white">
                  START
                </span>
              )}
              {isEnd && (
                <span className="rounded bg-correct px-1.5 py-0.5 text-[9px] font-bold text-white">
                  END
                </span>
              )}
            </div>
          );
        })}
      </div>
    </div>
  );
}

function ThermometerPractice() {
  const scenarios = [
    { city: "London", startTemp: -3, change: 7, question: "The temperature rose by 7°C. What is the new temperature?" },
    { city: "Moscow", startTemp: -12, change: -5, question: "The temperature dropped by 5°C. What is the new temperature?" },
    { city: "Kingston", startTemp: 28, change: -10, question: "The temperature dropped by 10°C. What is the new temperature?" },
    { city: "Ottawa", startTemp: -8, change: 15, question: "The temperature rose by 15°C. What is the new temperature?" },
    { city: "Reykjavik", startTemp: -1, change: -6, question: "The temperature dropped by 6°C. What is the new temperature?" },
  ];

  const [scenarioIdx, setScenarioIdx] = useState(0);
  const [userAnswer, setUserAnswer] = useState("");
  const [feedback, setFeedback] = useState<"correct" | "incorrect" | null>(null);

  const scenario = scenarios[scenarioIdx];
  const correctAnswer = scenario.startTemp + scenario.change;

  function check() {
    const parsed = parseInt(userAnswer);
    if (isNaN(parsed)) return;
    setFeedback(parsed === correctAnswer ? "correct" : "incorrect");
  }

  function next() {
    setScenarioIdx((i) => (i + 1) % scenarios.length);
    setUserAnswer("");
    setFeedback(null);
  }

  return (
    <Card className="space-y-4">
      <p className="text-xs font-bold uppercase tracking-wider text-unit-5">
        Real-World Challenge
      </p>
      <div className="rounded-xl border-2 border-unit-5/20 bg-unit-5-light/50 p-4">
        <p className="text-sm font-bold text-unit-5-dark">
          In {scenario.city}, the temperature is {scenario.startTemp}°C.
        </p>
        <p className="mt-1 text-sm text-unit-5-dark/80">{scenario.question}</p>
      </div>
      <div className="flex flex-wrap items-center gap-3">
        <input
          type="number"
          value={userAnswer}
          onChange={(e) => {
            setUserAnswer(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-lg 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="°C"
          aria-label="Temperature answer"
        />
        <span className="text-sm font-semibold text-muted">°C</span>
        {feedback === null ? (
          <button
            onClick={check}
            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={next}
            className="rounded-lg bg-foreground px-5 py-2.5 text-sm font-bold text-background transition-colors hover:bg-foreground/80"
          >
            Next City →
          </button>
        )}
      </div>
      {feedback === "correct" && (
        <p className="text-sm font-bold text-correct">
          Correct! {scenario.startTemp} + ({scenario.change}) = {correctAnswer}°C
        </p>
      )}
      {feedback === "incorrect" && (
        <p className="text-sm font-bold text-incorrect">
          Not quite. {scenario.startTemp} + ({scenario.change}) = {correctAnswer}°C
        </p>
      )}
    </Card>
  );
}

function generateProblem() {
  const ops = ["×", "÷"] as const;
  const op = ops[Math.floor(Math.random() * ops.length)];

  if (op === "×") {
    const a = Math.floor(Math.random() * 25) - 12;
    const b = Math.floor(Math.random() * 25) - 12;
    return { a, b, op, answer: a * b };
  } else {
    // Generate division with clean integer results
    const b = Math.floor(Math.random() * 11) - 5;
    const nonZeroB = b === 0 ? 3 : b;
    const answer = Math.floor(Math.random() * 21) - 10;
    const a = answer * nonZeroB;
    return { a, b: nonZeroB, op, answer };
  }
}

function MultiplyDividePractice() {
  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 check() {
    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 next() {
    setProblem(generateProblem());
    setUserAnswer("");
    setFeedback(null);
  }

  const displayA = problem.a < 0 ? `(${problem.a})` : `${problem.a}`;
  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">
          {displayA} {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) next();
              else check();
            }
          }}
          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={check} 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={next} 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!</p>
      )}
      {feedback === "incorrect" && (
        <p className="text-center text-sm font-bold text-incorrect">
          Not quite. The answer is {problem.answer}.
        </p>
      )}
    </Card>
  );
}

export function IntegerMultiplyDivideExplorer() {
  const [tab, setTab] = useState<Tab>("multiply");
  const [inputA, setInputA] = useState("-3");
  const [inputB, setInputB] = useState("5");
  const [startTemp, setStartTemp] = useState("-3");
  const [tempChange, setTempChange] = useState("7");
  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("");

    if (tab === "thermometer") {
      const st = parseInt(startTemp);
      const ch = parseInt(tempChange);
      if (isNaN(st) || isNaN(ch)) {
        setError("Enter valid integers.");
        return;
      }
      if (Math.abs(st) > 20 || Math.abs(ch) > 30) {
        setError("Keep temperatures reasonable (-20 to 30).");
        return;
      }
      const s = buildThermometerSteps(st, ch);
      setSteps(s);
      setCurrentStep(0);
      setIsPlaying(false);
      return;
    }

    const a = parseInt(inputA);
    const b = parseInt(inputB);
    if (isNaN(a) || isNaN(b)) {
      setError("Enter valid integers.");
      return;
    }
    if (tab === "divide" && b === 0) {
      setError("Cannot divide by zero!");
      return;
    }
    if (Math.abs(a) > 99 || Math.abs(b) > 99) {
      setError("Keep numbers under 100.");
      return;
    }
    if (tab === "divide" && !Number.isInteger(a / b)) {
      setError("Choose numbers that divide evenly for now.");
      return;
    }

    try {
      const s = tab === "multiply" ? buildMultiplySteps(a, b) : buildDivideSteps(a, b);
      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;

  return (
    <div className="space-y-4">
      {/* Tab selector */}
      <div className="flex flex-wrap gap-2">
        {(["multiply", "divide", "thermometer"] as Tab[]).map((t) => (
          <button
            key={t}
            onClick={() => {
              setTab(t);
              reset();
            }}
            className={`rounded-full border-2 px-4 py-2 text-sm font-semibold transition-colors ${
              tab === t
                ? "border-unit-5 bg-unit-5 text-white"
                : "border-unit-5/40 text-unit-5 hover:bg-unit-5-light"
            }`}
          >
            {t === "multiply"
              ? "Multiply (×)"
              : t === "divide"
                ? "Divide (÷)"
                : "Thermometer"}
          </button>
        ))}
      </div>

      {/* Input Card */}
      <Card>
        <p className="mb-3 text-xs font-bold uppercase tracking-wider text-unit-5">
          {tab === "thermometer" ? "Enter temperature scenario" : "Enter two integers"}
        </p>

        {tab === "thermometer" ? (
          <div className="flex flex-wrap items-center gap-3">
            <div className="flex flex-col">
              <label className="mb-1 text-xs font-semibold text-muted">Start temp (°C)</label>
              <input
                type="number"
                value={startTemp}
                onChange={(e) => setStartTemp(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-5"
                aria-label="Starting temperature"
              />
            </div>
            <div className="flex flex-col">
              <label className="mb-1 text-xs font-semibold text-muted">Change (°C)</label>
              <input
                type="number"
                value={tempChange}
                onChange={(e) => setTempChange(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-5"
                aria-label="Temperature change"
              />
            </div>
            <button
              onClick={handleGo}
              className="mt-5 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>
        ) : (
          <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">
              {tab === "multiply" ? "×" : "÷"}
            </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 Grid (for multiply/divide) */}
      {tab !== "thermometer" && (
        <SignRuleGrid
          visual={step?.signVisual}
          operation={tab === "multiply" ? "×" : "÷"}
        />
      )}

      {/* Display Card */}
      <Card className="flex min-h-[300px] flex-col items-center justify-center gap-4 p-6">
        {!step ? (
          <p className="text-muted/50">
            Enter values 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" />
            {step.thermometer && <Thermometer data={step.thermometer} />}
          </>
        )}
      </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>

      {/* Practice sections */}
      <ClientOnly fallback={<Card className="min-h-[220px]" />}>
        {tab === "thermometer" ? <ThermometerPractice /> : <MultiplyDividePractice />}
      </ClientOnly>
    </div>
  );
}
