"use client";

import { useState, useCallback } from "react";
import { Card } from "@/components/ui/card";
import { StepControls } from "./step-controls";
import { MathDisplay } from "@/components/math/math-display";
import { simplifyRatio } from "@/lib/math/ratios";
import { gcd } from "@/lib/math/fractions";

type RatioMode = "divide" | "simplify" | "equivalent";

interface Step {
  label: string;
  math: string;
  barSegments: { value: number; filled: boolean; label?: string }[];
}

const COLORS = ["var(--unit-4)", "var(--unit-1)", "var(--unit-3)", "var(--hint)"];

function buildDivideSteps(total: number, parts: number[]): Step[] {
  const steps: Step[] = [];
  const sum = parts.reduce((a, b) => a + b, 0);

  // Step 0: Show the ratio and total
  steps.push({
    label: `Divide ${total} in the ratio ${parts.join(" : ")}`,
    math: `${total} \\div (${parts.join(" : ")})`,
    barSegments: parts.map((p) => ({ value: p, filled: false })),
  });

  // Step 1: Sum the parts
  steps.push({
    label: `Add the ratio parts: ${parts.join(" + ")} = ${sum}`,
    math: `${parts.join(" + ")} = ${sum} \\text{ total parts}`,
    barSegments: parts.map((p) => ({ value: p, filled: false })),
  });

  // Step 2: Find one part
  const onePart = total / sum;
  steps.push({
    label: `Find one part: ${total} ÷ ${sum} = ${onePart}`,
    math: `\\text{One part} = ${total} \\div ${sum} = ${Number.isInteger(onePart) ? onePart : onePart.toFixed(2)}`,
    barSegments: parts.map((p) => ({ value: p, filled: false })),
  });

  // Steps 3+: Calculate each share
  const shares: number[] = [];
  parts.forEach((p, i) => {
    const share = p * onePart;
    shares.push(share);
    steps.push({
      label: `Part ${i + 1}: ${p} × ${Number.isInteger(onePart) ? onePart : onePart.toFixed(2)} = ${Number.isInteger(share) ? share : share.toFixed(2)}`,
      math: `${p} \\times ${Number.isInteger(onePart) ? onePart : onePart.toFixed(2)} = ${Number.isInteger(share) ? share : share.toFixed(2)}`,
      barSegments: parts.map((pp, j) => ({
        value: pp,
        filled: j <= i,
        label: j <= i ? `${Number.isInteger(shares[j]) ? shares[j] : shares[j].toFixed(2)}` : undefined,
      })),
    });
  });

  // Final step: Show all shares
  const shareStrs = shares.map((s) => (Number.isInteger(s) ? s.toString() : s.toFixed(2)));
  steps.push({
    label: `Result: ${shareStrs.join(", ")}`,
    math: `${total} = ${shareStrs.join(" + ")}`,
    barSegments: parts.map((pp, j) => ({
      value: pp,
      filled: true,
      label: shareStrs[j],
    })),
  });

  return steps;
}

function buildSimplifySteps(parts: number[]): Step[] {
  const steps: Step[] = [];

  steps.push({
    label: `Simplify the ratio ${parts.join(" : ")}`,
    math: parts.join(" : "),
    barSegments: parts.map((p) => ({ value: p, filled: true })),
  });

  // Find GCD
  let g = parts[0];
  for (let i = 1; i < parts.length; i++) g = gcd(g, parts[i]);

  if (g === 1) {
    steps.push({
      label: "The ratio is already in its simplest form (GCD = 1)",
      math: `\\text{GCD} = 1`,
      barSegments: parts.map((p) => ({ value: p, filled: true })),
    });
  } else {
    steps.push({
      label: `Find the GCD of all parts: ${g}`,
      math: `\\text{GCD}(${parts.join(", ")}) = ${g}`,
      barSegments: parts.map((p) => ({ value: p, filled: true })),
    });

    const simplified = simplifyRatio(parts);
    steps.push({
      label: `Divide each part by ${g}`,
      math: parts.map((p) => `${p} \\div ${g} = ${p / g}`).join(", \\quad "),
      barSegments: simplified.map((p) => ({ value: p, filled: true })),
    });

    steps.push({
      label: `Simplified ratio: ${simplified.join(" : ")}`,
      math: `${parts.join(" : ")} = ${simplified.join(" : ")}`,
      barSegments: simplified.map((p) => ({ value: p, filled: true })),
    });
  }

  return steps;
}

function buildEquivalentSteps(parts: number[], multiplier: number): Step[] {
  const steps: Step[] = [];

  steps.push({
    label: `Find an equivalent ratio: ${parts.join(" : ")} × ${multiplier}`,
    math: `(${parts.join(" : ")}) \\times ${multiplier}`,
    barSegments: parts.map((p) => ({ value: p, filled: true })),
  });

  const result = parts.map((p) => p * multiplier);
  steps.push({
    label: `Multiply each part by ${multiplier}`,
    math: parts.map((p) => `${p} \\times ${multiplier} = ${p * multiplier}`).join(", \\quad "),
    barSegments: result.map((p) => ({ value: p, filled: true })),
  });

  steps.push({
    label: `Equivalent ratio: ${result.join(" : ")}`,
    math: `${parts.join(" : ")} = ${result.join(" : ")}`,
    barSegments: result.map((p) => ({ value: p, filled: true })),
  });

  return steps;
}

function RatioBar({
  segments,
}: {
  segments: { value: number; filled: boolean; label?: string }[];
}) {
  const total = segments.reduce((s, seg) => s + seg.value, 0);
  if (total === 0) return null;

  return (
    <div className="w-full max-w-lg">
      <div className="flex h-14 overflow-hidden rounded-xl border-2 border-border">
        {segments.map((seg, i) => (
          <div
            key={i}
            className="relative flex items-center justify-center border-r border-white/40 text-sm font-bold text-white transition-all duration-500 last:border-r-0"
            style={{
              flex: seg.value,
              backgroundColor: seg.filled ? COLORS[i % COLORS.length] : "transparent",
              color: seg.filled ? "white" : "var(--foreground)",
            }}
          >
            {seg.label || seg.value}
          </div>
        ))}
      </div>
      <div className="mt-1 flex">
        {segments.map((seg, i) => (
          <div
            key={i}
            className="text-center text-xs text-muted"
            style={{ flex: seg.value }}
          >
            {seg.label && `(${seg.value} parts)`}
          </div>
        ))}
      </div>
    </div>
  );
}

export function RatioExplorer({
  initialMode = "divide",
}: {
  initialMode?: RatioMode;
} = {}) {
  const [mode, setMode] = useState<RatioMode>(initialMode);
  const [partA, setPartA] = useState("2");
  const [partB, setPartB] = useState("3");
  const [partC, setPartC] = useState("");
  const [total, setTotal] = useState("60");
  const [multiplier, setMultiplier] = useState("4");
  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 getParts(): number[] {
    const parts = [parseInt(partA), parseInt(partB)];
    if (partC.trim()) parts.push(parseInt(partC));
    return parts;
  }

  function handleGo() {
    setError("");
    const parts = getParts();
    if (parts.some(isNaN) || parts.some((p) => p <= 0)) {
      setError("Enter valid positive ratio parts.");
      return;
    }

    try {
      let s: Step[];
      if (mode === "divide") {
        const t = parseFloat(total);
        if (isNaN(t) || t <= 0) {
          setError("Enter a valid positive total.");
          return;
        }
        s = buildDivideSteps(t, parts);
      } else if (mode === "simplify") {
        s = buildSimplifySteps(parts);
      } else {
        const m = parseInt(multiplier);
        if (isNaN(m) || m <= 0) {
          setError("Enter a valid positive multiplier.");
          return;
        }
        s = buildEquivalentSteps(parts, m);
      }
      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 modeLabels: Record<RatioMode, string> = {
    divide: "Divide in Ratio",
    simplify: "Simplify Ratio",
    equivalent: "Equivalent Ratio",
  };

  return (
    <div className="space-y-4">
      {/* Mode tabs */}
      <div className="flex flex-wrap gap-2">
        {(["divide", "simplify", "equivalent"] as RatioMode[]).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-4 bg-unit-4 text-white"
                : "border-unit-4/40 text-unit-4 hover:bg-unit-4-light"
            }`}
          >
            {modeLabels[m]}
          </button>
        ))}
      </div>

      {/* Input */}
      <Card>
        <p className="mb-3 text-xs font-bold uppercase tracking-wider text-unit-4">
          {mode === "divide" ? "Enter ratio parts and total" : mode === "simplify" ? "Enter ratio parts" : "Enter ratio parts and multiplier"}
        </p>
        <div className="flex flex-wrap items-center gap-2.5">
          <input
            type="number"
            value={partA}
            onChange={(e) => setPartA(e.target.value)}
            className="w-16 rounded-lg border-2 border-border bg-surface px-2 py-2.5 text-center text-lg font-bold outline-none focus:border-unit-4"
            aria-label="Part A"
          />
          <span className="text-xl font-bold text-muted">:</span>
          <input
            type="number"
            value={partB}
            onChange={(e) => setPartB(e.target.value)}
            className="w-16 rounded-lg border-2 border-border bg-surface px-2 py-2.5 text-center text-lg font-bold outline-none focus:border-unit-4"
            aria-label="Part B"
          />
          <span className="text-xl font-bold text-muted">:</span>
          <input
            type="number"
            value={partC}
            onChange={(e) => setPartC(e.target.value)}
            placeholder="?"
            className="w-16 rounded-lg border-2 border-border bg-surface px-2 py-2.5 text-center text-lg font-bold outline-none focus:border-unit-4"
            aria-label="Part C (optional)"
          />

          {mode === "divide" && (
            <>
              <span className="text-sm font-medium text-muted">Total:</span>
              <input
                type="number"
                value={total}
                onChange={(e) => setTotal(e.target.value)}
                className="w-20 rounded-lg border-2 border-border bg-surface px-2 py-2.5 text-center text-lg font-bold outline-none focus:border-unit-4"
                aria-label="Total"
              />
            </>
          )}
          {mode === "equivalent" && (
            <>
              <span className="text-sm font-medium text-muted">× </span>
              <input
                type="number"
                value={multiplier}
                onChange={(e) => setMultiplier(e.target.value)}
                className="w-16 rounded-lg border-2 border-border bg-surface px-2 py-2.5 text-center text-lg font-bold outline-none focus:border-unit-4"
                aria-label="Multiplier"
              />
            </>
          )}

          <button
            onClick={handleGo}
            className="rounded-lg bg-unit-4 px-6 py-2.5 text-sm font-bold text-white transition-colors hover:bg-unit-4-dark"
          >
            Go →
          </button>
        </div>
        {error && <p className="mt-2 text-sm text-incorrect">{error}</p>}
      </Card>

      {/* Display */}
      <Card className="flex min-h-[220px] 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-xl" />
            <RatioBar segments={step.barSegments} />
          </>
        )}
      </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>
            <p className="text-2xl font-extrabold text-foreground max-sm:text-xl">
              {steps[steps.length - 1].label.replace("Result: ", "").replace("Simplified ratio: ", "").replace("Equivalent ratio: ", "")}
            </p>
          </>
        )}
      </Card>
    </div>
  );
}
