import { DataTable } from "~/components/custom_ui/data-table";
import type {
  PinnedFiltro,
  SearchFiltro,
} from "~/components/custom_ui/dataTable-toolbar";
import { DataTableColumnHeader } from "~/components/custom_ui/dataTable-header";
import { formatCurrency } from "~/lib/utils";
import type { ColumnDef } from "@tanstack/react-table";
import { EllipsisVertical, Trash2, Wrench } from "lucide-react";
import PaymentStatusEnum from "~/schemas/public/PaymentStatusEnum";
import {
  DropdownMenu,
  DropdownMenuContent,
  DropdownMenuItem,
  DropdownMenuLabel,
  DropdownMenuPortal,
  DropdownMenuRadioGroup,
  DropdownMenuRadioItem,
  DropdownMenuSeparator,
  DropdownMenuSub,
  DropdownMenuSubContent,
  DropdownMenuSubTrigger,
  DropdownMenuTrigger,
} from "~/components/ui/dropdown-menu";
import { Button } from "~/components/ui/button";
import type { OrdiniWPagamenti } from "~/server/controllers/ordini.controller";
import { api } from "~/utils/api";

type PaymentsTableProps = {
  data: OrdiniWPagamenti["pagamenti"];
  isAdmin: boolean;
  isUserView?: boolean;
};

const StatusMapping = (status: PaymentStatusEnum | null) => {
  switch (status) {
    case PaymentStatusEnum.success:
      return "Successo";
    case PaymentStatusEnum.processing:
      return "In lavorazione";
    case PaymentStatusEnum.failed:
      return "Errore";
    default:
    case null:
      return "Non completato";
  }
};
const EnumFromString = (value: string) => {
  switch (value) {
    case "Successo":
      return PaymentStatusEnum.success;
    case "In lavorazione":
      return PaymentStatusEnum.processing;
    case "Errore":
      return PaymentStatusEnum.failed;
    default:
      return null;
  }
};

export const PaymentsTable = ({
  data,
  isAdmin,
  isUserView = false,
}: PaymentsTableProps) => {
  const tabledata = data.map((row) => {
    return {
      id: row.id,
      status: StatusMapping(row.paymentstatus),
      amount: row.amount_cent,
      paid_at: row.paid_at,
      raw_status: row.paymentstatus,
      actions: "Azioni",
    };
  });

  const columns_titles = {
    username: "Utente",
    status: "Stato",
    amount: "Importo",
    paid_at: "Pagato il",
    actions: "Azioni",
  };
  const status_options = [
    { label: "Inutilizzato", value: "Inutilizzato" },
    { label: "Successo", value: "Successo" },
    { label: "In lavorazione", value: "In lavorazione" },
    { label: "Errore", value: "Errore" },
  ];
  const utils = api.useUtils();
  const { mutate: update } = api.servizio.updatePagamento.useMutation({
    onSuccess: async () => {
      await utils.servizio.getAllPagamenti.invalidate();
      await utils.servizio.getOrdini.invalidate();
      await utils.servizio.getOrdineById.invalidate({
        ordineId: data[0]?.ordine_id,
      });
      if ((!isAdmin || isUserView) && data[0]) {
        await utils.servizio.getUserPagamenti.invalidate({
          userId: data[0].userid,
        });
      }
    },
  });
  const { mutate: remove } = api.servizio.removePagamento.useMutation({
    onSuccess: async () => {
      await utils.servizio.getAllPagamenti.invalidate();
      await utils.servizio.getOrdini.invalidate();
      await utils.servizio.getOrdineById.invalidate({
        ordineId: data[0]?.ordine_id,
      });
      if ((!isAdmin || isUserView) && data[0]) {
        await utils.servizio.getUserPagamenti.invalidate({
          userId: data[0].userid,
        });
      }
    },
  });

  type Column = (typeof tabledata)[number];

  const columns: ColumnDef<Column>[] = [
    {
      header: ({ column }) => (
        <DataTableColumnHeader column={column} title={columns_titles.paid_at} />
      ),
      accessorKey: "paid_at",
      cell: ({ row }) => {
        const date = row.getValue("paid_at");
        return new Date(date as Date).toLocaleDateString();
      },
      sortingFn: "datetime",
      enableHiding: false,
    },
    {
      header: ({ column }) => (
        <DataTableColumnHeader column={column} title={columns_titles.status} />
      ),
      accessorKey: "status",

      filterFn: (row, id, value) => {
        // eslint-disable-next-line @typescript-eslint/no-unsafe-return, @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access
        return value.includes(row.getValue(id));
      },
    },
    {
      header: ({ column }) => (
        <DataTableColumnHeader column={column} title={columns_titles.amount} />
      ),
      accessorKey: "amount",
      cell: ({ row }) => {
        return <span>{formatCurrency(row.original.amount / 100)}</span>;
      },
    },
    {
      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>
                <EllipsisVertical />
              </Button>
            </DropdownMenuTrigger>
            <DropdownMenuContent align="end">
              <DropdownMenuLabel>Azioni</DropdownMenuLabel>
              <DropdownMenuSub>
                <DropdownMenuSubTrigger>
                  <Wrench />
                  <span>Aggiorna status</span>
                </DropdownMenuSubTrigger>
                <DropdownMenuPortal>
                  <DropdownMenuSubContent>
                    <DropdownMenuRadioGroup
                      value={StatusMapping(data.raw_status)}
                      onValueChange={(v) => {
                        update({
                          pagamentoId: data.id,
                          data: { paymentstatus: EnumFromString(v) },
                        });
                      }}
                    >
                      <DropdownMenuRadioItem value="Inutilizzato">
                        Inutilizzato
                      </DropdownMenuRadioItem>

                      <DropdownMenuRadioItem value="Successo">
                        Successo
                      </DropdownMenuRadioItem>
                      <DropdownMenuRadioItem value="In lavorazione">
                        In lavorazione
                      </DropdownMenuRadioItem>
                      <DropdownMenuRadioItem value="Errore">
                        Errore
                      </DropdownMenuRadioItem>
                    </DropdownMenuRadioGroup>
                  </DropdownMenuSubContent>
                </DropdownMenuPortal>
              </DropdownMenuSub>
              <DropdownMenuSeparator />
              <DropdownMenuItem
                aria-label="Elimina Pagamento"
                className="flex items-center gap-3 hover:cursor-pointer"
                onClick={() =>
                  confirm("Sei sicuro di voler eliminare il servizio?") &&
                  remove({ pagamentoId: data.id })
                }
              >
                <Trash2 className="size-6" />
                Elimina Pagamento
              </DropdownMenuItem>
            </DropdownMenuContent>
          </DropdownMenu>
        );
      },
    },
  ];

  const searchFiltro: SearchFiltro | undefined =
    isAdmin && !isUserView
      ? {
          columnName: "username",
          placeholder: "Cerca utente...",
        }
      : undefined;

  const pinnedFiltri: PinnedFiltro[] = [
    {
      title: "Status",
      columnName: "status",
      options: status_options,
    },
  ];

  return (
    <div className="w-full py-6">
      <DataTable
        columns={columns}
        data={tabledata}
        pinnedFiltri={pinnedFiltri}
        searchColumn={searchFiltro}
        columns_titles={columns_titles}
        defaultSort={[{ desc: true, id: "paid_at" }]}
        defaultColumnVisibility={{
          username: isAdmin && !isUserView,
          packid: true,
          status: true,
          amount: true,
          paid_at: true,
          actions: true,
        }}
      />
    </div>
  );
};
