﻿"use client";

import { SidebarContent, ResizableSidebar } from "@/components/sidebar";
import { Editor } from "@/components/editor";
import { useEditorStore } from "@/lib/store";
import { Hash, X, Plus, ChevronLeft, ChevronRight, ChevronDown, Sparkles, Lock, Unlock, FolderOpen, History, RotateCcw } from "lucide-react";
import { useSettingsStore } from "@/lib/settings-store";
import { exportPageAsMarkdown } from "@/lib/export";
import { useMemo, useState } from "react";
import { useEffect } from "react";
import { cn, getTagColor } from "@/lib/utils";
import { useSearchStore } from "@/lib/search-store";
import { type Editor as TiptapEditor } from "@tiptap/react";
import { ImportProvider } from "@/components/import-context";
import { AIChatPanel } from "@/components/chat/ai-chat-panel";
import { SearchCommand } from "@/components/search-command";
import { getBacklinks, getOutgoingLinks, getUnresolvedLinkTitles } from "@/lib/wiki-links";
import { getPageHistory } from "@/lib/page-history";

const ICONS = [
  "📄", "📝", "📒", "📘", "📙", "📕", "📗", "📚",
  "💡", "🔥", "✅", "❗", "⭐", "📌", "📎", "🧠",
  "🎯", "🚀", "⚙️", "🧪", "💼", "📊", "📈", "🧩",
  "🌱", "🌟", "🎨", "🎵", "🎬", "📷", "💬", "🔖",
  "⌛", "🗂️", "📦", "🏷️", "🗓️", "🕒", "🔍", "🧾",
];

export default function Home() {
  const { activePageId, pages, pageSync, updatePage, setActivePageId, addPage, retryPageSync, retryPendingSyncs, flushPendingSyncs } = useEditorStore();
  const { openSearchWithTag } = useSearchStore();
  const { timezone } = useSettingsStore();

  const activePage = pages.find((p) => p.id === activePageId);
  const activePageSync = activePageId ? pageSync[activePageId] : undefined;
  const [isChatOpen, setIsChatOpen] = useState(false);
  const [editor, setEditor] = useState<TiptapEditor | null>(null);
  const [isAddingTag, setIsAddingTag] = useState(false);
  const [tagInput, setTagInput] = useState("");
  const [isIconPickerOpen, setIsIconPickerOpen] = useState(false);
  const [isHistoryOpen, setIsHistoryOpen] = useState(false);
  const [selectedHistoryIndex, setSelectedHistoryIndex] = useState(0);

  const breadcrumbs = useMemo(() => {
    if (!activePage) return [];
    const result = [] as typeof pages;
    let current = activePage;
    while (current) {
      result.unshift(current);
      if (!current.parentId) break;
      const parent = pages.find((p) => p.id === current.parentId);
      if (!parent) break;
      current = parent;
    }
    return result;
  }, [activePage, pages]);

  const outgoingLinks = useMemo(() => {
    if (!activePage || activePage.type !== "file") return [];
    return getOutgoingLinks(activePage, pages);
  }, [activePage, pages]);

  const backlinks = useMemo(() => {
    if (!activePage || activePage.type !== "file") return [];
    return getBacklinks(activePage, pages);
  }, [activePage, pages]);

  const unresolvedLinks = useMemo(() => {
    if (!activePage || activePage.type !== "file") return [];
    return getUnresolvedLinkTitles(activePage, pages);
  }, [activePage, pages]);

  const localHistory = useMemo(() => {
    if (!activePage || activePage.type !== "file") return [];
    return getPageHistory(activePage.id);
  }, [activePage]);
  const effectiveHistoryIndex = Math.min(selectedHistoryIndex, Math.max(localHistory.length - 1, 0));

  const addTag = () => {
    if (!activePage) return;
    const next = tagInput.trim();
    if (!next) return;
    const merged = Array.from(new Set([...(activePage.tags || []), next]));
    updatePage(activePage.id, { tags: merged });
    setTagInput("");
    setIsAddingTag(false);
  };

  const handleOpenWikiLink = async (title: string) => {
    const target = pages.find((p) => p.type === "file" && (p.title || "").trim() === title);
    if (target) {
      setActivePageId(target.id);
      return;
    }
    const shouldCreate = window.confirm(`未找到页面“${title}”。是否立即创建？`);
    if (!shouldCreate) return;
    await addPage(null, "file", { title, content: "" });
  };

  useEffect(() => {
    const onOnline = () => {
      retryPendingSyncs();
    };
    window.addEventListener("online", onOnline);
    return () => window.removeEventListener("online", onOnline);
  }, [retryPendingSyncs]);

  useEffect(() => {
    const flush = () => flushPendingSyncs();
    const onVisibilityChange = () => {
      if (document.visibilityState === "hidden") {
        flush();
      }
    };

    window.addEventListener("beforeunload", flush);
    window.addEventListener("pagehide", flush);
    document.addEventListener("visibilitychange", onVisibilityChange);

    return () => {
      window.removeEventListener("beforeunload", flush);
      window.removeEventListener("pagehide", flush);
      document.removeEventListener("visibilitychange", onVisibilityChange);
    };
  }, [flushPendingSyncs]);

  return (
    <ImportProvider>
      <div className="relative flex h-[100dvh] w-full overflow-hidden bg-background">
        <SearchCommand />

        <div className={cn(activePageId ? "hidden" : "block h-full flex-1 md:hidden")}>
          <SidebarContent />
        </div>

        <ResizableSidebar />

        <main className={cn("relative z-0 flex h-full flex-1 flex-col overflow-hidden", !activePageId && "hidden md:flex")}>
          {activePage ? (
            <div className="flex-1 overflow-y-auto scroll-smooth">
              <div className="mx-auto min-h-screen max-w-7xl px-3 py-4 md:px-16 md:py-6">
                <div className="ui-enter group relative mb-6 pt-10 md:mb-8 md:pt-0">
                  <button
                    className="absolute left-0 top-0 flex h-9 items-center gap-1 py-2 text-sm text-muted-foreground transition-colors hover:text-foreground md:hidden"
                    onClick={() => useEditorStore.getState().setActivePageId(null)}
                  >
                    <ChevronLeft size={18} />
                    返回列表
                  </button>

                  <div className="mb-3 flex flex-wrap items-center gap-1 text-xs text-muted-foreground md:mb-4 md:text-sm">
                    {breadcrumbs.map((crumb, index) => (
                      <div key={crumb.id} className="flex min-w-0 items-center gap-1">
                        {index > 0 && <ChevronRight size={14} className="opacity-50" />}
                        <button
                          onClick={() => useEditorStore.getState().setActivePageId(crumb.id)}
                          className={cn(
                            "flex min-w-0 items-center gap-1 transition-colors hover:text-foreground hover:underline",
                            crumb.id === activePage.id && "pointer-events-none font-medium text-foreground"
                          )}
                        >
                          {crumb.icon && <span>{crumb.icon}</span>}
                          <span className="truncate">{crumb.title || "无标题"}</span>
                        </button>
                      </div>
                    ))}
                  </div>

                  <div className="flex items-start gap-2">
                    {activePage.icon && <span className="select-none pt-0.5 text-[28px] md:text-3xl">{activePage.icon}</span>}
                    <input
                      value={activePage.title}
                      onChange={(e) => updatePage(activePage.id, { title: e.target.value })}
                      placeholder="无标题"
                      disabled={activePage.isLocked}
                      className={cn(
                        "w-full border-none bg-transparent text-2xl font-bold leading-tight text-foreground outline-none placeholder:text-muted-foreground/30 md:text-3xl",
                        activePage.isLocked && "cursor-not-allowed select-none opacity-80"
                      )}
                    />
                  </div>
                </div>

                <div className="ui-enter-delayed relative z-20 mb-6 flex flex-wrap items-center gap-2">
                  {activePage.tags?.map((tag) => {
                    const colors = getTagColor(tag);
                    return (
                      <span
                        key={tag}
                        onClick={() => openSearchWithTag(tag)}
                        className={cn(
                          "group/tag inline-flex items-center gap-1 rounded-[4px] border px-2.5 py-1 text-[11px] font-medium shadow-sm",
                          colors.bg,
                          colors.text,
                          colors.border
                        )}
                      >
                        <Hash size={10} className="opacity-70" />
                        {tag}
                        <button
                          onClick={(e) => {
                            e.stopPropagation();
                            const newTags = activePage.tags?.filter((t) => t !== tag) || [];
                            updatePage(activePage.id, { tags: newTags });
                          }}
                          className="ml-1 rounded-full p-1 opacity-100 transition-all hover:bg-black/10 md:p-0.5 md:opacity-0 md:group-hover/tag:opacity-100 dark:hover:bg-white/10"
                          title="移除标签"
                        >
                          <X size={10} />
                        </button>
                      </span>
                    );
                  })}

                  {isAddingTag ? (
                    <input
                      autoFocus
                      type="text"
                      value={tagInput}
                      onChange={(e) => setTagInput(e.target.value)}
                      onBlur={addTag}
                      onKeyDown={(e) => {
                        if (e.key === "Enter") {
                          e.preventDefault();
                          addTag();
                        }
                        if (e.key === "Escape") {
                          setTagInput("");
                          setIsAddingTag(false);
                        }
                      }}
                      className="w-28 rounded-md border border-primary/40 bg-background px-2 py-1 text-xs outline-none focus:ring-2 focus:ring-primary/20"
                      placeholder="输入标签"
                    />
                  ) : (
                    <button
                      onClick={() => setIsAddingTag(true)}
                      className="ui-btn-secondary px-2 py-1 text-xs text-muted-foreground"
                    >
                      <Plus size={12} /> 添加标签
                    </button>
                  )}

                  <div className="relative z-30">
                    <button
                      onClick={() => setIsIconPickerOpen((v) => !v)}
                      className="ui-btn-secondary px-2 py-1 text-xs text-muted-foreground"
                    >
                      <Sparkles size={12} /> {activePage.icon ? "更换图标" : "添加图标"}
                    </button>
                    {isIconPickerOpen && (
                      <div className="ui-card absolute left-0 top-full z-[120] mt-1 w-[min(92vw,20rem)] p-2 shadow-xl animate-in fade-in zoom-in-95 sm:w-80">
                        <div className="grid h-48 grid-cols-6 gap-1 overflow-y-auto pr-1 sm:grid-cols-8">
                          {ICONS.map((icon) => (
                            <button
                              key={icon}
                              onClick={() => {
                                updatePage(activePage.id, { icon });
                                setIsIconPickerOpen(false);
                              }}
                              className={cn(
                                "flex h-8 w-8 items-center justify-center rounded-md text-lg transition-colors hover:bg-accent",
                                activePage.icon === icon && "bg-accent"
                              )}
                            >
                              {icon}
                            </button>
                          ))}
                          <button
                            onClick={() => {
                              updatePage(activePage.id, { icon: null });
                              setIsIconPickerOpen(false);
                            }}
                            className="flex h-8 w-8 items-center justify-center rounded-md text-destructive transition-colors hover:bg-destructive/10"
                            title="清除图标"
                          >
                            <X size={14} />
                          </button>
                        </div>
                      </div>
                    )}
                  </div>

                  <button
                    onClick={() => updatePage(activePage.id, { isLocked: !activePage.isLocked })}
                    className={cn(
                      "ui-btn-secondary px-2 py-1 text-xs",
                      activePage.isLocked ? "border-orange-200 bg-orange-50 text-orange-600 dark:bg-orange-900/20 dark:text-orange-300" : "text-muted-foreground"
                    )}
                    title={activePage.isLocked ? "解锁编辑" : "锁定编辑，防止误触"}
                  >
                    {activePage.isLocked ? <Lock size={12} /> : <Unlock size={12} />}
                    {activePage.isLocked ? "已锁定" : "锁定"}
                  </button>

                  {activePageSync && (
                    <div className="flex items-center gap-1.5">
                      <div
                        className={cn(
                          "rounded border px-2 py-0.5 text-[11px] md:text-xs",
                          activePageSync.status === "saving" && "border-blue-200 bg-blue-50 text-blue-700 dark:bg-blue-900/20 dark:text-blue-300",
                          activePageSync.status === "pending" && "border-amber-200 bg-amber-50 text-amber-700 dark:bg-amber-900/20 dark:text-amber-300",
                          activePageSync.status === "error" && "border-red-200 bg-red-50 text-red-700 dark:bg-red-900/20 dark:text-red-300",
                          activePageSync.status === "saved" && "border-emerald-200 bg-emerald-50 text-emerald-700 dark:bg-emerald-900/20 dark:text-emerald-300"
                        )}
                        title={activePageSync.message}
                      >
                        {activePageSync.message || "已保存"}
                      </div>
                      {(activePageSync.status === "pending" || activePageSync.status === "error") && (
                        <button
                          onClick={() => activePage && retryPageSync(activePage.id)}
                          className="ui-btn-secondary px-2 py-0.5 text-[11px] md:text-xs"
                          title="立即尝试同步到本地数据库"
                        >
                          立即同步
                        </button>
                      )}
                    </div>
                  )}

                  {activePage.updatedAt && (
                    <div className="w-full pt-0.5 text-[11px] text-muted-foreground/60 md:ml-1 md:h-4 md:w-auto md:border-l md:pl-2 md:pt-0 md:text-xs md:text-muted-foreground/50">
                      {new Date(activePage.updatedAt).toLocaleString("zh-CN", {
                        timeZone: timezone || "Asia/Shanghai",
                        hour12: false,
                      })}
                    </div>
                  )}
                </div>

                {activePage.type === "folder" ? (
                  <div className="ui-card ui-enter flex h-[45vh] flex-col items-center justify-center gap-3 text-muted-foreground md:h-[50vh]">
                    <div className="ui-float rounded-2xl border border-border/70 bg-muted/40 p-4">
                      <FolderOpen size={34} className="text-primary/80" />
                    </div>
                    <p className="text-base font-medium text-foreground">当前是文件夹</p>
                    <p className="text-sm text-muted-foreground">你可以在左侧新建文档，或把文档拖拽到此文件夹。</p>
                  </div>
                ) : (
                  <div className="min-h-[60vh] pb-24">
                    <Editor
                      content={activePage.content}
                      onChange={(content) => updatePage(activePage.id, { content })}
                      onEditorReady={setEditor}
                      onToggleAI={() => setIsChatOpen(!isChatOpen)}
                      onExport={() => exportPageAsMarkdown(activePage)}
                      onOpenWikiLink={handleOpenWikiLink}
                      editable={!activePage.isLocked}
                    />

                    <section className="ui-enter mt-6 space-y-3 md:mt-7">
                      <div className="grid gap-2 md:grid-cols-3">
                        <div className="ui-card p-2.5 md:p-3">
                          <div className="flex items-center justify-between">
                            <h3 className="text-sm font-semibold text-foreground">关联页面</h3>
                            <span className="rounded bg-muted px-1.5 py-0.5 text-[10px] text-muted-foreground">{outgoingLinks.length}</span>
                          </div>
                          <p className="mt-1 text-[11px] text-muted-foreground">正文写 `[[页面名]]` 可自动关联。</p>
                          <div className="mt-2 flex flex-wrap gap-1.5">
                          {outgoingLinks.length > 0 ? (
                            outgoingLinks.map((item) => (
                              <button
                                key={item.id}
                                onClick={() => setActivePageId(item.id)}
                                className="rounded-md border border-border/70 bg-muted/40 px-2 py-0.5 text-[11px] text-foreground transition-colors hover:bg-accent"
                              >
                                {item.icon ? `${item.icon} ` : ""}
                                {item.title}
                              </button>
                            ))
                          ) : (
                            <span className="text-[11px] text-muted-foreground">暂无</span>
                          )}
                        </div>
                        </div>

                        <div className="ui-card p-2.5 md:p-3">
                          <div className="flex items-center justify-between">
                            <h3 className="text-sm font-semibold text-foreground">反向链接</h3>
                            <span className="rounded bg-muted px-1.5 py-0.5 text-[10px] text-muted-foreground">{backlinks.length}</span>
                          </div>
                          <p className="mt-1 text-[11px] text-muted-foreground">被哪些页面引用。</p>
                          <div className="mt-2 flex flex-wrap gap-1.5">
                          {backlinks.length > 0 ? (
                            backlinks.map((item) => (
                              <button
                                key={item.id}
                                onClick={() => setActivePageId(item.id)}
                                className="rounded-md border border-border/70 bg-muted/40 px-2 py-0.5 text-[11px] text-foreground transition-colors hover:bg-accent"
                              >
                                {item.icon ? `${item.icon} ` : ""}
                                {item.title}
                              </button>
                            ))
                          ) : (
                            <span className="text-[11px] text-muted-foreground">暂无</span>
                          )}
                        </div>
                        </div>

                        <div className="ui-card p-2.5 md:p-3">
                          <div className="flex items-center justify-between">
                            <h3 className="text-sm font-semibold text-foreground">未解析链接</h3>
                            <span className="rounded bg-muted px-1.5 py-0.5 text-[10px] text-muted-foreground">{unresolvedLinks.length}</span>
                          </div>
                          <p className="mt-1 text-[11px] text-muted-foreground">可一键创建缺失页面。</p>
                          <div className="mt-2 flex flex-wrap gap-1.5">
                          {unresolvedLinks.length > 0 ? (
                            unresolvedLinks.map((title) => (
                              <button
                                key={title}
                                onClick={async () => {
                                  await addPage(null, "file", { title, content: "" });
                                }}
                                className="rounded-md border border-dashed border-border bg-muted/30 px-2 py-0.5 text-[11px] text-foreground transition-colors hover:bg-accent"
                                title={`创建页面：${title}`}
                              >
                                + {title}
                              </button>
                            ))
                          ) : (
                            <span className="text-[11px] text-muted-foreground">全部已解析</span>
                          )}
                        </div>
                      </div>
                      </div>

                      <div className="ui-card p-2.5 md:p-3">
                        <button
                          onClick={() => setIsHistoryOpen((v) => !v)}
                          className="flex w-full items-center justify-between rounded-md px-1 py-1 text-left transition-colors hover:bg-muted/45"
                          aria-expanded={isHistoryOpen}
                          aria-label="切换本地历史版本面板"
                        >
                          <div className="flex items-center gap-2">
                            <History size={14} className="text-muted-foreground" />
                            <h3 className="text-sm font-semibold text-foreground">本地历史版本</h3>
                            <span className="rounded bg-muted px-1.5 py-0.5 text-[10px] text-muted-foreground">{localHistory.length}</span>
                          </div>
                          <ChevronDown size={15} className={cn("text-muted-foreground transition-transform", isHistoryOpen && "rotate-180")} />
                        </button>
                        <p className="mt-1 text-[11px] text-muted-foreground">自动保存最近修改快照（当前浏览器本地）。</p>
                        {isHistoryOpen && (
                          <div className="mt-2 space-y-2.5">
                            {localHistory.length > 0 ? (
                              <>
                                <div className="rounded-lg border border-border/60 bg-muted/20 p-2">
                                  <label className="mb-1 block text-[11px] text-muted-foreground">选择要恢复的版本</label>
                                  <select
                                    value={selectedHistoryIndex}
                                    onChange={(e) => setSelectedHistoryIndex(parseInt(e.target.value, 10))}
                                    className="ui-select h-9 py-1 text-xs"
                                  >
                                    {localHistory.slice(0, 20).map((snapshot, index) => (
                                      <option key={`${snapshot.timestamp}-${index}`} value={index}>
                                        {new Date(snapshot.timestamp).toLocaleString("zh-CN", {
                                          timeZone: timezone || "Asia/Shanghai",
                                          hour12: false,
                                        })}
                                        {` · ${snapshot.title || "无标题"}`}
                                      </option>
                                    ))}
                                  </select>
                                </div>
                                <div className="rounded-md border border-border/60 bg-muted/15 px-2.5 py-2">
                                  <div className="truncate text-xs text-foreground">
                                    {localHistory[effectiveHistoryIndex]?.title || "无标题"}
                                  </div>
                                  <div className="text-[11px] text-muted-foreground">
                                    {localHistory[effectiveHistoryIndex]
                                      ? new Date(localHistory[effectiveHistoryIndex].timestamp).toLocaleString("zh-CN", {
                                          timeZone: timezone || "Asia/Shanghai",
                                          hour12: false,
                                        })
                                      : "-"}
                                  </div>
                                </div>
                                <button
                                  onClick={async () => {
                                    const target = localHistory[effectiveHistoryIndex];
                                    if (!target || !activePage) return;
                                    const ok = window.confirm("恢复该历史版本后将覆盖当前内容，是否继续？");
                                    if (!ok) return;
                                    await updatePage(activePage.id, {
                                      title: target.title,
                                      content: target.content,
                                    });
                                  }}
                                  className="ui-btn-secondary h-9 w-full justify-center px-2 py-1 text-xs sm:h-auto sm:w-auto sm:justify-start"
                                >
                                  <RotateCcw size={12} />
                                  恢复选中版本
                                </button>
                              </>
                            ) : (
                              <span className="text-xs text-muted-foreground">暂无历史记录</span>
                            )}
                          </div>
                        )}
                      </div>
                    </section>
                  </div>
                )}
              </div>
            </div>
          ) : (
            <div className="ui-enter flex h-full items-center justify-center p-4 md:p-8">
              <div className="ui-card flex w-full max-w-md flex-col items-center gap-3 px-6 py-8 text-center text-muted-foreground">
                <div className="ui-float rounded-2xl border border-border/70 bg-muted/40 p-4">
                  <span className="text-4xl">🧠</span>
                </div>
                <div className="space-y-1">
                  <h3 className="text-lg font-semibold text-foreground">欢迎使用 NoteAI</h3>
                  <p className="text-sm text-muted-foreground/90">在左侧选择一个页面，或新建文档开始写作。</p>
                </div>
              </div>
            </div>
          )}
        </main>

        <AIChatPanel editor={editor} isOpen={isChatOpen} onClose={() => setIsChatOpen(false)} />
      </div>
    </ImportProvider>
  );
}
