import type { ColumnDef, Table } from "@tanstack/react-table";
import { DataTableColumnHeader } from "~/components/custom_ui/dataTable-header";
import { ExternalLink, MoreHorizontal, Pen, Trash } from "lucide-react";
import { DataTable } from "~/components/custom_ui/data-table";
import type { SearchFiltro } from "~/components/custom_ui/dataTable-toolbar";
import { Button, buttonVariants } from "~/components/ui/button";
import { useEffect, useState, type FormEvent } from "react";
import type {
  Storageindex,
  StorageindexId,
} from "~/schemas/public/Storageindex";
import { Checkbox } from "~/components/ui/checkbox";
import {
  DropdownMenu,
  DropdownMenuContent,
  DropdownMenuItem,
  DropdownMenuLabel,
  DropdownMenuSeparator,
  DropdownMenuTrigger,
} from "~/components/ui/dropdown-menu";
import Link from "next/link";
import { cn } from "~/lib/utils";

import {
  AlertDialog,
  AlertDialogTrigger,
  AlertDialogContent,
  AlertDialogHeader,
  AlertDialogTitle,
  AlertDialogDescription,
  AlertDialogFooter,
  AlertDialogCancel,
  AlertDialogAction,
} from "~/components/ui/alert-dialog";
import { useTranslation } from "~/providers/I18nProvider";
import { api } from "~/utils/api";
import toast from "react-hot-toast";
import {
  Dialog,
  DialogContent,
  DialogDescription,
  DialogHeader,
  DialogTitle,
} from "~/components/ui/dialog";
import { Input } from "~/components/ui/input";
import { useStorageTable } from "~/providers/StorageTableProvider";

export const StorageTable = ({
  data,
  handleDelete,
}: {
  data: Storageindex[];

  handleDelete: (id: StorageindexId) => void;
}) => {
  const { setTable, cb_onStateChange } = useStorageTable();

  const [deleteConfirmId, setDeleteConfirmId] = useState<StorageindexId | null>(
    null,
  );

  const [renameTarget, setRenameTarget] = useState<{
    allegatoId: StorageindexId;
    filename: string | null;
  } | null>(null);

  const [tableInstance, setTableInstance] = useState<Table<Column> | null>(
    null,
  );

  // Defer the state update for `setTable`
  useEffect(() => {
    if (tableInstance) {
      setTable(tableInstance);
    }
  }, [tableInstance, setTable]);

  const tabledata = data.map((row) => {
    return {
      id: row.id,
      filename: row.filename,
      ext: row.ext,
      created_at: row.created_at,
      from_admin: row.from_admin,
      expires_at: row.expires_at,
      actions: "Azioni",
    };
  });

  const columns_titles = {
    id: "Codice",
    filename: "Nome file",
    ext: "Estensione",
    created_at: "Data creazione",
    from_admin: "Caricato da",

    actions: "Azioni",
  };
  type Column = (typeof tabledata)[number];

  const columns: ColumnDef<Column>[] = [
    {
      id: "select",
      header: ({ table }) => (
        <Checkbox
          checked={
            table.getIsAllPageRowsSelected() ||
            (table.getIsSomePageRowsSelected() && "indeterminate")
          }
          onCheckedChange={(value) => table.toggleAllPageRowsSelected(!!value)}
          aria-label="Select all"
        />
      ),
      cell: ({ row }) => (
        <Checkbox
          checked={row.getIsSelected()}
          onCheckedChange={(value) => row.toggleSelected(!!value)}
          aria-label="Select row"
        />
      ),
      enableSorting: false,
      enableHiding: false,
    },
    {
      header: ({ column }) => (
        <DataTableColumnHeader
          column={column}
          title={columns_titles.filename}
        />
      ),
      accessorKey: "filename",
      enableHiding: false,
      cell: ({ row }) => {
        return (
          <Link
            aria-label="Visualizza Allegato"
            href={`/area-riservata/allegato-view/${row.original.id}`}
            target="_blank"
            className="text-blue-600 underline underline-offset-2"
          >
            {row.original.filename}
          </Link>
        );
      },
    },
    {
      header: ({ column }) => (
        <DataTableColumnHeader
          column={column}
          title={columns_titles.created_at}
        />
      ),
      accessorKey: "created_at",
      cell: ({ row }) => {
        const date = row.getValue("created_at");
        return new Date(date as Date).toLocaleDateString();
      },

      enableHiding: false,
    },
    {
      header: ({ column }) => (
        <DataTableColumnHeader
          column={column}
          title={columns_titles.from_admin}
        />
      ),
      accessorKey: "from_admin",
      cell: ({ row }) => {
        return row.original.from_admin ? "Admin" : "Utente";
      },

      enableHiding: false,
    },
    {
      id: "actions",
      enableHiding: false,
      cell: ({ row }) => {
        const data = row.original;

        return (
          <DropdownMenu>
            <DropdownMenuTrigger asChild>
              <Button variant="ghost" className="size-8 p-0">
                <span className="sr-only">Open menu</span>
                <MoreHorizontal />
              </Button>
            </DropdownMenuTrigger>
            <DropdownMenuContent align="end">
              <DropdownMenuLabel>Azioni</DropdownMenuLabel>

              <DropdownMenuItem>
                <Link
                  aria-label="Visualizza Allegato"
                  href={`/area-riservata/allegato-view/${data.id}`}
                  target="_blank"
                  className="flex items-center gap-2"
                >
                  <ExternalLink className="size-5" />
                  Visualizza
                </Link>
              </DropdownMenuItem>
              <DropdownMenuSeparator />
              <DropdownMenuItem
                aria-label="Rinomina Allegato"
                role="button"
                onClick={() =>
                  setRenameTarget({
                    allegatoId: data.id,
                    filename: data.filename,
                  })
                }
                className="flex w-full items-center gap-2"
              >
                <Pen className="size-5" />
                Rinomina
              </DropdownMenuItem>
              <DropdownMenuSeparator />
              <DropdownMenuItem
                aria-label="Elimina Allegato"
                role="button"
                className="flex w-full items-center gap-2"
                onClick={() => setDeleteConfirmId(data.id)}
              >
                <Trash className="size-5" />
                Elimina
              </DropdownMenuItem>
            </DropdownMenuContent>
          </DropdownMenu>
        );
      },
    },
  ];

  const searchFiltro: SearchFiltro = {
    columnName: "filename",
    placeholder: "Cerca file ...",
  };
  return (
    <div className="mx-auto w-full px-2 py-4">
      <DataTable
        columns={columns}
        data={tabledata}
        pinnedFiltri={undefined}
        searchColumn={searchFiltro}
        columns_titles={columns_titles}
        defaultSort={[{ desc: true, id: "created_at" }]}
        onTableInit={setTableInstance}
        onStateChange={cb_onStateChange}
      />
      {deleteConfirmId !== null && (
        <AlertDialog
          open={deleteConfirmId !== null}
          onOpenChange={() => setDeleteConfirmId(null)}
        >
          <AlertDialogTrigger asChild></AlertDialogTrigger>
          <AlertDialogContent>
            <AlertDialogHeader>
              <AlertDialogTitle>Elimina allegato</AlertDialogTitle>
              <AlertDialogDescription>
                Sei sicuro di voler eliminare questo allegato?
              </AlertDialogDescription>
            </AlertDialogHeader>
            <AlertDialogFooter>
              <AlertDialogCancel>Annulla</AlertDialogCancel>
              <AlertDialogAction
                className={cn(buttonVariants({ variant: "destructive" }))}
                onClick={() => {
                  handleDelete(deleteConfirmId);
                  setDeleteConfirmId(null);
                }}
              >
                Procedi
              </AlertDialogAction>
            </AlertDialogFooter>
          </AlertDialogContent>
        </AlertDialog>
      )}

      {renameTarget !== null && (
        <RinominaDialog
          renameTarget={renameTarget}
          setRenameTarget={setRenameTarget}
        />
      )}
    </div>
  );
};

const RinominaDialog = ({
  renameTarget,
  setRenameTarget,
}: {
  renameTarget: { allegatoId: StorageindexId; filename: string | null };
  setRenameTarget: (
    target: { allegatoId: StorageindexId; filename: string | null } | null,
  ) => void;
}) => {
  const { t } = useTranslation();
  const utils = api.useUtils();

  const { mutate: renameFile } = api.storage.renameFile.useMutation({
    onMutate: () => {
      setRenameTarget(null);
      const toastId = toast.loading(t.caricamento, {
        icon: "🪛",
      });
      return { toastId };
    },
    onSuccess: async (_error, _variables, context) => {
      await utils.storage.getAll.invalidate();
      toast.success(t.successo, {
        icon: "👍",
        id: context?.toastId,
      });
    },
  });

  const handleEditSubmit = (e: FormEvent<HTMLFormElement>) => {
    e.preventDefault();
    const form = e.currentTarget;
    const formData = new FormData(form);
    if (!formData.get("filename")) {
      return;
    }
    renameFile({
      fileId: renameTarget.allegatoId,
      name: formData.get("filename") as string,
    });
  };
  return (
    <Dialog
      open={renameTarget !== null}
      onOpenChange={() => setRenameTarget(null)}
    >
      <DialogContent>
        <DialogHeader>
          <DialogTitle>{t.modifica}</DialogTitle>
          <DialogDescription className="sr-only">modifica</DialogDescription>
        </DialogHeader>

        <form onSubmit={handleEditSubmit} method="post">
          <div className="flex items-center gap-3">
            <Input
              type="text"
              placeholder="Modifica messaggio"
              className="mt-0"
              name="filename"
              defaultValue={renameTarget.filename || undefined}
              minLength={5}
            />
            <Button type="submit">{t.salva}</Button>
          </div>
        </form>
      </DialogContent>
    </Dialog>
  );
};
