"use client";

import { useCallback, useMemo, useState } from "react";
import { useQuery } from "@tanstack/react-query";
import { Search } from "lucide-react";
import { TreePickerSurface } from "@/components/sidebar/tree-shell-surface";
import { Dialog, DialogContent, DialogTitle } from "@/components/ui/dialog";
import { Input } from "@/components/ui/input";
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs";
import type { SidebarInitialData } from "@/components/sidebar/types";
import { getMnoteRuntimeConfig } from "@/lib/runtime-config";
import { buildPageTreeProjectionItems, buildPickerTreeItems } from "@/lib/tree-projection";
import { useDocumentSearch } from "@/hooks/use-document-search";
import type { DocumentSearchFilters, DocumentSearchResult } from "@/types/search";

export type MoveEmbedMode = "move" | "embed";

const DEFAULT_FILTERS: DocumentSearchFilters = {
  titleOnly: true,
  exact: false,
  onlyCurrentPage: false,
  includeOcr: false,
  timeRange: "any",
  timeField: "updated",
};

type PickerItem =
  | { kind: "root"; id: null; title: string; subtitle?: string }
  | { kind: "doc"; id: string; title: string; subtitle?: string; depth?: number; raw?: DocumentSearchResult };

async function fetchSidebarData(workspaceId: string): Promise<SidebarInitialData> {
  const response = await fetch(`/api/sidebar?workspaceId=${encodeURIComponent(workspaceId)}`, {
    method: "GET",
    credentials: "include",
  });

  if (!response.ok) {
    const payload = await response.json().catch(() => ({}));
    const message = payload?.error ?? "获取页面列表失败";
    throw new Error(message);
  }

  return response.json();
}

interface MoveEmbedPickerDialogProps {
  open: boolean;
  onOpenChange: (open: boolean) => void;
  workspaceId: string | null;
  defaultMode?: MoveEmbedMode;
  modes?: MoveEmbedMode[];
  allowRoot?: boolean;
  excludeIds?: string[];
  onPick: (mode: MoveEmbedMode, targetId: string | null) => void | Promise<void>;
}

export function MoveEmbedPickerDialog({
  open,
  onOpenChange,
  workspaceId,
  defaultMode = "move",
  modes = ["move", "embed"],
  allowRoot = true,
  excludeIds = [],
  onPick,
}: MoveEmbedPickerDialogProps) {
  return (
    <Dialog open={open} onOpenChange={onOpenChange}>
      <DialogContent className="max-h-[90vh] w-full max-w-md overflow-hidden border-none bg-white p-0 shadow-xl">
        <DialogTitle className="sr-only">选择目标页面</DialogTitle>
        {open ? (
          <MoveEmbedPickerDialogBody
            onOpenChange={onOpenChange}
            workspaceId={workspaceId}
            defaultMode={defaultMode}
            modes={modes}
            allowRoot={allowRoot}
            excludeIds={excludeIds}
            onPick={onPick}
          />
        ) : null}
      </DialogContent>
    </Dialog>
  );
}

interface MoveEmbedPickerDialogBodyProps {
  onOpenChange: (open: boolean) => void;
  workspaceId: string | null;
  defaultMode: MoveEmbedMode;
  modes: MoveEmbedMode[];
  allowRoot: boolean;
  excludeIds: string[];
  onPick: (mode: MoveEmbedMode, targetId: string | null) => void | Promise<void>;
}

function MoveEmbedPickerDialogBody({
  onOpenChange,
  workspaceId,
  defaultMode,
  modes,
  allowRoot,
  excludeIds,
  onPick,
}: MoveEmbedPickerDialogBodyProps) {
  const [mode, setMode] = useState<MoveEmbedMode>(defaultMode);
  const [query, setQuery] = useState("");
  const [highlighted, setHighlighted] = useState(0);
  const treeRendererFamily = getMnoteRuntimeConfig().treeRendererFamily ?? "react";

  const handleModeChange = useCallback((value: string) => {
    setMode(value as MoveEmbedMode);
    setQuery("");
    setHighlighted(0);
  }, []);

  const handleQueryChange = useCallback((value: string) => {
    setQuery(value);
    setHighlighted(0);
  }, []);

  const payload = useMemo(() => {
    if (!workspaceId) return null;
    return {
      workspaceId,
      query,
      filters: DEFAULT_FILTERS,
      limit: 30,
    };
  }, [query, workspaceId]);

  const trimmed = query.trim();
  const isEmptyQuery = trimmed.length === 0;

  const sidebarQuery = useQuery({
    queryKey: ["move-embed-picker-sidebar", workspaceId],
    queryFn: () => {
      if (!workspaceId) {
        throw new Error("缺少 workspaceId");
      }
      return fetchSidebarData(workspaceId);
    },
    enabled: Boolean(workspaceId) && isEmptyQuery,
    staleTime: 30_000,
    gcTime: 60_000,
  });

  const { data, isLoading, error } = useDocumentSearch(payload, Boolean(payload) && !isEmptyQuery);

  const items = useMemo<PickerItem[]>(() => {
    const excluded = new Set(excludeIds);

    const result: PickerItem[] = [];

    if (allowRoot && mode === "move") {
      result.push({ kind: "root", id: null, title: "根目录", subtitle: "移动到工作空间根目录" });
    }

    if (isEmptyQuery) {
      const tree = sidebarQuery.data?.kernelSidebarTree ?? [];
      const flattened = buildPickerTreeItems(
        buildPageTreeProjectionItems(tree),
        excluded,
      );

      for (const item of flattened) {
        if (excluded.has(item.id)) continue;
        result.push({
          kind: "doc",
          id: item.id,
          title: item.title,
          depth: item.depth,
        });
      }

      return result;
    }

    const rawList = data?.results?.length ? data?.results : data?.recent ?? [];
    for (const r of rawList) {
      if (!r || excluded.has(r.id)) continue;
      result.push({
        kind: "doc",
        id: r.id,
        title: r.title || "无标题",
        subtitle: r.matchField === "recent" ? "最近打开" : undefined,
        raw: r,
      });
    }

    return result;
  }, [allowRoot, data?.recent, data?.results, excludeIds, isEmptyQuery, mode, sidebarQuery.data?.kernelSidebarTree]);

  const placeholder = mode === "move" ? "移动到..." : "嵌入到...";
  const handlePick = useCallback(
    async (targetId: string | null) => {
      await onPick(mode, targetId);
      onOpenChange(false);
    },
    [mode, onOpenChange, onPick],
  );
  const pickerFallback = (
    sidebarQuery.isLoading ? (
      <div className="p-4 text-sm text-gray-400">加载中...</div>
    ) : sidebarQuery.error ? (
      <div className="p-4 text-sm text-red-600">{String(sidebarQuery.error)}</div>
    ) : items.length === 0 ? (
      <div className="p-4 text-sm text-gray-400">没有匹配结果</div>
    ) : (
      <TreePickerSurface
        rendererFamily={treeRendererFamily}
        workspaceId={workspaceId}
        treeShellEnabled={isEmptyQuery}
        allowRootPick={allowRoot && mode === "move"}
        excludeIds={excludeIds}
        items={items}
        highlighted={highlighted}
        onHighlight={setHighlighted}
        onPick={(targetId) => {
          void handlePick(targetId);
        }}
      />
    )
  );

  return (
    <div className="flex h-[520px] flex-col">
      <div className="border-b border-[#eef2ff] p-4">
        <Tabs value={mode} onValueChange={handleModeChange}>
          <TabsList className="w-full">
            {modes.includes("move") && (
              <TabsTrigger value="move" className="flex-1">
                移动到
              </TabsTrigger>
            )}
            {modes.includes("embed") && (
              <TabsTrigger value="embed" className="flex-1">
                嵌入到
              </TabsTrigger>
            )}
          </TabsList>
          <TabsContent value={mode} className="mt-4">
            <div className="relative">
              <Search className="pointer-events-none absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-gray-400" />
              <Input
                value={query}
                onChange={(e) => handleQueryChange(e.target.value)}
                placeholder={placeholder}
                className="h-10 rounded-xl border-[#e2e8f0] pl-9 text-sm"
              />
            </div>
          </TabsContent>
        </Tabs>
      </div>

      <div
        className="flex-1 overflow-y-auto"
        onKeyDown={(event) => {
          if (isEmptyQuery) {
            return;
          }
          if (event.key === "ArrowDown") {
            event.preventDefault();
            setHighlighted((prev) => Math.min(items.length - 1, prev + 1));
          } else if (event.key === "ArrowUp") {
            event.preventDefault();
            setHighlighted((prev) => Math.max(0, prev - 1));
          } else if (event.key === "Enter") {
            event.preventDefault();
            const picked = items[highlighted];
            if (!picked) return;
            void handlePick(picked.id);
          }
        }}
      >
        {!workspaceId ? (
          <div className="p-4 text-sm text-gray-500">缺少 workspaceId，无法加载页面列表。</div>
        ) : isEmptyQuery ? (
          <div className="h-full p-3">{pickerFallback}</div>
        ) : isLoading ? (
          <div className="p-4 text-sm text-gray-400">加载中...</div>
        ) : error ? (
          <div className="p-4 text-sm text-red-600">{String(error)}</div>
        ) : items.length === 0 ? (
          <div className="p-4 text-sm text-gray-400">没有匹配结果</div>
        ) : (
          <TreePickerSurface
            rendererFamily={treeRendererFamily}
            workspaceId={workspaceId}
            treeShellEnabled={Boolean(workspaceId)}
            allowRootPick={false}
            excludeIds={excludeIds}
            treeShellItems={items}
            items={items}
            highlighted={highlighted}
            className="py-2"
            onHighlight={setHighlighted}
            onPick={(targetId) => {
              void handlePick(targetId);
            }}
          />
        )}
      </div>
    </div>
  );
}
