"use client";
import React, { useState, useRef } from "react";
import { useLocale, useTranslations } from "next-intl";
import { Ellipsis, Plus, Trash2 } from "lucide-react";
import {
    Dataset,
    DatasetTable,
    DatasetCol,
    DatasetFilters,
    DatasetToolbar,
    DatasetActionBar,
    DatasetAction
} from "@/components/ui/dataset";
import {
    DropdownMenu,
    DropdownMenuContent,
    DropdownMenuItem,
    DropdownMenuSeparator,
    DropdownMenuShortcut,
    DropdownMenuTrigger
} from "@/components/ui/dropdown-menu";
import { Button } from "@/components/ui/button";
import { Badge } from "@/components/ui/badge";
import { api } from "@/lib/trpc/client";
import { useQueryStates } from "@/lib/hooks/use-query-states";
import type { AppRouterOutput } from "@/lib/trpc/router";
import { TagListQueryValidator } from "@/server/modules/tag/validators/tag-list-query.validator";
import formatDate from "@/lib/utils/format-date";
import { DeleteDialog } from "@/components/dashboard/delete-dialog";
import { TagModalEditor, TagModalEditorRef } from "@/components/dashboard/tag/tag-modal-editor";

type Tag = NonNullable<AppRouterOutput["tags"]["get"]>;

export const TagList: React.FC = () => {
    const locale = useLocale();
    const t = useTranslations("dashboard.tag");
    const [toDelete, setToDelete] = useState<Tag[]>([]);
    const [params, setParams] = useQueryStates(TagListQueryValidator, {
        history: "replace",
        scroll: false,
        shallow: true,
        clearOnDefault: true
    });

    const editorRef = useRef<TagModalEditorRef>(null);

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

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

    const { data: canDeleteTag } = api.gate.can.useQuery({
        resource: "tag",
        action: "delete-many"
    });

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

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

    return (
        <Dataset
          selection
          total={count}
          data={tags}
          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={setParams}>

                </DatasetFilters>

                <Button
                  variant="outline"
                  size="sm"
                  onClick={() => editorRef.current?.open()}>
                    <Plus className="h-4 w-4" />
                    {t("actions.new")}
                </Button>
            </DatasetToolbar>

            <DatasetTable>
                <DatasetCol
                  enableSorting
                  label={t("list.fields.name.label")}
                  name="name"
                  render={n => n} />

                <DatasetCol
                  enableSorting
                  label={t("list.fields.slug.label")}
                  name="slug"
                  render={(slug) => {
                    return (
                        <div className="max-w-[15rem] truncate font-mono text-sm text-muted-foreground">
                            {slug}
                        </div>
                    );
                  }} />

                <DatasetCol<Tag, "postCount">
                  label={t("list.fields.usage.label")}
                  name="postCount"
                  render={(usageCount) => {
                    if(typeof usageCount === "undefined") {
                        return null;
                    }

                    let variant: "default" | "secondary" | "destructive" | "outline";

                    if(usageCount === 0) variant = "secondary";
                    else if(usageCount <= 5) variant = "outline";
                    else if(usageCount <= 20) variant = "default";
                    else variant = "destructive";

                    return (
                        <Badge className="font-mono" variant={variant}>
                            {usageCount} {usageCount === 1 ? t("list.fields.usage.post") : t("list.fields.usage.posts")}
                        </Badge>
                    );
                  }}
                />

                <DatasetCol
                  enableSorting
                  label={t("list.fields.createdAt.label")}
                  name="createdAt"
                  render={createdAt => formatDate(createdAt, { locale, day: "numeric", month: "long", year: "numeric" })} />

                <DatasetCol<Tag, "id">
                  label=""
                  name="id"
                  render={(_, tag) => {
                    return (
                        <DropdownMenu>
                            <DropdownMenuTrigger asChild>
                                <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={() => setToEdit(tag)}
                                  onClick={() => {
                                    editorRef.current?.open(tag)
                                  }}>
                                    {t("actions.edit")}
                                </DropdownMenuItem>

                                {canDeleteTag && (
                                  <>
                                    <DropdownMenuSeparator />
                                    <DropdownMenuItem
                                      variant="destructive"
                                      onSelect={() => setToDelete([tag])}>
                                        {t("actions.delete")}
                                        <DropdownMenuShortcut>⌘⌫</DropdownMenuShortcut>
                                    </DropdownMenuItem>
                                  </>
                                )}
                            </DropdownMenuContent>
                        </DropdownMenu>
                    );
                  }} />
            </DatasetTable>

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

            <TagModalEditor ref={editorRef} />

            <DeleteDialog
              open={toDelete.length > 0}
              pending={deleteManyMutation.isPending}
              onConfirm={async () => {
                await deleteManyMutation.mutateAsync({
                    ids: toDelete.map(t => t.id)
                });
              }}
              onCancel={() => setToDelete([])} />
        </Dataset>
    );
};
