"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";
import { CartesianGrid, type GridPoint } from "./cartesian-grid";

interface Step {
  label: string;
  math: string;
  points: GridPoint[];
  highlight?: { x: number; y: number };
  guide?: "x" | "y" | "both";
}

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

function quadrantName(x: number, y: number): string {
  if (x === 0 && y === 0) return "the origin";
  if (x === 0) return "on the y-axis";
  if (y === 0) return "on the x-axis";
  if (x > 0 && y > 0) return "the top-right quadrant";
  if (x < 0 && y > 0) return "the top-left quadrant";
  if (x < 0 && y < 0) return "the bottom-left quadrant";
  return "the bottom-right quadrant";
}

function buildReadSteps(x: number, y: number): Step[] {
  const point: GridPoint = { x, y, tone: "solid" };
  return [
    {
      label: "Here is a point. Let's read off its coordinates.",
      math: `(?,\\ ?)`,
      points: [point],
    },
    {
      label: `Trace straight ${y >= 0 ? "DOWN" : "UP"} to the x-axis. It lands on ${x}.`,
      math: `x = ${x}`,
      points: [point],
      highlight: { x, y },
      guide: "x",
    },
    {
      label: `Now trace straight across to the y-axis. It lands on ${y}.`,
      math: `y = ${y}`,
      points: [point],
      highlight: { x, y },
      guide: "both",
    },
    {
      label: `The coordinates are (${x}, ${y}) — x first, then y. This point is in ${quadrantName(x, y)}.`,
      math: `(${x},\\ ${y})`,
      points: [{ x, y, label: `(${x}, ${y})`, tone: "solid" }],
      highlight: { x, y },
      guide: "both",
    },
  ];
}

// ── Quick practice: read the coordinates ─────────────────────────────────────

function ReadPractice() {
  const [target, setTarget] = useState(() => ({ x: randInt(-9, 9), y: randInt(-9, 9) }));
  const [xVal, setXVal] = useState("");
  const [yVal, setYVal] = useState("");
  const [feedback, setFeedback] = useState<"correct" | "swapped" | "incorrect" | null>(null);
  const [score, setScore] = useState({ correct: 0, total: 0 });

  function check() {
    const gx = parseInt(xVal, 10);
    const gy = parseInt(yVal, 10);
    if (isNaN(gx) || isNaN(gy)) return;
    if (gx === target.x && gy === target.y) {
      setFeedback("correct");
      setScore((s) => ({ correct: s.correct + 1, total: s.total + 1 }));
    } else if (gx === target.y && gy === target.x && target.x !== target.y) {
      setFeedback("swapped");
      setScore((s) => ({ correct: s.correct, total: s.total + 1 }));
    } else {
      setFeedback("incorrect");
      setScore((s) => ({ correct: s.correct, total: s.total + 1 }));
    }
  }

  function next() {
    setTarget({ x: randInt(-9, 9), y: randInt(-9, 9) });
    setXVal("");
    setYVal("");
    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-7">Quick Practice</p>
        <span className="rounded-full bg-unit-7-light px-3 py-1 text-xs font-bold text-unit-7-dark">
          {score.correct}/{score.total}
        </span>
      </div>
      <p className="text-center text-lg font-bold">What are the coordinates of this point?</p>
      <div className="mx-auto max-w-md">
        <CartesianGrid points={[{ x: target.x, y: target.y, tone: "solid" }]} highlight={feedback ? target : undefined} />
      </div>
      <div className="flex flex-wrap items-center justify-center gap-2">
        <span className="text-lg font-bold text-muted">(</span>
        <input
          type="number"
          value={xVal}
          onChange={(e) => {
            setXVal(e.target.value);
            setFeedback(null);
          }}
          disabled={feedback === "correct"}
          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-7"
          placeholder="x"
          aria-label="x coordinate"
        />
        <span className="text-lg font-bold text-muted">,</span>
        <input
          type="number"
          value={yVal}
          onChange={(e) => {
            setYVal(e.target.value);
            setFeedback(null);
          }}
          disabled={feedback === "correct"}
          onKeyDown={(e) => {
            if (e.key === "Enter") {
              if (feedback === "correct") next();
              else check();
            }
          }}
          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-7"
          placeholder="y"
          aria-label="y coordinate"
        />
        <span className="text-lg font-bold text-muted">)</span>
        {feedback === "correct" ? (
          <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>
        ) : (
          <button onClick={check} className="rounded-lg bg-unit-7 px-5 py-2.5 text-sm font-bold text-white hover:bg-unit-7-dark">
            Check
          </button>
        )}
      </div>
      {feedback === "correct" && <p className="text-center text-sm font-bold text-correct">Correct! ({target.x}, {target.y})</p>}
      {feedback === "swapped" && (
        <p className="text-center text-sm font-bold text-incorrect">You swapped them — the x-coordinate comes first! Try again.</p>
      )}
      {feedback === "incorrect" && (
        <p className="text-center text-sm font-bold text-incorrect">Not quite. Trace down to the x-axis, then across to the y-axis.</p>
      )}
    </Card>
  );
}

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

export function ReadCoordinatesExplorer() {
  const [point, setPoint] = useState(() => ({ x: 3, y: 2 }));
  const [steps, setSteps] = useState<Step[] | null>(() => buildReadSteps(3, 2));
  const [currentStep, setCurrentStep] = useState(0);
  const [isPlaying, setIsPlaying] = useState(false);

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

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

  function newPoint() {
    let x = randInt(-9, 9);
    const y = randInt(-9, 9);
    if (x === point.x && y === point.y) x = -x || 1;
    setPoint({ x, y });
    setSteps(buildReadSteps(x, y));
    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">
      <Card>
        <p className="mb-3 text-xs font-bold uppercase tracking-wider text-unit-7">
          Read the coordinates of the point
        </p>
        <button
          onClick={newPoint}
          className="rounded-lg bg-unit-7 px-6 py-2.5 text-sm font-bold text-white transition-colors hover:bg-unit-7-dark"
        >
          New Point ↻
        </button>
      </Card>

      {/* Display card */}
      <Card className="flex min-h-[320px] flex-col items-center justify-center gap-4 p-6">
        {step && (
          <>
            <p className="text-center text-sm font-medium text-muted">{step.label}</p>
            <MathDisplay math={step.math} className="text-2xl" />
            <div className="w-full max-w-md">
              <CartesianGrid
                points={step.points}
                highlight={
                  step.guide && step.highlight
                    ? { ...step.highlight, axis: step.guide === "x" ? "x" : "both" }
                    : undefined
                }
              />
            </div>
          </>
        )}
      </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]" />}>
        <ReadPractice />
      </ClientOnly>
    </div>
  );
}
