﻿"use client";

import * as DropdownMenu from "@radix-ui/react-dropdown-menu";
import { useRouter, usePathname } from "next/navigation";
import { useSortable, SortableContext, verticalListSortingStrategy } from "@dnd-kit/sortable";
import { CSS } from "@dnd-kit/utilities";
import {
    ChevronRight,
    FileText,
    Folder,
    FolderOpen,
    MoreHorizontal,
    Trash2,
    FilePlus,
    FolderPlus,
    Download,
    Upload,
} from "lucide-react";

import { Page, useEditorStore } from "@/lib/store";
import { cn } from "@/lib/utils";
import { exportPageAsMarkdown, exportFolderAsZip } from "@/lib/export";
import { useImport } from "@/components/import-context";
import { useConfirm } from "@/components/confirm-provider";

interface TreeViewProps {
    pages: Page[];
    parentId: string | null;
    expanded: Record<string, boolean>;
    toggleExpand: (id: string) => void;
    level?: number;
    folderFileCount: Record<string, number>;
}

function buildFolderFileCount(pages: Page[]): Record<string, number> {
    const byParent = new Map<string | null, Page[]>();
    for (const page of pages) {
        const siblings = byParent.get(page.parentId) || [];
        siblings.push(page);
        byParent.set(page.parentId, siblings);
    }

    const counts: Record<string, number> = {};

    const dfs = (folderId: string): number => {
        const children = byParent.get(folderId) || [];
        let total = 0;
        for (const child of children) {
            if (child.type === "file") {
                total += 1;
            } else {
                total += dfs(child.id);
            }
        }
        counts[folderId] = total;
        return total;
    };

    for (const page of pages) {
        if (page.type === "folder") {
            dfs(page.id);
        }
    }

    return counts;
}

function TreeNode({
    node,
    pages,
    level,
    expanded,
    toggleExpand,
    folderFileCount,
}: {
    node: Page;
    pages: Page[];
    level: number;
    expanded: Record<string, boolean>;
    toggleExpand: (id: string) => void;
    folderFileCount: Record<string, number>;
}) {
    const { activePageId, setActivePageId, addPage, deletePage } = useEditorStore();
    const router = useRouter();
    const pathname = usePathname();
    const { triggerImport } = useImport();
    const confirm = useConfirm();

    const isFolder = node.type === "folder";
    const hasChildren = pages.some((p) => p.parentId === node.id);
    const isExpanded = expanded[node.id];
    const isActive = activePageId === node.id;

    const { attributes, listeners, setNodeRef, transform, transition, isDragging } = useSortable({
        id: node.id,
        data: { type: node.type, title: node.title, parentId: node.parentId },
    });

    const style = {
        paddingLeft: `${level * 12 + 6}px`,
        transform: CSS.Translate.toString(transform),
        transition,
        opacity: isDragging ? 0.5 : 1,
    };

    return (
        <div key={node.id} style={style} ref={setNodeRef} {...attributes} {...listeners}>
            <div
                className={cn(
                    "sidebar-tree-item group relative flex h-10 items-center justify-between rounded-lg border border-transparent px-1.5 text-[14px] transition-colors cursor-pointer select-none md:h-9 md:text-[13px]",
                    isActive
                        ? "border-border/60 bg-accent/75 text-accent-foreground"
                        : "text-foreground/85 hover:border-border/45 hover:bg-muted/55 hover:text-foreground"
                )}
                onClick={() => {
                    setActivePageId(node.id);
                    if (pathname !== "/") router.push("/");
                }}
            >
                {isActive && <span className="absolute left-0 top-[8px] h-5 w-0.5 rounded-r bg-primary/90" />}

                <div className="grid min-w-0 flex-1 grid-cols-[1.75rem_1.25rem_minmax(0,1fr)] items-center gap-1.5">
                    <button
                        onPointerDown={(e) => e.stopPropagation()}
                        onClick={(e) => {
                            e.stopPropagation();
                            toggleExpand(node.id);
                        }}
                        className={cn(
                            "flex h-9 w-9 items-center justify-center rounded-md text-muted-foreground/80 transition-colors hover:bg-muted-foreground/15 hover:text-foreground md:h-8 md:w-8",
                            !hasChildren && !isFolder && "invisible"
                        )}
                    >
                        <ChevronRight size={14} className={cn("shrink-0 text-muted-foreground/60 transition-transform", isExpanded && "rotate-90")} />
                    </button>
                    <span className="flex h-5 w-5 items-center justify-center">
                        {node.icon ? (
                            <span className="flex h-5 w-5 items-center justify-center text-[16px] leading-none grayscale-[0.2]">{node.icon}</span>
                        ) : isFolder ? (
                            isExpanded ? (
                                <FolderOpen size={15} className="fill-indigo-500/20 text-indigo-500" />
                            ) : (
                                <Folder size={15} className="fill-indigo-500/20 text-indigo-500" />
                            )
                        ) : (
                            <FileText size={15} className="text-muted-foreground/70" />
                        )}
                    </span>
                    <span className="flex min-w-0 items-center gap-1.5">
                        <span
                            className={cn(
                                "sidebar-title",
                                level === 0 ? "text-[15px] font-semibold md:text-[14px]" : "text-[14px] md:text-[13px]"
                            )}
                        >
                            {node.title || "无标题"}
                        </span>
                        {isFolder && (
                            <span className="inline-flex min-w-[1.2rem] shrink-0 items-center justify-center rounded-full bg-muted px-1.5 py-0.5 text-[10px] font-medium text-muted-foreground">
                                {folderFileCount[node.id] ?? 0}
                            </span>
                        )}
                    </span>
                </div>

                <DropdownMenu.Root>
                    <DropdownMenu.Trigger asChild>
                        <button
                            onPointerDown={(e) => e.stopPropagation()}
                            className="flex h-9 w-9 items-center justify-center rounded-md text-muted-foreground/85 transition-opacity hover:bg-muted-foreground/15 hover:text-foreground opacity-100 md:h-8 md:w-8 lg:opacity-0 lg:group-hover:opacity-100"
                        >
                            <MoreHorizontal size={13} />
                        </button>
                    </DropdownMenu.Trigger>
                    <DropdownMenu.Portal>
                        <DropdownMenu.Content className="ui-card z-50 min-w-[160px] p-1.5 shadow-xl animate-in fade-in zoom-in-95" align="start" sideOffset={6}>
                            <DropdownMenu.Item
                                className="flex cursor-pointer items-center gap-2 rounded-md px-2 py-1.5 text-sm outline-none transition-colors hover:bg-accent"
                                onClick={(e) => {
                                    e.stopPropagation();
                                    const targetParentId = node.type === "folder" ? node.id : node.parentId;
                                    const order = node.type === "folder" ? undefined : (node.order || 0) + 1;
                                    addPage(targetParentId, "file", undefined, order);
                                    if (node.type === "folder") toggleExpand(node.id);
                                }}
                            >
                                <FilePlus size={14} />
                                <span>新建文件</span>
                            </DropdownMenu.Item>
                            <DropdownMenu.Item
                                className="flex cursor-pointer items-center gap-2 rounded-md px-2 py-1.5 text-sm outline-none transition-colors hover:bg-accent"
                                onClick={(e) => {
                                    e.stopPropagation();
                                    const targetParentId = node.type === "folder" ? node.id : node.parentId;
                                    const order = node.type === "folder" ? undefined : (node.order || 0) + 1;
                                    addPage(targetParentId, "folder", undefined, order);
                                    if (node.type === "folder") toggleExpand(node.id);
                                }}
                            >
                                <FolderPlus size={14} />
                                <span>新建文件夹</span>
                            </DropdownMenu.Item>
                            <DropdownMenu.Item
                                className="flex cursor-pointer items-center gap-2 rounded-md px-2 py-1.5 text-sm outline-none transition-colors hover:bg-accent"
                                onClick={(e) => {
                                    e.stopPropagation();
                                    const targetParentId = node.type === "folder" ? node.id : node.parentId;
                                    triggerImport(targetParentId);
                                    if (node.type === "folder") toggleExpand(node.id);
                                }}
                            >
                                <Upload size={14} />
                                <span>导入文档...</span>
                            </DropdownMenu.Item>
                            <DropdownMenu.Item
                                className="flex cursor-pointer items-center gap-2 rounded-md px-2 py-1.5 text-sm outline-none transition-colors hover:bg-accent"
                                onClick={(e) => {
                                    e.stopPropagation();
                                    if (node.type === "folder") {
                                        exportFolderAsZip(node.id, pages, node.title);
                                    } else {
                                        exportPageAsMarkdown(node);
                                    }
                                }}
                            >
                                <Download size={14} />
                                <span>导出</span>
                            </DropdownMenu.Item>
                            <DropdownMenu.Separator className="my-1 h-px bg-muted" />
                            <DropdownMenu.Item
                                className="flex cursor-pointer items-center gap-2 rounded-md px-2 py-1.5 text-sm text-destructive outline-none transition-colors hover:bg-destructive/10"
                                onClick={async (e) => {
                                    e.stopPropagation();
                                    const ok = await confirm({
                                        title: "确认删除",
                                        description: "此操作无法撤销。",
                                        confirmText: "删除",
                                        cancelText: "取消",
                                        tone: "danger",
                                    });
                                    if (ok) {
                                        deletePage(node.id);
                                    }
                                }}
                            >
                                <Trash2 size={14} />
                                <span>删除</span>
                            </DropdownMenu.Item>
                        </DropdownMenu.Content>
                    </DropdownMenu.Portal>
                </DropdownMenu.Root>
            </div>

            {(isExpanded || hasChildren) && isExpanded && (
                <TreeView
                    pages={pages}
                    parentId={node.id}
                    level={level + 1}
                    expanded={expanded}
                    toggleExpand={toggleExpand}
                    folderFileCount={folderFileCount}
                />
            )}
        </div>
    );
}

export function TreeView({ pages, parentId, expanded, toggleExpand, level = 0, folderFileCount }: TreeViewProps) {
    const computedFolderFileCount = level === 0 ? buildFolderFileCount(pages) : folderFileCount;
    const nodes = pages
        .filter((p) => p.parentId === parentId)
        .sort((a, b) => (a.order || 0) - (b.order || 0));

    if (nodes.length === 0) return null;

    return (
        <SortableContext items={nodes.map((n) => n.id)} strategy={verticalListSortingStrategy}>
            <div className="flex flex-col gap-0 md:gap-0.5">
                {nodes.map((node) => (
                    <TreeNode
                        key={node.id}
                        node={node}
                        pages={pages}
                        level={level}
                        expanded={expanded}
                        toggleExpand={toggleExpand}
                        folderFileCount={computedFolderFileCount}
                    />
                ))}
            </div>
        </SortableContext>
    );
}
