"use client";
import React, { useState } from "react";
import { useTranslations, useLocale } from "next-intl";
import { Ellipsis, Plus, Trash2 } from "lucide-react";
import Link from "next/link";
import { DeleteDialog } from "@/components/dashboard/delete-dialog";
import { CheckboxControl } from "@/components/form/control/checkbox.control";
import { SelectControl } from "@/components/form/control/select.control";
import {
    Dataset,
    DatasetCol,
    DatasetToolbar,
    DatasetFilters,
    DatasetTable,
    DatasetActionBar,
    DatasetAction
} from "@/components/ui/dataset";
import { SelectValue, SelectTrigger, SelectContent, SelectItem } from "@/components/ui/select";
import { Badge } from "@/components/ui/badge";
import { Button } from "@/components/ui/button";
import {
    DropdownMenu,
    DropdownMenuItem,
    DropdownMenuTrigger,
    DropdownMenuContent,
    DropdownMenuShortcut,
    DropdownMenuSeparator
} from "@/components/ui/dropdown-menu";
import { PostGuestLinkDialog } from "@/components/dashboard/post/post-guest-link-dialog";
import { ButtonGroup } from "@/components/ui/button-group";
import { api } from "@/lib/trpc/client";
import type { AppRouterOutput } from "@/lib/trpc/router";
import formatDate from "@/lib/utils/format-date";
import { useQueryStates } from "@/lib/hooks/use-query-states";
import { PostListQueryValidator } from "@/server/modules/post/validators/post-list-query.validator";
import { PostType, PostTypeHelpers, PostStatusEnum, PostStatusHelpers, PostOrderEnum } from "@/config/enums";
import { Routes } from "@/config/routes";

type Post = NonNullable<AppRouterOutput["posts"]["get"]>;

export const PostList: React.FC = () => {
    const [params, setParams] = useQueryStates(PostListQueryValidator, {
        history: "replace",
        scroll: false,
        shallow: true,
        clearOnDefault: true
    });
    const t = useTranslations();
    const locale = useLocale();
    const [gPost, setGPost] = useState<Post | null>(null),
        [toDelete, setToDelete] = useState<Post[]>([]);

    const utils = api.useUtils();
    const { data: total = 0 } = api.posts.count.useQuery({
        access: "dashboard",
        search: params.search || undefined,
        topic: params.topic || undefined,
        status: params.status || undefined,
        isPinned: typeof params.isPinned === "boolean" ? params.isPinned : undefined
    });

    const { data: posts = [] } = api.posts.list.useQuery(
        {
            access: "dashboard",
            search: params.search || undefined,
            topic: params.topic || undefined,
            status: params.status || undefined,
            isPinned: typeof params.isPinned === "boolean" ? params.isPinned : undefined,
            offset: params.perPage * params.page,
            limit: params.perPage,
            orderBy: params.orderBy,
            orderDir: params.orderDir
        },
        {
            placeholderData: (prev) => prev
        }
    );

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

    const deleteManyMutation = api.posts.deleteMany.useMutation({
        async onSuccess() {
            await Promise.all([utils.posts.list.invalidate(), utils.posts.count.invalidate()]);
            setToDelete([]);
        }
    });

    return (
        <Dataset<Post>
            data={posts}
            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: orderBy as PostOrderEnum })}
            onOrderDirChange={(orderDir) => setParams({ orderDir })}
        >
            <DatasetToolbar>
                <DatasetFilters search filters={params} onChange={setParams}>
                    <SelectControl name="topic">
                        <SelectTrigger className="w-full">
                            <SelectValue placeholder={t("dashboard.post.list.filters.type.placeholder")} />
                        </SelectTrigger>

                        <SelectContent>
                            {PostTypeHelpers.values().map((type) => {
                                return (
                                    <SelectItem key={type} value={type}>
                                        {PostTypeHelpers.translate(t, type)}
                                    </SelectItem>
                                );
                            })}
                        </SelectContent>
                    </SelectControl>

                    <SelectControl name="status">
                        <SelectTrigger className="w-full">
                            <SelectValue placeholder={t("dashboard.post.list.filters.status.placeholder")} />
                        </SelectTrigger>

                        <SelectContent>
                            {PostStatusHelpers.values().map((status) => {
                                const Icon = PostStatusHelpers.getIcon(status);

                                return (
                                    <SelectItem key={status} value={status}>
                                        <Icon className="mr-1 inline-block" />
                                        {PostStatusHelpers.translate(t, status)}
                                    </SelectItem>
                                );
                            })}
                        </SelectContent>
                    </SelectControl>

                    <CheckboxControl label={t("dashboard.post.list.fields.isPinned.label")} name="isPinned" />
                </DatasetFilters>

                <Button variant="outline" size="sm" asChild>
                    <Link href={Routes.DASHBOARD.POST_CREATE}>
                        <Plus className="h-4 w-4" />
                        {t("dashboard.post.actions.new")}
                    </Link>
                </Button>
            </DatasetToolbar>

            <DatasetTable>
                <DatasetCol<Post, "title">
                    enableSorting
                    label={t("dashboard.post.list.fields.title.label")}
                    name="title"
                    render={(title, post) => {
                        const isPublished = post.status === PostStatusEnum.PUBLISHED;

                        return (
                            <Link
                                className="hover:text-primary flex items-center gap-1 hover:underline"
                                href={
                                    isPublished
                                        ? Routes.POST(post.topic, post.slug)
                                        : Routes.DASHBOARD.POST_EDIT(post.slug)
                                }
                            >
                                {title}
                            </Link>
                        );
                    }}
                />

                <DatasetCol<Post, "status">
                    enableSorting
                    label={t("dashboard.post.list.fields.status.label")}
                    name="status"
                    render={(status) => {
                        if (!status) {
                            return null;
                        }

                        const Icon = PostStatusHelpers.getIcon(status);

                        return (
                            <Badge variant="outline" className="py-1 [&>svg]:size-3.5">
                                <Icon />

                                <span className="capitalize">{PostStatusHelpers.translate(t, status)}</span>
                            </Badge>
                        );
                    }}
                />

                <DatasetCol<Post, "topic">
                    enableSorting
                    label={t("dashboard.post.list.fields.type.label")}
                    name="topic"
                    render={(type) => {
                        if (!type) {
                            return null;
                        }

                        return (
                            <Badge variant="outline" className="py-1">
                                <span className="capitalize">{PostTypeHelpers.translate(t, type)}</span>
                            </Badge>
                        );
                    }}
                />

                <DatasetCol<Post, "publishedAt">
                    enableSorting
                    label={t("dashboard.post.list.fields.publishedAt.label")}
                    name="publishedAt"
                    render={(publishedAt) => {
                        return formatDate(publishedAt, {
                            locale,
                            year: "numeric",
                            month: "long",
                            day: "numeric"
                        });
                    }}
                />

                <DatasetCol<Post, "isPinned">
                    enableSorting
                    label={t("dashboard.post.list.fields.isPinned.label")}
                    name="isPinned"
                    render={(sticky) => {
                        return sticky ? t("general.yes") : t("general.no");
                    }}
                />

                <DatasetCol<Post, "id">
                    label=""
                    name="id"
                    render={(_, post) => {
                        return (
                            <ButtonGroup>
                                <Button variant="outline" size="sm" asChild>
                                    <Link href={Routes.DASHBOARD.POST_EDIT(post.slug)}>
                                        {t("dashboard.general.actions.edit")}
                                    </Link>
                                </Button>
                                <DropdownMenu>
                                    <DropdownMenuTrigger asChild>
                                        <Button
                                            className="data-[state=open]:bg-muted flex size-8 p-0"
                                            variant="outline"
                                            size="sm"
                                            aria-label={t("dashboard.post.list.actions.openMenu")}
                                        >
                                            <Ellipsis className="size-4" aria-hidden="true" />
                                        </Button>
                                    </DropdownMenuTrigger>

                                    <DropdownMenuContent className="w-40" align="end">
                                        {post.topic === PostType.KBHPLUS && (
                                            <DropdownMenuItem onClick={() => setGPost(post)}>
                                                {t("dashboard.post.actions.generateGuestLink")}
                                            </DropdownMenuItem>
                                        )}

                                        <DropdownMenuItem asChild>
                                            <Link href={Routes.DASHBOARD.POST_EDIT(post.slug)}>
                                                {t("dashboard.post.actions.comments")}
                                            </Link>
                                        </DropdownMenuItem>

                                        {canDeletePost && (
                                            <>
                                                <DropdownMenuSeparator />

                                                <DropdownMenuItem
                                                    variant="destructive"
                                                    onSelect={() => setToDelete([post])}
                                                >
                                                    {t("dashboard.general.actions.delete")}
                                                    <DropdownMenuShortcut>⌘⌫</DropdownMenuShortcut>
                                                </DropdownMenuItem>
                                            </>
                                        )}
                                    </DropdownMenuContent>
                                </DropdownMenu>
                            </ButtonGroup>
                        );
                    }}
                />
            </DatasetTable>

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

            <PostGuestLinkDialog post={gPost} onClose={() => setGPost(null)} />

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