"use client";

import { useRef } from "react";

interface Row {
  level: number;
  cantripsKnown: number;
  spellsKnown: number;
  slots: number[];
}

interface Props {
  progression: Row[];
  onChange: (rows: Row[]) => void;
}

const COLUMNS = 12; // level, cantrips, spells, slots 1-9

function cellId(r: number, c: number) {
  return `sp-cell-${r}-${c}`;
}

export default function SpellProgressionTable({ progression, onChange }: Props) {
  const rootRef = useRef<HTMLDivElement>(null);

  const patchRow = (idx: number, patch: Partial<Row>) => {
    onChange(progression.map((r, k) => (k === idx ? { ...r, ...patch } : r)));
  };
  const patchSlot = (idx: number, spellLv: number, value: number) => {
    const row = progression[idx];
    const nextSlots = [...(row.slots ?? [])];
    while (nextSlots.length <= spellLv - 1) nextSlots.push(0);
    nextSlots[spellLv - 1] = value;
    patchRow(idx, { slots: nextSlots });
  };
  const addRow = () => {
    const last = progression[progression.length - 1];
    onChange([
      ...progression,
      { level: (last?.level ?? 0) + 1, cantripsKnown: last?.cantripsKnown ?? 0, spellsKnown: last?.spellsKnown ?? 0, slots: [...(last?.slots ?? [])] },
    ]);
  };
  const removeRow = (k: number) => onChange(progression.filter((_, i) => i !== k));

  const setCell = (r: number, c: number, raw: string) => {
    const v = Number(raw) || 0;
    if (c === 0) patchRow(r, { level: v || 1 });
    else if (c === 1) patchRow(r, { cantripsKnown: Math.max(0, v) });
    else if (c === 2) patchRow(r, { spellsKnown: Math.max(0, v) });
    else patchSlot(r, c - 2, Math.max(0, v));
  };

  const focusCell = (r: number, c: number) => {
    const el = rootRef.current?.querySelector<HTMLInputElement>(`#${cellId(r, c)}`);
    el?.focus();
    el?.select();
  };

  const onKeyDown = (e: React.KeyboardEvent<HTMLInputElement>, r: number, c: number) => {
    const maxR = progression.length - 1;
    if (e.key === "ArrowRight" || (e.key === "Enter" && e.shiftKey === false && e.altKey === false && !e.ctrlKey && !e.metaKey && c < COLUMNS - 1)) {
      e.preventDefault();
      focusCell(r, Math.min(COLUMNS - 1, c + 1));
    } else if (e.key === "ArrowLeft") {
      e.preventDefault();
      focusCell(r, Math.max(0, c - 1));
    } else if (e.key === "ArrowDown" || (e.key === "Enter" && c === COLUMNS - 1)) {
      e.preventDefault();
      if (r < maxR) focusCell(r + 1, c === COLUMNS - 1 ? 0 : c);
    } else if (e.key === "ArrowUp") {
      e.preventDefault();
      focusCell(Math.max(0, r - 1), c);
    }
  };

  const onPaste = (e: React.ClipboardEvent<HTMLInputElement>, startR: number, startC: number) => {
    const text = e.clipboardData.getData("text");
    if (!text || (!text.includes("\t") && !text.includes("\n"))) return; // single value: let default happen
    e.preventDefault();
    const rows = text.replace(/\r/g, "").split("\n").filter((line) => line.length > 0);
    const grid = rows.map((line) => line.split("\t"));

    const next: Row[] = progression.map((r) => ({ ...r, slots: [...r.slots] }));

    for (let dr = 0; dr < grid.length; dr++) {
      const targetRow = startR + dr;
      while (next.length <= targetRow) {
        const last = next[next.length - 1];
        next.push({
          level: (last?.level ?? 0) + 1,
          cantripsKnown: 0,
          spellsKnown: 0,
          slots: [],
        });
      }
      for (let dc = 0; dc < grid[dr].length; dc++) {
        const targetC = startC + dc;
        if (targetC >= COLUMNS) break;
        const raw = grid[dr][dc].trim();
        // Skip empty cells so partial pastes don't wipe existing data
        if (raw === "") continue;
        const v = Number(raw);
        if (Number.isNaN(v)) continue;
        const row = next[targetRow];
        if (targetC === 0) row.level = v || 1;
        else if (targetC === 1) row.cantripsKnown = Math.max(0, v);
        else if (targetC === 2) row.spellsKnown = Math.max(0, v);
        else {
          const spellLv = targetC - 2;
          while (row.slots.length <= spellLv - 1) row.slots.push(0);
          row.slots[spellLv - 1] = Math.max(0, v);
        }
      }
    }
    onChange(next);
  };

  return (
    <div ref={rootRef} className="flex flex-col gap-2 w-full">
      <div className="text-xs text-neutral-500">
        Tip: paste tab-separated rows (e.g. from Excel or dndbeyond) into any cell. Arrow keys / Enter to navigate.
      </div>
      <div className="overflow-x-auto">
        <table className="text-xs border-collapse w-full">
          <thead>
            <tr className="text-neutral-500">
              <th className="p-1 text-left">Lv</th>
              <th className="p-1 text-left">Cantrips</th>
              <th className="p-1 text-left">Spells</th>
              {[1,2,3,4,5,6,7,8,9].map((sl) => (
                <th key={sl} className="p-1 text-center">{sl}</th>
              ))}
              <th className="p-1"></th>
            </tr>
          </thead>
          <tbody>
            {progression.map((row, r) => (
              <tr key={r} className="border-t border-neutral-800">
                {[
                  row.level,
                  row.cantripsKnown,
                  row.spellsKnown,
                  ...Array.from({ length: 9 }, (_, i) => row.slots[i] ?? 0),
                ].map((val, c) => (
                  <td key={c} className="p-1">
                    <input
                      id={cellId(r, c)}
                      type="number"
                      min={c === 0 ? 1 : 0}
                      max={c === 0 ? 20 : undefined}
                      value={val}
                      onChange={(e) => setCell(r, c, e.target.value)}
                      onKeyDown={(e) => onKeyDown(e, r, c)}
                      onPaste={(e) => onPaste(e, r, c)}
                      className={`bg-neutral-800 border border-neutral-700 rounded px-1 py-0.5 ${c >= 3 ? "w-10 text-center" : "w-12"}`}
                    />
                  </td>
                ))}
                <td className="p-1">
                  <button
                    type="button"
                    onClick={() => removeRow(r)}
                    className="text-red-400 hover:text-red-300 text-xs px-1"
                  >×</button>
                </td>
              </tr>
            ))}
          </tbody>
        </table>
      </div>
      <button
        type="button"
        onClick={addRow}
        className="self-start text-xs text-amber-400 border border-amber-400/40 hover:bg-amber-400/10 rounded px-3 py-1"
      >
        + Add level row
      </button>
    </div>
  );
}
