"use client";
import { useState, useTransition } from "react";
import { Hash, Loader2, CheckCircle2 } from "lucide-react";
import { previewReparseCodes, reparseCodes, type ReparseCodesPreview } from "@/app/actions/maintenance";

type State =
  | { kind: "idle" }
  | { kind: "scanning" }
  | { kind: "preview"; data: ReparseCodesPreview }
  | { kind: "running" }
  | { kind: "done"; filled: number; updated: number; skipped: number };

export function ReparseCodesButton() {
  const [state, setState] = useState<State>({ kind: "idle" });
  const [pending, start] = useTransition();

  const scan = () => {
    setState({ kind: "scanning" });
    start(async () => {
      const data = await previewReparseCodes();
      setState({ kind: "preview", data });
    });
  };

  const run = (force: boolean) => {
    if (state.kind !== "preview") return;
    const count = force ? state.data.missing + state.data.changed : state.data.missing;
    const verb = force ? "Re-parse all (overwrite manual edits)" : "Fill missing only";
    if (!confirm(`${verb} for ${count} cover${count === 1 ? "" : "s"}? Files won't move into new letter buckets until you also run Re-organize, and thumbnail filenames won't update until Regenerate Thumbnails runs.`)) return;
    setState({ kind: "running" });
    start(async () => {
      const r = await reparseCodes({ force });
      setState({ kind: "done", ...r });
    });
  };

  return (
    <div className="py-2">
      <div className="flex items-start justify-between gap-4">
        <div className="min-w-0">
          <div className="text-sm font-medium">Re-parse Codes From Filenames</div>
          <div className="text-xs text-[var(--color-fg-muted)] mt-0.5">
            Re-run the JAV-code parser against every cover&apos;s stored filename. Useful after a parser
            change (added <code className="font-mono">z</code>-suffix or alphanumeric prefix support, etc.) so old
            rows pick up the new behaviour. Pair with <em>Re-organize</em> + <em>Regenerate Thumbnails</em>
            to also move files and rename thumbs.
          </div>
          {state.kind === "preview" && (
            <div className="text-xs mt-2 text-[var(--color-fg-dim)] space-y-0.5">
              <div>
                <span className="font-mono text-[var(--color-cyan)]">{state.data.missing}</span> missing
                {" · "}
                <span className="font-mono text-[var(--color-amber,#fbbf24)]">{state.data.changed}</span> would change
                {" · "}of {state.data.total} top-level covers
              </div>
              {state.data.sampleChanges.length > 0 && (
                <details className="mt-2">
                  <summary className="cursor-pointer text-[var(--color-fg-dim)] hover:text-[var(--color-fg)]">
                    Preview {state.data.sampleChanges.length} sample change{state.data.sampleChanges.length === 1 ? "" : "s"}
                  </summary>
                  <div className="mt-1.5 max-h-40 overflow-y-auto rounded-md border border-[var(--color-glass-border)] p-2 space-y-0.5 font-mono text-[11px]">
                    {state.data.sampleChanges.map((c) => (
                      <div key={c.id} className="flex items-baseline gap-2">
                        <span className="text-[var(--color-coral)] line-through">{c.oldCode}</span>
                        <span className="text-[var(--color-fg-muted)]">→</span>
                        <span className="text-[var(--color-mint)]">{c.newCode}</span>
                        <span className="text-[var(--color-fg-muted)] truncate">{c.filename}</span>
                      </div>
                    ))}
                  </div>
                </details>
              )}
            </div>
          )}
          {state.kind === "done" && (
            <div className="flex items-center gap-1.5 text-xs text-[var(--color-mint)] mt-2 flex-wrap">
              <CheckCircle2 className="w-3.5 h-3.5" />
              Filled {state.filled} · updated {state.updated} · skipped {state.skipped}
            </div>
          )}
        </div>
        <div className="flex-shrink-0 flex items-center gap-2">
          {state.kind === "idle" && (
            <button
              onClick={scan}
              disabled={pending}
              className="inline-flex items-center justify-center gap-1.5 min-w-[100px] text-xs px-3 py-1.5 rounded-lg glass glass-hover text-[var(--color-fg-dim)] hover:text-[var(--color-fg)] whitespace-nowrap"
            >
              <Hash className="w-3.5 h-3.5" /> Scan
            </button>
          )}
          {(state.kind === "scanning" || state.kind === "running") && (
            <span className="flex items-center gap-1.5 text-xs text-[var(--color-fg-dim)]">
              <Loader2 className="w-3.5 h-3.5 animate-spin" />
              {state.kind === "scanning" ? "Scanning…" : "Updating…"}
            </span>
          )}
          {state.kind === "preview" && (
            <>
              <button
                onClick={() => setState({ kind: "idle" })}
                className="inline-flex items-center justify-center min-w-[80px] text-xs px-3 py-1.5 rounded-lg text-[var(--color-fg-muted)] hover:text-[var(--color-fg)] hover:bg-[var(--color-glass)]"
              >
                Cancel
              </button>
              {state.data.missing > 0 && (
                <button
                  onClick={() => run(false)}
                  disabled={pending}
                  className="inline-flex items-center justify-center gap-1.5 min-w-[100px] text-xs px-3 py-1.5 rounded-lg bg-[var(--color-cyan)]/15 text-[var(--color-cyan)] border border-[var(--color-cyan)]/40 hover:bg-[var(--color-cyan)]/25 disabled:opacity-40 whitespace-nowrap"
                >
                  Fill {state.data.missing} missing
                </button>
              )}
              {state.data.changed > 0 && (
                <button
                  onClick={() => run(true)}
                  disabled={pending}
                  className="flex items-center gap-1.5 text-xs px-3 py-1.5 rounded-lg border border-amber-500/40 text-amber-200 hover:bg-amber-500/10 disabled:opacity-40 whitespace-nowrap"
                  title="Overwrite codes that disagree with the parser. Will clobber any code you set manually."
                >
                  Force overwrite {state.data.changed}
                </button>
              )}
            </>
          )}
          {state.kind === "done" && (
            <button
              onClick={() => setState({ kind: "idle" })}
              className="inline-flex items-center justify-center min-w-[80px] text-xs px-3 py-1.5 rounded-lg text-[var(--color-fg-muted)] hover:text-[var(--color-fg)] hover:bg-[var(--color-glass)]"
            >
              Done
            </button>
          )}
        </div>
      </div>
    </div>
  );
}
