import type { AdminTableColumn } from "@xtablo/shared-types";
import { FormEvent, useEffect, useMemo, useState } from "react";

type RowEditFormProps = {
  columns: AdminTableColumn[];
  editableFields: string[];
  isSaving?: boolean;
  onSave: (changes: Record<string, string | boolean | null>) => Promise<void>;
  record: Record<string, string | boolean | null>;
};

export function RowEditForm({
  columns,
  editableFields,
  isSaving = false,
  onSave,
  record,
}: RowEditFormProps) {
  const [draft, setDraft] = useState(record);
  const [showDiff, setShowDiff] = useState(false);

  useEffect(() => {
    setDraft(record);
    setShowDiff(false);
  }, [record]);

  const editableColumns = useMemo(
    () => columns.filter((column) => editableFields.includes(column.id)),
    [columns, editableFields]
  );

  const changedFields = editableColumns.filter((column) => draft[column.id] !== record[column.id]);
  const hasChanges = changedFields.length > 0;

  const handleSubmit = (event: FormEvent<HTMLFormElement>) => {
    event.preventDefault();
    setShowDiff(true);
  };

  const handleSave = async () => {
    if (!hasChanges) {
      return;
    }

    await onSave(
      Object.fromEntries(changedFields.map((column) => [column.id, draft[column.id] ?? null]))
    );
    setShowDiff(false);
  };

  return (
    <form className="space-y-4" onSubmit={handleSubmit}>
      {editableColumns.map((column) => (
        <label className="block" htmlFor={column.id} key={column.id}>
          <span className="mb-2 block text-sm font-medium">{column.label}</span>
          <input
            className="w-full rounded-2xl border border-border px-3 py-2"
            id={column.id}
            onChange={(event) =>
              setDraft((currentValue) => ({
                ...currentValue,
                [column.id]: event.target.value,
              }))
            }
            value={String(draft[column.id] ?? "")}
          />
        </label>
      ))}

      <button className="rounded-2xl bg-foreground px-4 py-2 text-background" type="submit">
        Review Changes
      </button>

      {showDiff ? (
        <div className="rounded-3xl border border-border bg-card p-4">
          <p className="text-sm font-semibold uppercase tracking-[0.2em]">Before</p>
          {changedFields.map((column) => (
            <p key={`${column.id}-before`}>
              {column.label}: {String(record[column.id] ?? "")}
            </p>
          ))}
          <p className="mt-4 text-sm font-semibold uppercase tracking-[0.2em]">After</p>
          {changedFields.map((column) => (
            <p key={`${column.id}-after`}>
              {column.label}: {String(draft[column.id] ?? "")}
            </p>
          ))}
          {!hasChanges ? (
            <p className="mt-4 text-sm text-foreground/70">No changes to save yet.</p>
          ) : null}
          <div className="mt-4 flex gap-3">
            <button
              className="rounded-2xl border border-border px-4 py-2"
              onClick={() => setShowDiff(false)}
              type="button"
            >
              Keep Editing
            </button>
            <button
              className="rounded-2xl bg-foreground px-4 py-2 text-background disabled:cursor-not-allowed disabled:opacity-60"
              disabled={!hasChanges || isSaving}
              onClick={() => void handleSave()}
              type="button"
            >
              {isSaving ? "Saving..." : "Confirm Update"}
            </button>
          </div>
        </div>
      ) : null}
    </form>
  );
}
