"use client";
import React, { useState } from "react";
import { useRouter } from "next/navigation";
import { useTranslations } from "next-intl";
import { Ellipsis, Trash2 } from "lucide-react";
import {
    Dataset,
    DatasetFilters,
    DatasetAction,
    DatasetCol,
    DatasetActionBar,
    DatasetTable,
    DatasetToolbar
} from "@/components/ui/dataset";
import {
    DropdownMenu,
    DropdownMenuItem,
    DropdownMenuTrigger,
    DropdownMenuContent,
    DropdownMenuShortcut,
    DropdownMenuSeparator
} from "@/components/ui/dropdown-menu";
import { DeleteDialog } from "@/components/dashboard/delete-dialog";
import { Button } from "@/components/ui/button";
import { MediaPreview } from "@/components/dashboard/media/media-preview";
import { MediaTableToolbarActions } from "./media-table-toolbar-actions";
import { Tooltip, TooltipTrigger, TooltipContent } from "@/components/ui/tooltip";
import { useQueryStates } from "@/lib/hooks/use-query-states";
import formatDate from "@/lib/utils/format-date";
import { api } from "@/lib/trpc/client";
import type { AppRouterOutput } from "@/server/trpc/types";
import { MediaListQuerySchema } from "@/server/modules/media/media.validators";
import { cn } from "@/lib/utils/cn";

type MediaItem = NonNullable<AppRouterOutput["media"]["get"]>;

export const MediaList: React.FC = () => {
    const router = useRouter();
    const t = useTranslations();
    const [params, setParams] = useQueryStates(MediaListQuerySchema, {
        history: "replace",
        scroll: false,
        shallow: true,
        clearOnDefault: true
    });
    const [toDelete, setToDelete] = useState<MediaItem[]>([]),
          [view, setView] = useState<"table" | "grid">("table");

    const utils = api.useUtils();
    const { data: total = 0 } = api.media.count.useQuery({
        search: params.search || undefined
    });

    const { data: media = [] } = api.media.list.useQuery({
        with: ["user"],
        search: params.search || undefined,
        offset: params.perPage * params.page,
        limit: params.perPage,
        orderBy: params.orderBy,
        orderDir: params.orderDir
    }, {
        placeholderData: (prev) => prev
    });

    const deleteManyMutation = api.media.deleteMany.useMutation({
        onSuccess: async () => {
            setToDelete([]);

            await Promise.all([
                utils.media.list.invalidate(),
                utils.media.count.invalidate()
            ]);
        }
    });

    return (
        <Dataset<MediaItem>
          selection
          view={view}
          data={media}
          total={total}
          page={params.page}
          perPage={params.perPage}
          orderBy={params.orderBy}
          orderDir={params.orderDir}
          onPerPageChange={(perPage) => setParams({ perPage })}
          onPageChange={(page) => setParams({ page })}
          onOrderByChange={(orderBy) => setParams({ orderBy })}
          onOrderDirChange={(orderDir) => setParams({ orderDir })}>
            <DatasetToolbar>
                <DatasetFilters
                  search
                  filters={params}
                  onChange={(filters) => setParams({ ...filters, page: 0 })}>
                </DatasetFilters>

                <MediaTableToolbarActions
                  view={view}
                  onViewChange={setView} />
            </DatasetToolbar>

            <DatasetTable>
                <DatasetCol<MediaItem, "url">
                  label={t("dashboard.media.list.fields.preview.label")}
                  name="url"
                  render={(url, media) => {
                    if(view === "grid") {
                        return (
                            <MediaPreview
                              size="100%"
                              originalName={media.originalName}
                              mimeType={media.mimeType}
                              alt={media.alt || ""}
                              author={media.author || ""}
                              caption={media.caption || ""}
                              url={url} />
                        );
                    }

                    return (
                        <Tooltip>
                            <TooltipTrigger>
                                <MediaPreview
                                  size={25}
                                  mimeType={media.mimeType}
                                  url={url} />
                            </TooltipTrigger>

                            <TooltipContent>
                                <MediaPreview
                                  originalName={media.originalName}
                                  mimeType={media.mimeType}
                                  alt={media.alt || ""}
                                  author={media.author || ""}
                                  caption={media.caption || ""}
                                  url={url} />
                            </TooltipContent>
                        </Tooltip>
                    );
                  }} />

                {view === "table" && (
                    <DatasetCol<MediaItem, "originalName">
                      enableSorting
                      label={t("dashboard.media.list.fields.name.label")}
                      name="originalName"
                      render={name => name} />
                )}

                {view === "table" && (
                    <DatasetCol<MediaItem, "author">
                      enableSorting
                      label={t("dashboard.media.list.fields.author.label")}
                      name="author"
                      render={author => author} />
                )}

                {view === "table" && (
                    <DatasetCol<MediaItem, "alt">
                      enableSorting
                      label={t("dashboard.media.list.fields.alt.label")}
                      name="alt"
                      render={alt => alt} />
                )}

                {view === "table" && (
                    <DatasetCol<MediaItem, "caption">
                      label={t("dashboard.media.list.fields.caption.label")}
                      name="caption"
                      render={caption => caption} />
                )}

                {view === "table" && (
                    <DatasetCol<MediaItem>
                      label={t("dashboard.media.list.fields.user.label")}
                      name="userId"
                      render={(_, media) => {
                        if(!media.user) {
                            return null;
                        }

                        return (
                            <React.Fragment>
                                {media.user.name}
                            </React.Fragment>
                        );
                      }} />
                )}

                {view === "table" && (
                    <DatasetCol<MediaItem, "createdAt">
                      enableSorting
                      label={t("dashboard.media.list.fields.createdAt.label")}
                      name="createdAt"
                      render={createdAt => formatDate(createdAt)} />
                )}

                <DatasetCol<MediaItem, "id">
                  label=""
                  name="id"
                  render={(id, media) => {
                    return (
                        <DropdownMenu>
                            <DropdownMenuTrigger
                              asChild
                              className={cn({ "absolute top-1 right-1 z-1": view === "grid" })}>
                                <Button
                                  className="data-[state=open]:bg-muted flex size-8 p-0"
                                  variant="ghost"
                                  aria-label="Open menu">
                                    <Ellipsis className="size-4" aria-hidden="true" />
                                </Button>
                            </DropdownMenuTrigger>

                            <DropdownMenuContent>
                                <DropdownMenuItem
                                  onClick={() => router.push(`/dashboard/media/${id}`)}>
                                    {t("dashboard.general.actions.edit")}
                                </DropdownMenuItem>

                                <DropdownMenuSeparator />

                                <DropdownMenuItem
                                  variant="destructive"
                                  onClick={() => setToDelete([media])}>
                                    {t("dashboard.general.actions.delete")}

                                    <DropdownMenuShortcut>⌘⌫</DropdownMenuShortcut>
                                </DropdownMenuItem>
                            </DropdownMenuContent>
                        </DropdownMenu>
                    );
                  }} />
            </DatasetTable>

            <DatasetActionBar>
                <DatasetAction<MediaItem>
                  size="icon"
                  variant="destructive"
                  onClick={(rows) => setToDelete(rows.map(r => r.original))}>
                    <Trash2 />
                </DatasetAction>
            </DatasetActionBar>

            <DeleteDialog
              open={toDelete.length > 0}
              pending={deleteManyMutation.isPending}
              onConfirm={() => {
                deleteManyMutation.mutate(
                    toDelete.map((m) => m.id)
                );
              }}
              onCancel={() => setToDelete([])} />
        </Dataset>
    );
};
