"use client";

import { useEffect, useRef, useState, useTransition } from "react";

type EditableCellProps = {
  value: string;
  onSave: (next: string) => Promise<{ ok: boolean; error?: string }>;
  label?: string;
  isCurrentlyEditing?: boolean;
  onEditStart?: () => void;
  onEditEnd?: () => void;
};

export default function EditableCell({
  value,
  onSave,
  label,
  isCurrentlyEditing,
  onEditStart,
  onEditEnd,
}: EditableCellProps) {
  const [editing, setEditing] = useState(false);
  const [draft, setDraft] = useState(value);
  const [error, setError] = useState<string | null>(null);
  const [isPending, startTransition] = useTransition();
  const inputRef = useRef<HTMLInputElement>(null);

  // Keep draft in sync if the underlying value changes from outside
  // (auto-refresh, server revalidation) while we are NOT actively editing.
  useEffect(() => {
    if (!editing) setDraft(value);
  }, [value, editing]);

  // Auto-clear an error after 3 seconds.
  useEffect(() => {
    if (!error) return;
    const id = setTimeout(() => setError(null), 3000);
    return () => clearTimeout(id);
  }, [error]);

  function begin() {
    setDraft(value);
    setEditing(true);
    onEditStart?.();
    requestAnimationFrame(() => {
      inputRef.current?.focus();
      inputRef.current?.select();
    });
  }

  function cancel() {
    setEditing(false);
    setDraft(value);
    setError(null);
    onEditEnd?.();
  }

  function commit() {
    const next = draft;
    if (next === value) {
      cancel();
      return;
    }
    startTransition(async () => {
      const result = await onSave(next);
      if (result.ok) {
        setEditing(false);
        setError(null);
        onEditEnd?.();
      } else {
        setError(result.error ?? "Save failed");
      }
    });
  }

  if (!editing) {
    return (
      <button
        type="button"
        onClick={begin}
        aria-label={label ? `Edit ${label}` : undefined}
        className="group relative -mx-1 -my-0.5 inline-flex w-full items-center rounded-sm px-1 py-0.5 text-left font-mono text-sm text-zinc-900 hover:bg-yellow-50 focus:outline-none focus-visible:ring-2 focus-visible:ring-yellow-400"
      >
        <span className="truncate">
          {value || <em className="not-italic text-zinc-400">—</em>}
        </span>
        <span
          aria-hidden="true"
          className="ml-2 hidden text-[10px] font-semibold uppercase tracking-widest text-zinc-400 group-hover:inline"
        >
          edit
        </span>
      </button>
    );
  }

  return (
    <div className="relative -mx-1 -my-0.5 flex flex-col">
      <div className="flex items-center gap-1">
        <input
          ref={inputRef}
          value={draft}
          onChange={(e) => setDraft(e.target.value)}
          onKeyDown={(e) => {
            if (e.key === "Enter") {
              e.preventDefault();
              commit();
            } else if (e.key === "Escape") {
              e.preventDefault();
              cancel();
            }
          }}
          disabled={isPending}
          className="w-full min-w-0 rounded-sm border-2 border-yellow-400 bg-white px-1 py-0.5 font-mono text-sm text-zinc-900 outline-none disabled:opacity-60"
        />
        <button
          type="button"
          onClick={commit}
          disabled={isPending}
          aria-label="Save"
          className="shrink-0 border border-zinc-900 bg-zinc-900 px-1.5 py-0.5 text-[10px] font-bold uppercase tracking-widest text-white hover:bg-zinc-700 disabled:opacity-60"
        >
          {isPending ? "…" : "save"}
        </button>
        <button
          type="button"
          onClick={cancel}
          disabled={isPending}
          aria-label="Cancel"
          className="shrink-0 border border-zinc-300 bg-white px-1.5 py-0.5 text-[10px] font-bold uppercase tracking-widest text-zinc-600 hover:border-zinc-500 hover:text-zinc-900 disabled:opacity-60"
        >
          ✕
        </button>
      </div>
      {error && (
        <p className="mt-1 font-mono text-[11px] text-red-700" role="alert">
          {error}
        </p>
      )}
    </div>
  );
}
