import { Download, Pen, Trash } from "lucide-react";
import type { GetServerSideProps } from "next";
import Head from "next/head";
import { useState, type FormEvent } from "react";
import { AreaRiservataLayout } from "~/components/Layout";
import { LoadingPage } from "~/components/loading";
import { Status500 } from "~/components/status-page";
import { Button } from "~/components/ui/button";
import type { NextPageWithLayout } from "~/pages/_app";
import { useSession } from "~/providers/SessionProvider";
import type { StorageindexId } from "~/schemas/public/Storageindex";
import { api } from "~/utils/api";
import toast from "react-hot-toast";
import {
  Dialog,
  DialogContent,
  DialogDescription,
  DialogHeader,
  DialogTitle,
  DialogTrigger,
} from "~/components/ui/dialog";
import { useTranslation } from "~/providers/I18nProvider";
import { Input } from "~/components/ui/input";
import { Confirm } from "~/components/confirm";
import { useRouter } from "next/router";
import { AllegatoIframe } from "~/components/allegato-iframe";
import { handleDownload } from "~/hooks/filesHooks";
import { TrpcAuthedFetchingIstance } from "~/server/utils/ssgHelper";
import { zStorageIndexId } from "~/server/utils/zod_types";
import { DocNotFoundPage } from "~/components/doc_not_found";

type AllegatoViewProps = {
  allegatoId: StorageindexId;
};

const AllegatoView: NextPageWithLayout<AllegatoViewProps> = ({
  allegatoId,
}: AllegatoViewProps) => {
  const { t } = useTranslation();
  const session = useSession();
  const { mutateAsync: getToken } = api.storage.getStorageToken.useMutation();
  const { data: fileInfos, isLoading } = api.storage.getStorageFromId.useQuery({
    storageId: allegatoId,
  });
  const utils = api.useUtils();
  const router = useRouter();
  const { mutate: deleteFile } = api.storage.deleteStorage.useMutation({
    onMutate: () => {
      const toastId = toast.loading(t.caricamento, {
        icon: "🪛",
      });
      return { toastId };
    },
    onSuccess: async (_error, _variables, context) => {
      await utils.storage.getUserStorage.invalidate();

      toast.success(t.allegati.allegato_rimosso, {
        icon: "🗑️",
        id: context?.toastId,
      });

      await router.push("/area-riservata/admin/storage");
    },
  });

  if (session.status === "pending" || isLoading) return <LoadingPage />;
  if (!session || !session.user) {
    console.error("Session not found or user not authenticated", session);

    return <Status500 />;
  }
  if (!fileInfos) return <DocNotFoundPage />;

  return (
    <>
      <Head>
        <title>Infoalloggi.it | {fileInfos.filename}</title>
      </Head>

      <div className="flex h-full w-full grow flex-col md:flex-row">
        <div className="flex grow flex-col justify-center space-y-2 p-4">
          <div className="mx-auto flex flex-wrap items-center gap-4">
            <span>{fileInfos.filename}</span>
            <span>caricato il {fileInfos.created_at.toLocaleString("it")}</span>
            <Button
              onClick={() =>
                handleDownload({
                  file: fileInfos,
                  getToken: async () => await getToken(),
                })
              }
              className="flex gap-2"
            >
              <Download size={16} />
              Download
            </Button>
            <RinominaDialog
              allegatoId={allegatoId}
              filename={fileInfos.filename}
            />
            {session.user.isAdmin && (
              <Confirm
                onConfirm={() => deleteFile({ storageId: allegatoId })}
                title="Elimina allegato"
                description="Sei sicuro di voler eliminare questo allegato?"
              >
                <Button variant="destructive" className="flex gap-2">
                  <Trash size={16} />
                  Elimina
                </Button>
              </Confirm>
            )}
          </div>
          <AllegatoIframe allegato={fileInfos.id + fileInfos.ext} />
        </div>
      </div>
    </>
  );
};

AllegatoView.getLayout = function getLayout(page) {
  return <AreaRiservataLayout noSidebar>{page}</AreaRiservataLayout>;
};

export const getServerSideProps = (async (context) => {
  const allegatoId = context.params?.allegatoId;
  if (!allegatoId || typeof allegatoId !== "string") {
    return {
      notFound: true,
    };
  }

  const parsedStorageId = zStorageIndexId.safeParse(allegatoId);

  if (!parsedStorageId.success) {
    return {
      notFound: true,
    };
  }

  const access_token = context.req.cookies.access_token;

  const helper = await TrpcAuthedFetchingIstance({ access_token });
  if (helper) {
    await helper.trpc.storage.getStorageFromId.prefetch({
      storageId: parsedStorageId.data,
    });

    return {
      props: {
        allegatoId: parsedStorageId.data,
        trpcState: helper.trpc.dehydrate(),
      },
    };
  }
  return {
    redirect: {
      destination: "/500",
      permanent: false,
    },
  };
}) satisfies GetServerSideProps<AllegatoViewProps>;

export default AllegatoView;

const RinominaDialog = ({
  allegatoId,
  filename,
}: {
  allegatoId: StorageindexId;
  filename: string | null;
}) => {
  const { t } = useTranslation();
  const utils = api.useUtils();
  const [editOpen, setEditOpen] = useState(false);

  const { mutate: renameFile } = api.storage.renameFile.useMutation({
    onMutate: () => {
      setEditOpen(false);
      const toastId = toast.loading(t.caricamento, {
        icon: "🪛",
      });
      return { toastId };
    },
    onSuccess: async (_error, _variables, context) => {
      await utils.storage.getStorageFromId.invalidate({
        storageId: allegatoId,
      });
      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: allegatoId,
      name: formData.get("filename") as string,
    });
  };
  return (
    <Dialog open={editOpen} onOpenChange={setEditOpen}>
      <DialogTrigger asChild>
        <Button
          variant="info"
          onClick={() => console.log("rinomina")}
          className="flex gap-2"
        >
          <Pen size={16} />
          Rinomina
        </Button>
      </DialogTrigger>
      <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={filename || undefined}
              minLength={5}
            />
            <Button type="submit">{t.salva}</Button>
          </div>
        </form>
      </DialogContent>
    </Dialog>
  );
};
