import { Button, Card, TextInput } from "@cv/ui";
import { keepPreviousData, useQueryClient } from "@tanstack/react-query";
import { useState } from "react";
import {
  useAdminCreateLookupEntityMutation,
  useAdminDeleteLookupEntityMutation,
  useAdminLookupEntitiesQuery,
  useAdminUpdateLookupEntityMutation,
} from "@/generated/graphql";

interface AdminLookupTableProps {
  entityType: string;
  title: string;
}

type LookupEntity = {
  id: string;
  name: string;
  description: string | null;
  createdAt: string;
  updatedAt: string;
};

const formatDate = (iso: string) =>
  new Date(iso).toLocaleDateString(undefined, {
    year: "numeric",
    month: "short",
    day: "numeric",
  });

export const AdminLookupTable = ({
  entityType,
  title,
}: AdminLookupTableProps) => {
  const queryClient = useQueryClient();
  const [searchTerm, setSearchTerm] = useState("");
  const [newName, setNewName] = useState("");
  const [newDescription, setNewDescription] = useState("");
  const [editingId, setEditingId] = useState<string | null>(null);
  const [editName, setEditName] = useState("");
  const [editDescription, setEditDescription] = useState("");
  const [deleteConfirmId, setDeleteConfirmId] = useState<string | null>(null);

  const queryKey = ["AdminLookupEntities", { entityType, searchTerm }];

  const { data, isLoading } = useAdminLookupEntitiesQuery(
    {
      entityType: entityType as never,
      searchTerm: searchTerm || undefined,
    },
    { placeholderData: keepPreviousData },
  );

  const invalidate = () =>
    queryClient.invalidateQueries({ queryKey: ["AdminLookupEntities"] });

  const createMutation = useAdminCreateLookupEntityMutation({
    onSuccess: () => {
      invalidate();
      setNewName("");
      setNewDescription("");
    },
  });

  const updateMutation = useAdminUpdateLookupEntityMutation({
    onSuccess: () => {
      invalidate();
      setEditingId(null);
    },
  });

  const deleteMutation = useAdminDeleteLookupEntityMutation({
    onSuccess: () => {
      invalidate();
      setDeleteConfirmId(null);
    },
  });

  const handleCreate = (e: React.FormEvent) => {
    e.preventDefault();
    if (!newName.trim()) return;
    createMutation.mutate({
      entityType: entityType as never,
      name: newName.trim(),
      description: newDescription.trim() || undefined,
    });
  };

  const handleUpdate = (id: string) => {
    updateMutation.mutate({
      entityType: entityType as never,
      id,
      name: editName.trim() || undefined,
      description: editDescription,
    });
  };

  const handleDelete = (id: string) => {
    deleteMutation.mutate({ entityType: entityType as never, id });
  };

  const startEditing = (entity: LookupEntity) => {
    setEditingId(entity.id);
    setEditName(entity.name);
    setEditDescription(entity.description ?? "");
  };

  const entities = (data?.adminLookupEntities ?? []) as LookupEntity[];

  return (
    <Card>
      <div className="mb-4 flex items-center justify-between">
        <h3 className="text-lg font-medium text-ctp-text">{title}</h3>
        <span className="text-xs text-ctp-subtext0">
          {entities.length} {entities.length === 1 ? "item" : "items"}
        </span>
      </div>

      <div className="mb-4">
        <TextInput
          label=""
          placeholder="Search..."
          value={searchTerm}
          onChange={setSearchTerm}
        />
      </div>

      <form onSubmit={handleCreate} className="mb-4 flex gap-2">
        <TextInput
          label=""
          placeholder="Name"
          value={newName}
          onChange={setNewName}
        />
        <TextInput
          label=""
          placeholder="Description (optional)"
          value={newDescription}
          onChange={setNewDescription}
        />
        <Button type="submit" disabled={!newName.trim()}>
          Add
        </Button>
      </form>

      {isLoading ? (
        <p className="text-sm text-ctp-subtext0">Loading...</p>
      ) : entities.length === 0 ? (
        <p className="text-sm text-ctp-subtext0">No entities found</p>
      ) : (
        <div className="overflow-x-auto">
          <table className="w-full text-sm">
            <thead>
              <tr className="border-b border-ctp-surface1 text-left text-ctp-subtext0">
                <th className="pb-2 pr-4 font-medium">Name</th>
                <th className="pb-2 pr-4 font-medium">Description</th>
                <th className="pb-2 pr-4 font-medium">Created</th>
                <th className="pb-2 pr-4 font-medium text-right">Actions</th>
              </tr>
            </thead>
            <tbody>
              {entities.map((entity) => (
                <tr
                  key={entity.id}
                  className="border-b border-ctp-surface1 last:border-b-0"
                >
                  {editingId === entity.id ? (
                    <>
                      <td className="py-2 pr-4">
                        <TextInput
                          label=""
                          value={editName}
                          onChange={setEditName}
                        />
                      </td>
                      <td className="py-2 pr-4">
                        <TextInput
                          label=""
                          value={editDescription}
                          onChange={setEditDescription}
                        />
                      </td>
                      <td className="py-2 pr-4 text-ctp-subtext0">
                        {formatDate(entity.createdAt)}
                      </td>
                      <td className="py-2 pr-4 text-right">
                        <div className="flex justify-end gap-1">
                          <Button
                            variant="ghost"
                            size="sm"
                            onClick={() => handleUpdate(entity.id)}
                          >
                            Save
                          </Button>
                          <Button
                            variant="ghost"
                            size="sm"
                            onClick={() => setEditingId(null)}
                          >
                            Cancel
                          </Button>
                        </div>
                      </td>
                    </>
                  ) : (
                    <>
                      <td className="py-2 pr-4 text-ctp-text">
                        {entity.name}
                      </td>
                      <td className="py-2 pr-4 text-ctp-subtext0">
                        {entity.description ?? "-"}
                      </td>
                      <td className="py-2 pr-4 text-ctp-subtext0">
                        {formatDate(entity.createdAt)}
                      </td>
                      <td className="py-2 pr-4 text-right">
                        {deleteConfirmId === entity.id ? (
                          <div className="flex justify-end gap-1">
                            <Button
                              variant="ghost"
                              size="sm"
                              onClick={() => handleDelete(entity.id)}
                            >
                              Confirm
                            </Button>
                            <Button
                              variant="ghost"
                              size="sm"
                              onClick={() => setDeleteConfirmId(null)}
                            >
                              Cancel
                            </Button>
                          </div>
                        ) : (
                          <div className="flex justify-end gap-1">
                            <Button
                              variant="ghost"
                              size="sm"
                              onClick={() => startEditing(entity)}
                            >
                              Edit
                            </Button>
                            <Button
                              variant="ghost"
                              size="sm"
                              onClick={() => setDeleteConfirmId(entity.id)}
                            >
                              Delete
                            </Button>
                          </div>
                        )}
                      </td>
                    </>
                  )}
                </tr>
              ))}
            </tbody>
          </table>
        </div>
      )}
    </Card>
  );
};
