"use client";

import { useState, useMemo, useCallback } from "react";
import { Card } from "@/components/ui/card";

const COLUMNS = [32, 16, 8, 4, 2, 1];
const PRESETS = [3, 5, 11, 13, 22, 25, 29, 31, 45, 58];

interface DivisionRow {
  before: number;
  quotient: number;
  remainder: number;
}

interface ConversionResult {
  rows: DivisionRow[];
  bitsLowToHigh: number[];
}

function runDivision(n: number): ConversionResult {
  const rows: DivisionRow[] = [];
  if (n === 0) {
    rows.push({ before: 0, quotient: 0, remainder: 0 });
    return { rows, bitsLowToHigh: [0] };
  }
  let current = n;
  while (current > 0) {
    const q = Math.floor(current / 2);
    const r = current % 2;
    rows.push({ before: current, quotient: q, remainder: r });
    current = q;
  }
  return { rows, bitsLowToHigh: rows.map((r) => r.remainder) };
}

function bitsForChart(bitsLowToHigh: number[]): (number | null)[] {
  const out: (number | null)[] = Array(COLUMNS.length).fill(null);
  for (let i = 0; i < bitsLowToHigh.length && i < COLUMNS.length; i++) {
    out[COLUMNS.length - 1 - i] = bitsLowToHigh[i];
  }
  return out;
}

export function DenaryToBinaryExplorer() {
  const [input, setInput] = useState("");
  const [submitted, setSubmitted] = useState<number | null>(null);
  const [error, setError] = useState("");
  const [answerHidden, setAnswerHidden] = useState(false);
  const [chartHidden, setChartHidden] = useState(false);

  const handleInputChange = (value: string) => {
    setInput(value.replace(/[^0-9]/g, "").slice(0, 3));
    setError("");
  };

  const convert = useCallback((raw?: string) => {
    const source = (raw ?? input).trim();
    if (source === "") {
      setError("Type a denary number first (whole number from 1 to 63).");
      setSubmitted(null);
      return;
    }
    if (!/^\d+$/.test(source)) {
      setError("Use whole digits only (0-9).");
      return;
    }
    const n = parseInt(source, 10);
    if (n < 0 || n > 63) {
      setError("Pick a whole number between 1 and 63. The chart in this lesson is six columns: 32, 16, 8, 4, 2, 1.");
      return;
    }
    setError("");
    setSubmitted(n);
  }, [input]);

  const applyPreset = (value: number) => {
    setInput(String(value));
    convert(String(value));
  };

  const handleClear = () => {
    setInput("");
    setSubmitted(null);
    setError("");
  };

  const handleRandom = () => {
    const n = 1 + Math.floor(Math.random() * 63);
    setInput(String(n));
    convert(String(n));
  };

  const result = useMemo(() => {
    if (submitted === null) return null;
    return runDivision(submitted);
  }, [submitted]);

  const chartBits = useMemo(() => {
    if (!result) return Array(COLUMNS.length).fill(null) as (number | null)[];
    return bitsForChart(result.bitsLowToHigh);
  }, [result]);

  const binaryString = useMemo(() => {
    if (!result) return "";
    const reversed = result.bitsLowToHigh.slice().reverse().join("");
    return reversed.replace(/^0+/, "") || "0";
  }, [result]);

  return (
    <div className="space-y-4">
      {/* Input Card */}
      <Card>
        <p className="mb-3 text-xs font-bold uppercase tracking-wider text-unit-6">
          Type a Denary Number (1 to 63)
        </p>
        <div className="flex flex-wrap items-center gap-3">
          <label htmlFor="denaryInput" className="text-sm font-bold text-unit-6-dark">
            Denary:
          </label>
          <input
            id="denaryInput"
            type="text"
            inputMode="numeric"
            maxLength={3}
            autoComplete="off"
            spellCheck={false}
            placeholder="e.g. 13"
            value={input}
            onChange={(e) => handleInputChange(e.target.value)}
            onKeyDown={(e) => {
              if (e.key === "Enter") convert();
            }}
            className="w-32 rounded-lg border-2 border-unit-6 bg-surface px-3 py-2 text-center font-mono text-2xl font-bold tracking-[0.3em] text-unit-6 outline-none focus:border-unit-6-dark"
            aria-label="Denary number input"
          />
          <button
            onClick={() => convert()}
            className="rounded-lg bg-unit-6 px-5 py-2.5 text-sm font-bold text-white transition-colors hover:bg-unit-6-dark"
          >
            Convert
          </button>
          <button
            onClick={handleClear}
            className="rounded-lg border-2 border-border bg-surface px-4 py-2 text-sm font-bold text-muted transition-colors hover:border-unit-6/50 hover:text-unit-6"
          >
            Clear
          </button>
          <button
            onClick={handleRandom}
            className="rounded-lg border-2 border-border bg-surface px-4 py-2 text-sm font-bold text-muted transition-colors hover:border-unit-6/50 hover:text-unit-6"
          >
            Random
          </button>
        </div>

        <div className="mt-4 flex flex-wrap gap-2">
          {PRESETS.map((p) => (
            <button
              key={p}
              onClick={() => applyPreset(p)}
              className="rounded-lg border-2 border-unit-6/30 bg-unit-6-light px-3 py-1 font-mono text-sm font-bold text-unit-6-dark transition-colors hover:border-unit-6 hover:bg-unit-6 hover:text-white"
            >
              {p}
            </button>
          ))}
        </div>

        {error && (
          <p className="mt-3 rounded-lg border-2 border-incorrect bg-incorrect-light px-3 py-2 text-center text-sm font-bold text-incorrect">
            {error}
          </p>
        )}
      </Card>

      {/* Division steps */}
      <Card>
        <p className="mb-3 text-xs font-bold uppercase tracking-wider text-unit-6">
          Repeated Division by 2
        </p>

        <div className="rounded-xl border-2 border-hint/40 bg-hint-light/50 p-4">
          {!result ? (
            <p className="text-center font-mono text-sm text-muted">
              Type a denary number above and press Convert to see the division table.
            </p>
          ) : submitted === 0 ? (
            <p className="text-center font-mono text-base font-bold text-unit-6">
              0 in binary is 0.
            </p>
          ) : (
            <div className="overflow-x-auto">
              <table className="mx-auto min-w-[380px] border-collapse font-mono text-sm">
                <thead>
                  <tr>
                    {["Step", "n ÷ 2", "Quotient", "Remainder", ""].map((h, i) => (
                      <th
                        key={i}
                        className={
                          i === 4
                            ? "px-3 py-2 text-left"
                            : "border-2 border-unit-6/40 bg-unit-6-light px-4 py-2 text-xs font-bold uppercase tracking-wide text-unit-6-dark"
                        }
                      >
                        {h}
                      </th>
                    ))}
                  </tr>
                </thead>
                <tbody>
                  {result.rows.map((row, idx) => (
                    <tr key={idx}>
                      <td className="border-2 border-unit-6/40 bg-surface px-4 py-2 text-center font-bold text-unit-6">
                        {idx + 1}
                      </td>
                      <td className="border-2 border-unit-6/40 bg-surface px-4 py-2 text-center text-foreground">
                        {row.before} ÷ 2
                      </td>
                      <td className="border-2 border-unit-6/40 bg-surface px-4 py-2 text-center font-bold text-foreground">
                        {row.quotient}
                      </td>
                      <td className="border-2 border-unit-6/40 bg-correct-light px-4 py-2 text-center text-lg font-extrabold text-correct">
                        {row.remainder}
                      </td>
                      <td className="px-3 py-2 text-left text-sm font-bold italic text-hint">
                        {idx === 0
                          ? "↓ start"
                          : idx === result.rows.length - 1
                            ? "↑ read up"
                            : ""}
                      </td>
                    </tr>
                  ))}
                  <tr>
                    <td
                      colSpan={5}
                      className="border-2 border-unit-6/40 bg-unit-6-light px-4 py-2 text-center text-xs font-bold uppercase tracking-wide text-unit-6-dark"
                    >
                      Quotient is 0 — stop. Read remainders from bottom to top.
                    </td>
                  </tr>
                </tbody>
              </table>
            </div>
          )}
        </div>

        <p className="mt-3 text-sm italic text-hint">
          Read the remainders column <strong>from bottom to top</strong>. That string of 0s and 1s is your binary number.
        </p>
      </Card>

      {/* Place value chart */}
      <Card>
        <div className="mb-3 flex flex-wrap items-center justify-between gap-2">
          <p className="text-xs font-bold uppercase tracking-wider text-unit-6">
            Place Value Chart (powers of 2)
          </p>
          <button
            onClick={() => setChartHidden((v) => !v)}
            className="rounded-md border border-border bg-surface px-2.5 py-1 text-xs font-semibold text-muted transition-colors hover:border-unit-6/50 hover:text-unit-6"
          >
            {chartHidden ? "Show Chart" : "Hide Chart"}
          </button>
        </div>

        {!chartHidden && (
          <div className="overflow-x-auto rounded-xl border-2 border-unit-6/30 bg-unit-6-light/40 p-3">
            <table className="mx-auto border-collapse font-mono">
              <tbody>
                <tr>
                  {COLUMNS.map((_, idx) => {
                    const exp = COLUMNS.length - 1 - idx;
                    return (
                      <td
                        key={`p-${exp}`}
                        className="min-w-[64px] border-2 border-unit-6/40 bg-unit-6-light px-4 py-2 text-center text-sm font-bold text-unit-6-dark"
                      >
                        2<sup>{exp}</sup>
                      </td>
                    );
                  })}
                </tr>
                <tr>
                  {COLUMNS.map((v) => (
                    <td
                      key={`v-${v}`}
                      className="min-w-[64px] border-2 border-unit-6/40 bg-surface px-4 py-2 text-center text-base font-bold text-unit-6"
                    >
                      {v}
                    </td>
                  ))}
                </tr>
                <tr>
                  {chartBits.map((b, i) => (
                    <td
                      key={`d-${i}`}
                      className={`min-w-[64px] border-2 border-unit-6/40 px-4 py-2 text-center text-2xl font-extrabold ${
                        b === 1
                          ? "bg-correct-light text-correct"
                          : b === 0
                            ? "bg-surface text-muted"
                            : "bg-surface text-muted/60"
                      }`}
                    >
                      {b === null ? "-" : b}
                    </td>
                  ))}
                </tr>
                <tr>
                  {chartBits.map((b, i) => (
                    <td
                      key={`s-${i}`}
                      className={`min-w-[64px] border-2 border-unit-6/40 px-4 py-2 text-center text-sm font-bold tracking-wider ${
                        b === 1
                          ? "bg-correct-light text-correct"
                          : b === 0
                            ? "bg-[#fafbfc] text-muted"
                            : "bg-[#fafbfc] text-muted/60"
                      }`}
                    >
                      {b === null ? "OFF" : b === 1 ? "ON" : "OFF"}
                    </td>
                  ))}
                </tr>
              </tbody>
            </table>
          </div>
        )}
      </Card>

      {/* Answer banner */}
      <Card
        className={`flex min-h-[90px] flex-col items-center justify-center gap-2 text-center ${
          submitted !== null && !answerHidden
            ? "border-correct bg-correct-light"
            : "border-unit-6/30 bg-unit-6-light/60"
        }`}
      >
        {submitted === null ? (
          <p className="font-mono text-base font-bold text-unit-6">
            Type a denary number above and press Convert.
          </p>
        ) : answerHidden ? (
          <p className="font-mono text-lg font-bold text-unit-6">
            {submitted} = ?<sub>2</sub>  (press Show Answer)
          </p>
        ) : (
          <p className="font-mono text-2xl font-extrabold text-correct">
            {submitted} = {binaryString}<sub>2</sub> in binary
          </p>
        )}
        <button
          onClick={() => setAnswerHidden((v) => !v)}
          className="mt-1 rounded-md border border-border bg-surface px-3 py-1 text-xs font-semibold text-muted transition-colors hover:border-unit-6/50 hover:text-unit-6"
        >
          {answerHidden ? "Show Answer" : "Hide Answer"}
        </button>
      </Card>

      {/* Footer note */}
      <Card className="border-l-4 border-l-unit-6 bg-unit-6-light/40">
        <p className="text-sm text-unit-6-dark">
          <strong>For students:</strong> solve on paper <em>first</em> using the division table in your worksheet. Type the denary number here only to <em>check</em>. The lesson is in the division and the bottom-up read, not the click.
        </p>
      </Card>
    </div>
  );
}
