"use client";

import { useState, useEffect, useRef } from "react";
import { useTranslation } from "@/hooks/useTranslation";
import { useAuthGuard } from "@/hooks/useAuthGuard";
import { usePermissions } from "@/hooks/usePermissions";
import { useConfirm } from "@/components/common/feedback/ConfirmProvider";
import { toast } from "@/lib/toast";
import { ApiClientError } from "@/lib/api-client";
import { useRouter } from "next/navigation";
import { Input } from "@/components/ui/input";
import { Button } from "@/components/ui/button";
import {
  Dialog,
  DialogContent,
  DialogDescription,
  DialogHeader,
  DialogTitle,
} from "@/components/ui/dialog";
import { PageState } from "@/components/common/feedback/PageState";
import {
  Loader2,
  Search,
  RefreshCw,
  Clock,
  FileText,
  BookOpen,
  Sparkles,
  FolderOpen,
  ClipboardList,
  X,
} from "lucide-react";
import Link from "next/link";
import { cn } from "@/lib/utils";
import {
  buildRelevantSnippetFromSources,
  extractPreviewTextFromArticleContent,
  extractSearchKeywords,
  renderHighlightedText,
  sanitizeSearchText,
} from "./_lib/searchHighlight";
import { getKnowledgeBaseResultIcon } from "./_lib/documentTypeIcon";

// Components
import { KBAnalyticsPanel } from "./_components/KBAnalyticsPanel";
import { KBActivityFeed } from "./_components/KBActivityFeed";
import { KBChatbotButton } from "./_components/KBChatbotButton";
import { KBQuickStart } from "./_components/KBQuickStart";

// API
import {
  knowledgeBaseApi,
  type KnowledgeArticle,
  type SearchSuggestionItem,
  type SemanticSearchItem,
  type RecentlyVisitedItem,
} from "./_lib/api";

type ViewMode = "recent" | "starred";
type AuthorityLevelKey = "OFFICIAL" | "EXPERT" | "PUBLISHED" | "DRAFT";
type DocTypeKey =
  | "POLICY"
  | "MANUAL"
  | "TUTORIAL"
  | "FAQ"
  | "GENERAL"
  | "ARTICLE"
  | "document"
  | "article";

const placeholderMeta = [
  { icon: BookOpen, color: "text-blue-500 bg-blue-50" },
  { icon: FileText, color: "text-green-500 bg-green-50" },
  { icon: Sparkles, color: "text-purple-500 bg-purple-50" },
  { icon: FileText, color: "text-orange-500 bg-orange-50" },
  { icon: BookOpen, color: "text-pink-500 bg-pink-50" },
  { icon: FolderOpen, color: "text-cyan-500 bg-cyan-50" },
];

export default function KnowledgeBasePage() {
  const { t, locale } = useTranslation();
  const { isReady } = useAuthGuard();
  const { isAdmin } = usePermissions();
  const confirm = useConfirm();
  const router = useRouter();
  const [searchQuery, setSearchQuery] = useState("");
  const [appliedSearchQuery, setAppliedSearchQuery] = useState("");
  const [suggestions, setSuggestions] = useState<SearchSuggestionItem[]>([]);
  const [suggestionsOpen, setSuggestionsOpen] = useState(false);
  const [suggestionLoading, setSuggestionLoading] = useState(false);
  const [activeSuggestionIndex, setActiveSuggestionIndex] = useState(-1);
  const [viewMode, setViewMode] = useState<ViewMode>("recent");
  const [searchResults, setSearchResults] = useState<SemanticSearchItem[]>([]);
  const [searching, setSearching] = useState(false);
  const [showResults, setShowResults] = useState(false);
  const [searchError, setSearchError] = useState<{
    title: string;
    description?: string;
  } | null>(null);
  const [previewOpen, setPreviewOpen] = useState(false);
  const [previewLoading, setPreviewLoading] = useState(false);
  const [previewError, setPreviewError] = useState<string | null>(null);
  const [previewItem, setPreviewItem] = useState<SemanticSearchItem | null>(
    null,
  );
  const [previewArticle, setPreviewArticle] = useState<KnowledgeArticle | null>(
    null,
  );
  const [syncingFull, setSyncingFull] = useState(false);
  const [syncingDelta, setSyncingDelta] = useState(false);
  const [recentArticles, setRecentArticles] = useState<RecentlyVisitedItem[]>(
    [],
  );
  const [loadingArticles, setLoadingArticles] = useState(true);
  const searchBoxRef = useRef<HTMLDivElement | null>(null);
  const latestSuggestionRequestRef = useRef(0);
  const suppressSuggestionFetchRef = useRef(false);
  const placeholderArticles = t.knowledgeBase.placeholders.articles.map(
    (article, index) => ({
      ...article,
      ...(placeholderMeta[index] || {}),
    }),
  );

  // Fetch recent articles
  useEffect(() => {
    const fetchArticles = async () => {
      try {
        const response = await knowledgeBaseApi.getRecentlyVisited(12);
        setRecentArticles(response.items);
      } catch (err) {
        console.error("Failed to fetch recent articles:", err);
      } finally {
        setLoadingArticles(false);
      }
    };
    fetchArticles();
  }, []);

  // Get greeting based on time
  const getGreeting = () => {
    const hour = new Date().getHours();
    if (hour < 12) return t.knowledgeBase.home.greeting.morning;
    if (hour < 18) return t.knowledgeBase.home.greeting.afternoon;
    return t.knowledgeBase.home.greeting.evening;
  };

  const runSearch = async (query: string) => {
    const normalized = query.trim();
    if (!normalized) {
      setAppliedSearchQuery("");
      setShowResults(false);
      setSearchResults([]);
      setSearchError(null);
      return;
    }

    try {
      setSearching(true);
      setSearchError(null);
      // 使用本地语义搜索（混合模式：关键词 + 向量）
      const response = await knowledgeBaseApi.semanticSearch({
        q: normalized,
        type: "hybrid",
        limit: 10,
      });
      setAppliedSearchQuery(normalized);
      setSearchResults(response.items);
      setShowResults(true);
    } catch (err) {
      console.error("Search failed:", err);
      if (
        err instanceof ApiClientError &&
        err.code === "KNOWLEDGE_BASE_SEARCH_PROVIDER_ERROR"
      ) {
        toast.error(t.knowledgeBase.errors.searchProviderUnavailable);
        setSearchError({
          title: t.knowledgeBase.errors.searchProviderUnavailable,
          description:
            t.knowledgeBase.errors.searchProviderUnavailableDescription,
        });
      } else {
        toast.error(t.knowledgeBase.errors.searchFailed);
        setSearchError({
          title: t.knowledgeBase.errors.searchFailed,
        });
      }
      setSearchResults([]);
      setShowResults(true);
    } finally {
      setSearching(false);
    }
  };

  const handleSearch = async () => {
    setSuggestionsOpen(false);
    setActiveSuggestionIndex(-1);
    await runSearch(searchQuery);
  };

  const handleSuggestionSelect = async (value: string) => {
    suppressSuggestionFetchRef.current = true;
    setSearchQuery(value);
    setSuggestionsOpen(false);
    setActiveSuggestionIndex(-1);
    await runSearch(value);
  };

  const handleRemoveRecentSuggestion = async (text: string) => {
    try {
      const result = await knowledgeBaseApi.deleteSearchHistory({
        query: text,
      });
      if (result.deleted > 0) {
        const next = suggestions.filter(
          (item) =>
            !(
              item.source === "RECENT_SEARCH" &&
              item.text.toLowerCase() === text.toLowerCase()
            ),
        );
        setSuggestions(next);
        setActiveSuggestionIndex(next.length > 0 ? 0 : -1);
      }
    } catch (error) {
      console.error("Failed to remove recent search:", error);
      toast.error(t.knowledgeBase.suggestions.removeFailed);
    }
  };

  const handleClearRecentSuggestions = async () => {
    try {
      const result = await knowledgeBaseApi.deleteSearchHistory();
      if (result.deleted > 0) {
        const next = suggestions.filter(
          (item) => item.source !== "RECENT_SEARCH",
        );
        setSuggestions(next);
        setActiveSuggestionIndex(next.length > 0 ? 0 : -1);
      }
    } catch (error) {
      console.error("Failed to clear recent searches:", error);
      toast.error(t.knowledgeBase.suggestions.clearFailed);
    }
  };

  useEffect(() => {
    if (suppressSuggestionFetchRef.current) {
      suppressSuggestionFetchRef.current = false;
      return;
    }

    const keyword = searchQuery.trim();
    if (keyword.length < 2) {
      setSuggestions([]);
      setSuggestionsOpen(false);
      setActiveSuggestionIndex(-1);
      setSuggestionLoading(false);
      return;
    }

    const requestId = latestSuggestionRequestRef.current + 1;
    latestSuggestionRequestRef.current = requestId;

    const timer = window.setTimeout(async () => {
      try {
        setSuggestionLoading(true);
        const response = await knowledgeBaseApi.searchSuggestions({
          q: keyword,
          limit: 8,
        });
        if (latestSuggestionRequestRef.current !== requestId) {
          return;
        }
        setSuggestions(response.items);
        setSuggestionsOpen(true);
        setActiveSuggestionIndex(response.items.length > 0 ? 0 : -1);
      } catch {
        if (latestSuggestionRequestRef.current !== requestId) {
          return;
        }
        setSuggestions([]);
        setSuggestionsOpen(true);
        setActiveSuggestionIndex(-1);
      } finally {
        if (latestSuggestionRequestRef.current === requestId) {
          setSuggestionLoading(false);
        }
      }
    }, 200);

    return () => {
      window.clearTimeout(timer);
    };
  }, [searchQuery]);

  useEffect(() => {
    const onPointerDown = (event: MouseEvent) => {
      if (!searchBoxRef.current?.contains(event.target as Node)) {
        setSuggestionsOpen(false);
        setActiveSuggestionIndex(-1);
      }
    };

    document.addEventListener("mousedown", onPointerDown);
    return () => {
      document.removeEventListener("mousedown", onPointerDown);
    };
  }, []);

  const handleKeyDown = (e: React.KeyboardEvent) => {
    if (
      (e.key === "ArrowDown" || e.key === "ArrowUp") &&
      suggestionsOpen &&
      suggestions.length > 0
    ) {
      e.preventDefault();
      setActiveSuggestionIndex((previous) => {
        if (e.key === "ArrowDown") {
          return previous >= suggestions.length - 1 ? 0 : previous + 1;
        }
        return previous <= 0 ? suggestions.length - 1 : previous - 1;
      });
      return;
    }

    if (e.key === "Escape") {
      setSuggestionsOpen(false);
      setActiveSuggestionIndex(-1);
      return;
    }

    if (e.key === "Enter") {
      if (
        suggestionsOpen &&
        activeSuggestionIndex >= 0 &&
        suggestions[activeSuggestionIndex]
      ) {
        e.preventDefault();
        void handleSuggestionSelect(suggestions[activeSuggestionIndex].text);
        return;
      }
      void handleSearch();
    }
  };

  const handleFullSync = async () => {
    const confirmed = await confirm({
      title: t.knowledgeBase.fullSync.confirmTitle,
      description: t.knowledgeBase.fullSync.confirmDescription,
      variant: "primary",
    });
    if (!confirmed) return;

    try {
      setSyncingFull(true);
      const result = await knowledgeBaseApi.triggerFullSync();
      toast.action(t.knowledgeBase.fullSync.success, {
        label: t.knowledgeBase.fullSync.viewDetails,
        onClick: () =>
          router.push(`/knowledge-base/sync-tasks/${result.taskId}`),
      });
    } catch (err) {
      console.error("Failed to trigger knowledge base full sync:", err);
      toast.error(t.knowledgeBase.fullSync.failed);
    } finally {
      setSyncingFull(false);
    }
  };

  const handleDeltaSync = async () => {
    const confirmed = await confirm({
      title: t.knowledgeBase.deltaSync.confirmTitle,
      description: t.knowledgeBase.deltaSync.confirmDescription,
      variant: "primary",
    });
    if (!confirmed) return;

    try {
      setSyncingDelta(true);
      const result = await knowledgeBaseApi.triggerDeltaSync();
      const message = result.message;
      toast.action(message || t.knowledgeBase.deltaSync.success, {
        label: t.knowledgeBase.deltaSync.viewDetails,
        onClick: () =>
          router.push(`/knowledge-base/sync-tasks/${result.taskId}`),
      });
    } catch (err) {
      console.error("Failed to trigger knowledge base delta sync:", err);
      toast.error(t.knowledgeBase.deltaSync.failed);
    } finally {
      setSyncingDelta(false);
    }
  };

  if (!isReady) {
    return (
      <div className="flex h-full items-center justify-center bg-[#f4f5f7]">
        <Loader2 className="h-8 w-8 animate-spin text-blue-600" />
      </div>
    );
  }

  const hasRealArticles = recentArticles.length > 0;
  const searchKeywords = extractSearchKeywords(appliedSearchQuery);
  const fileSearchResults = searchResults.filter(
    (
      item,
    ): item is SemanticSearchItem & { type: "document" | "article" } =>
      item.type !== "folder",
  );
  const folderSearchResults = searchResults.filter(
    (
      item,
    ): item is SemanticSearchItem & { type: "folder" } =>
      item.type === "folder",
  );
  const suggestionsBySource = {
    RECENT_SEARCH: suggestions.filter(
      (item) => item.source === "RECENT_SEARCH",
    ),
    TOP_QUERY: suggestions.filter((item) => item.source === "TOP_QUERY"),
    TITLE: suggestions.filter((item) => item.source === "TITLE"),
  };

  const openOriginalResult = (item: SemanticSearchItem) => {
    if (item.type === "article") {
      router.push(`/knowledge-base/articles/${item.id}`);
      return;
    }
    if (item.webUrl) {
      window.open(item.webUrl, "_blank", "noopener,noreferrer");
    }
  };

  const openPreview = async (item: SemanticSearchItem) => {
    setPreviewItem(item);
    setPreviewArticle(null);
    setPreviewError(null);
    setPreviewLoading(false);
    setPreviewOpen(true);

    if (item.type !== "article") {
      return;
    }

    try {
      setPreviewLoading(true);
      const article = await knowledgeBaseApi.getArticle(item.id);
      setPreviewArticle(article);
    } catch (err) {
      console.error("Failed to load article preview:", err);
      setPreviewError(t.knowledgeBase.previewFailed);
    } finally {
      setPreviewLoading(false);
    }
  };

  const previewText = !previewItem
    ? ""
    : previewItem.type === "article"
      ? extractPreviewTextFromArticleContent(previewArticle?.content || "")
      : sanitizeSearchText(previewItem.previewContent || "").trim();
  const previewSourceLabel = !previewItem
    ? ""
    : previewItem.type === "article"
      ? t.knowledgeBase.previewSourceType.article
      : previewItem.previewContent
        ? t.knowledgeBase.previewSourceType.documentAggregated
        : t.knowledgeBase.previewSourceType.documentSnippet;
  const previewCharCount = previewText.length;

  return (
    <div className="flex h-full flex-col bg-[#f4f5f7]">
      {/* Page Header with Search */}
      <div className="flex-shrink-0 border-b border-gray-200 bg-white px-6 py-2">
        <div className="flex items-center justify-between">
          {/* Left: Title */}
          <div className="flex items-center gap-2">
            <div className="flex h-8 w-8 items-center justify-center rounded-lg bg-gradient-to-br from-blue-500 to-purple-600">
              <BookOpen className="h-4 w-4 text-white" />
            </div>
            <h1 className="text-lg font-semibold text-gray-900">
              {t.knowledgeBase.title}
            </h1>
          </div>

          {/* Center: Search */}
          <div className="flex flex-1 items-center justify-center px-8">
            <div ref={searchBoxRef} className="relative w-full max-w-xl">
              <Search className="absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-gray-400" />
              <Input
                type="text"
                placeholder={t.knowledgeBase.searchPlaceholder}
                value={searchQuery}
                onChange={(e) => setSearchQuery(e.target.value)}
                onKeyDown={handleKeyDown}
                onFocus={() => {
                  if (searchQuery.trim().length >= 2) {
                    setSuggestionsOpen(true);
                  }
                }}
                role="combobox"
                aria-autocomplete="list"
                aria-expanded={suggestionsOpen}
                aria-controls="kb-search-suggestions"
                aria-activedescendant={
                  activeSuggestionIndex >= 0
                    ? `kb-search-suggestion-item-${activeSuggestionIndex}`
                    : undefined
                }
                data-testid="kb-search-input"
                className="w-full rounded-full border-gray-200 bg-gray-50 py-2 pl-10 pr-20 text-sm transition-all focus:bg-white focus:shadow-sm"
              />
              <Button
                type="button"
                size="sm"
                onClick={() => {
                  void handleSearch();
                }}
                disabled={searching}
                data-testid="kb-search-button"
                className="absolute right-1 top-1/2 h-8 -translate-y-1/2 rounded-full px-3"
              >
                {searching ? (
                  <Loader2 className="h-4 w-4 animate-spin" />
                ) : (
                  t.knowledgeBase.searchButton
                )}
              </Button>
              {suggestionsOpen && (
                <div
                  id="kb-search-suggestions"
                  role="listbox"
                  data-testid="kb-search-suggestions"
                  className="absolute left-0 right-0 top-[calc(100%+8px)] z-20 max-h-96 overflow-y-auto rounded-xl border border-gray-200 bg-white p-2 shadow-lg"
                >
                  {suggestionLoading ? (
                    <p className="px-3 py-2 text-xs text-gray-500">
                      {t.knowledgeBase.suggestions.loading}
                    </p>
                  ) : suggestions.length === 0 ? (
                    <p className="px-3 py-2 text-xs text-gray-500">
                      {t.knowledgeBase.suggestions.empty}
                    </p>
                  ) : (
                    <div className="space-y-2">
                      {(["TITLE", "RECENT_SEARCH", "TOP_QUERY"] as const).map(
                        (source) => {
                          const items = suggestionsBySource[source];
                          if (items.length === 0) return null;
                          return (
                            <div key={source}>
                              <div className="flex items-center justify-between px-2 py-1">
                                <p className="text-xs font-medium text-gray-500">
                                  {t.knowledgeBase.suggestions.group[source]}
                                </p>
                                {source === "RECENT_SEARCH" && (
                                  <button
                                    type="button"
                                    className="text-xs text-gray-500 hover:text-gray-700"
                                    onClick={() => {
                                      void handleClearRecentSuggestions();
                                    }}
                                  >
                                    {t.knowledgeBase.suggestions.clearRecent}
                                  </button>
                                )}
                              </div>
                              <div className="space-y-1">
                                {items.map((item) => {
                                  const globalIndex = suggestions.findIndex(
                                    (candidate) =>
                                      candidate.text === item.text &&
                                      candidate.source === item.source,
                                  );
                                  const isActive =
                                    globalIndex === activeSuggestionIndex;
                                  if (source === "RECENT_SEARCH") {
                                    return (
                                      <div
                                        key={`${item.source}-${item.text}`}
                                        className={cn(
                                          "flex items-center gap-1 rounded-md px-2 py-1",
                                          isActive
                                            ? "bg-blue-50"
                                            : "hover:bg-gray-50",
                                        )}
                                        onMouseEnter={() =>
                                          setActiveSuggestionIndex(globalIndex)
                                        }
                                      >
                                        <button
                                          id={`kb-search-suggestion-item-${globalIndex}`}
                                          role="option"
                                          aria-selected={isActive}
                                          data-testid="kb-search-suggestion-item"
                                          type="button"
                                          className={cn(
                                            "min-w-0 flex-1 rounded-md px-1 py-1 text-left text-sm",
                                            isActive
                                              ? "text-blue-700"
                                              : "text-gray-700",
                                          )}
                                          onClick={() => {
                                            void handleSuggestionSelect(
                                              item.text,
                                            );
                                          }}
                                        >
                                          <span className="truncate">
                                            {item.text}
                                          </span>
                                        </button>
                                        <button
                                          type="button"
                                          className="shrink-0 rounded p-1 text-gray-400 hover:bg-white hover:text-gray-700"
                                          aria-label={
                                            t.knowledgeBase.suggestions
                                              .removeOne
                                          }
                                          onClick={(event) => {
                                            event.stopPropagation();
                                            void handleRemoveRecentSuggestion(
                                              item.text,
                                            );
                                          }}
                                        >
                                          <X className="h-3.5 w-3.5" />
                                        </button>
                                      </div>
                                    );
                                  }
                                  return (
                                    <button
                                      key={`${item.source}-${item.text}`}
                                      id={`kb-search-suggestion-item-${globalIndex}`}
                                      role="option"
                                      aria-selected={isActive}
                                      data-testid="kb-search-suggestion-item"
                                      type="button"
                                      className={cn(
                                        "w-full rounded-md px-3 py-2 text-left text-sm transition-colors",
                                        isActive
                                          ? "bg-blue-50 text-blue-700"
                                          : "text-gray-700 hover:bg-gray-50",
                                      )}
                                      onMouseEnter={() =>
                                        setActiveSuggestionIndex(globalIndex)
                                      }
                                      onClick={() => {
                                        void handleSuggestionSelect(item.text);
                                      }}
                                    >
                                      {item.text}
                                    </button>
                                  );
                                })}
                              </div>
                            </div>
                          );
                        },
                      )}
                    </div>
                  )}
                </div>
              )}
            </div>
          </div>

          {/* Right: Actions */}
          <div className="flex flex-col items-end gap-1">
            <div className="flex items-center gap-3">
              {isAdmin && (
                <>
                  <Button
                    variant="outline"
                    size="sm"
                    className="gap-1.5 rounded-full"
                    onClick={handleDeltaSync}
                    disabled={syncingDelta}
                    data-testid="kb-sync-delta"
                  >
                    {syncingDelta ? (
                      <Loader2 className="h-4 w-4 animate-spin" />
                    ) : (
                      <RefreshCw className="h-4 w-4" />
                    )}
                    {t.knowledgeBase.deltaSync.action}
                  </Button>
                  <Button
                    variant="outline"
                    size="sm"
                    className="gap-1.5 rounded-full"
                    onClick={handleFullSync}
                    disabled={syncingFull}
                    data-testid="kb-sync-full"
                  >
                    {syncingFull ? (
                      <Loader2 className="h-4 w-4 animate-spin" />
                    ) : (
                      <RefreshCw className="h-4 w-4" />
                    )}
                    {t.knowledgeBase.fullSync.action}
                  </Button>
                  <Button
                    variant="outline"
                    size="sm"
                    className="gap-1.5 rounded-full"
                    onClick={() => router.push("/knowledge-base/sync-tasks")}
                  >
                    <ClipboardList className="h-4 w-4" />
                    {t.knowledgeBase.syncTaskList.entry}
                  </Button>
                </>
              )}
            </div>
            {isAdmin && (
              <p
                data-testid="kb-sync-strategy"
                className="text-xs text-gray-500"
              >
                {t.knowledgeBase.deltaSync.strategyHint}
              </p>
            )}
          </div>
        </div>
      </div>

      {/* Main Content - Scrollable */}
      <main className="flex-1 overflow-y-auto">
        <div className="px-6 py-6">
          {/* Search Results */}
          {showResults && (
            <div className="mb-6 rounded-xl border border-gray-200 bg-white p-6 shadow-sm">
              <div className="mb-4 flex items-center justify-between">
                <h2 className="font-semibold text-gray-900">
                  {t.knowledgeBase.resultsTitle} ({searchResults.length})
                </h2>
                <button
                  onClick={() => setShowResults(false)}
                  className="text-sm text-gray-500 hover:text-gray-700"
                >
                  {t.knowledgeBase.clear}
                </button>
              </div>
              {searchError ? (
                <div className="py-8">
                  <PageState
                    variant="error"
                    title={searchError.title}
                    description={searchError.description}
                    layout="center"
                    className="border-0 bg-transparent"
                  />
                </div>
              ) : searchResults.length === 0 ? (
                <div className="py-8">
                  <PageState
                    variant="empty"
                    title={t.knowledgeBase.emptyState}
                    description={t.knowledgeBase.emptyStateHint}
                    layout="center"
                    className="border-0 bg-transparent"
                  />
                </div>
              ) : (
                <div className="space-y-4">
                  <div className="space-y-2">
                    <p className="text-xs font-medium text-gray-500">
                      {t.knowledgeBase.fileResultsTitle} ({fileSearchResults.length})
                    </p>
                    {fileSearchResults.map((item) => {
                    const fileIcon = getKnowledgeBaseResultIcon(item);
                    const ResultIcon = fileIcon.Icon;
                    return (
                      <div
                        key={item.id}
                        className="flex flex-col gap-3 rounded-lg border border-gray-100 p-3 transition-colors hover:bg-gray-50 sm:flex-row sm:items-center sm:justify-between"
                      >
                        <button
                          type="button"
                          className="flex min-w-0 flex-1 cursor-pointer items-center gap-3 rounded-md p-1 text-left transition-colors hover:bg-white focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[#3370FF]"
                          onClick={() => openOriginalResult(item)}
                        >
                          <div
                            className={cn(
                              "flex h-10 w-10 items-center justify-center rounded-lg",
                              fileIcon.containerClassName,
                            )}
                          >
                            <ResultIcon
                              className={cn("h-5 w-5", fileIcon.iconClassName)}
                            />
                          </div>
                          <div className="min-w-0 flex-1">
                            <div className="flex items-center gap-2">
                              <p className="font-medium text-gray-900 truncate">
                                {renderHighlightedText(item.title, searchKeywords, {
                                  enableLooseMatching: true,
                                })}
                              </p>
                              {item.docAuthorityLevel &&
                                item.docAuthorityLevel !== "DRAFT" && (
                                <span
                                  className={`shrink-0 rounded px-1.5 py-0.5 text-xs ${
                                    item.docAuthorityLevel === "OFFICIAL"
                                      ? "bg-green-100 text-green-700"
                                      : item.docAuthorityLevel === "EXPERT"
                                        ? "bg-blue-100 text-blue-700"
                                        : "bg-gray-100 text-gray-700"
                                  }`}
                                >
                                  {
                                    t.knowledgeBase.authorityLevel[
                                      item.docAuthorityLevel as AuthorityLevelKey
                                    ]
                                  }
                                </span>
                              )}
                            </div>
                            <p className="mt-0.5 truncate text-xs text-gray-500">
                              {renderHighlightedText(
                                buildRelevantSnippetFromSources(
                                  [
                                    item.previewContent,
                                    item.snippet,
                                  ],
                                  searchKeywords,
                                ),
                                searchKeywords,
                              )}
                            </p>
                            <p className="mt-1 text-xs text-gray-400">
                              {[
                                item.docType && item.docType !== "GENERAL"
                                  ? t.knowledgeBase.docType[
                                      item.docType as DocTypeKey
                                    ]
                                  : null,
                                item.createdBy
                                  ? `${t.knowledgeBase.createdBy} ${item.createdBy}`
                                  : null,
                                item.lastModifiedAt
                                  ? new Date(item.lastModifiedAt).toLocaleDateString(
                                      locale === "zh" ? "zh-CN" : "en-US",
                                    )
                                  : null,
                              ]
                                .filter(Boolean)
                                .join(" · ")}
                            </p>
                          </div>
                        </button>
                        <div className="flex shrink-0 items-end gap-1 self-start sm:self-auto">
                          <span className="mb-0.5 text-[9px] leading-none text-gray-300">
                            {t.knowledgeBase.relevance} {Math.round(item.score * 100)}%
                          </span>
                          {(item.type === "article" || item.webUrl) && (
                            <Button
                              variant="outline"
                              size="sm"
                              onClick={() => openPreview(item)}
                            >
                              {t.knowledgeBase.preview}
                            </Button>
                          )}
                        </div>
                      </div>
                    );
                  })}
                  </div>
                  {folderSearchResults.length > 0 && (
                    <div className="space-y-2 pt-1">
                      <p className="text-xs font-medium text-gray-500">
                        {t.knowledgeBase.folderResultsTitle} ({folderSearchResults.length})
                      </p>
                      {folderSearchResults.map((item) => (
                        <button
                          key={item.id}
                          type="button"
                          onClick={() => openOriginalResult(item)}
                          className="flex w-full cursor-pointer items-start gap-3 rounded-lg border border-gray-100 p-3 text-left transition-colors hover:bg-gray-50 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[#3370FF]"
                        >
                          <div className="flex h-10 w-10 items-center justify-center rounded-lg bg-blue-50 text-blue-600">
                            <FolderOpen className="h-5 w-5" />
                          </div>
                          <div className="min-w-0 flex-1">
                            <p className="truncate font-medium text-gray-900">
                              {renderHighlightedText(item.title, searchKeywords, {
                                enableLooseMatching: true,
                              })}
                            </p>
                            <p className="mt-0.5 truncate text-xs text-gray-500">
                              {renderHighlightedText(
                                item.folderPath || item.snippet,
                                searchKeywords,
                                { enableLooseMatching: true },
                              )}
                            </p>
                            <p className="mt-1 text-xs text-gray-400">
                              {[
                                item.lastModifiedAt
                                  ? new Date(item.lastModifiedAt).toLocaleDateString(
                                      locale === "zh" ? "zh-CN" : "en-US",
                                    )
                                  : null,
                              ]
                                .filter(Boolean)
                                .join(" · ")}
                            </p>
                          </div>
                        </button>
                      ))}
                    </div>
                  )}
                </div>
              )}
            </div>
          )}

          {/* Greeting */}
          <div className="mb-8 text-center">
            <h2 className="text-2xl font-semibold text-gray-900">
              {getGreeting()}
            </h2>
          </div>

          {/* Section 1: Recently Visited */}
          <KBQuickStart className="mb-8" />

          {/* Section 2: Recently/Starred Articles */}
          <div className="mb-8 rounded-xl border border-gray-200 bg-white shadow-sm">
            {/* Header with tabs and actions */}
            <div className="border-b border-gray-100 px-5 py-3">
              <div className="mb-3 flex items-center justify-between">
                <h2 className="text-sm font-semibold text-gray-900">
                  {t.knowledgeBase.home.recentlyVisited}
                </h2>
              </div>
              <div className="flex items-center justify-between">
                <div className="flex rounded-lg border border-gray-200 p-0.5">
                  <button
                    onClick={() => setViewMode("recent")}
                    className={cn(
                      "rounded-md px-3 py-1.5 text-sm font-medium transition-colors",
                      viewMode === "recent"
                        ? "bg-blue-100 text-blue-700"
                        : "text-gray-500 hover:text-gray-700",
                    )}
                  >
                    {t.knowledgeBase.home.recent}
                  </button>
                  <button
                    onClick={() => setViewMode("starred")}
                    className={cn(
                      "rounded-md px-3 py-1.5 text-sm font-medium transition-colors",
                      viewMode === "starred"
                        ? "bg-blue-100 text-blue-700"
                        : "text-gray-500 hover:text-gray-700",
                    )}
                  >
                    {t.knowledgeBase.home.starred}
                  </button>
                </div>
                <div className="relative">
                  <Search className="absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-gray-400" />
                  <Input
                    placeholder={t.knowledgeBase.home.searchArticles}
                    className="h-8 w-40 rounded-lg border-gray-200 pl-9 text-sm"
                  />
                </div>
              </div>
            </div>

            {/* Articles Grid with Create Button */}
            <div className="flex gap-4 p-5">
              {/* Articles */}
              <div className="flex-1">
                {loadingArticles ? (
                  <div className="flex items-center justify-center py-12">
                    <Loader2 className="h-6 w-6 animate-spin text-gray-400" />
                  </div>
                ) : hasRealArticles ? (
                  <div className="grid gap-3 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-6">
                    {recentArticles.slice(0, 6).map((article) => (
                      <Link
                        key={article.id}
                        href={
                          article.type === "article"
                            ? `/knowledge-base/articles/${article.id}`
                            : "#"
                        }
                        onClick={(e) => {
                          if (article.type === "document" && article.webUrl) {
                            e.preventDefault();
                            window.open(article.webUrl, "_blank");
                          }
                        }}
                        className="group block"
                      >
                        <div className="rounded-lg border border-gray-100 bg-gray-50 p-3 transition-all hover:border-blue-200 hover:bg-white hover:shadow-sm">
                          <div className="mb-2 flex h-8 w-8 items-center justify-center rounded bg-white">
                            <FileText className="h-4 w-4 text-gray-500" />
                          </div>
                          <p className="truncate text-sm font-medium text-gray-900 group-hover:text-blue-600">
                            {article.title}
                          </p>
                          <p className="mt-1 flex items-center gap-1 text-xs text-gray-400">
                            <Clock className="h-3 w-3" />
                            {article.editedAt
                              ? new Date(article.editedAt).toLocaleDateString()
                              : t.knowledgeBase.time.recently}
                          </p>
                        </div>
                      </Link>
                    ))}
                  </div>
                ) : (
                  /* Empty State with Placeholders */
                  <div className="grid gap-3 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-6">
                    {placeholderArticles.map((article, index) => {
                      const Icon = article.icon;
                      return (
                        <div
                          key={`${index}-${article.title}`}
                          className="group cursor-pointer rounded-lg border border-dashed border-gray-200 bg-gray-50/50 p-3 transition-all hover:border-blue-300 hover:bg-white hover:shadow-sm"
                        >
                          <div
                            className={cn(
                              "mb-2 flex h-8 w-8 items-center justify-center rounded bg-white",
                              article.color.split(" ")[1],
                            )}
                          >
                            <Icon
                              className={cn(
                                "h-4 w-4",
                                article.color.split(" ")[0],
                              )}
                            />
                          </div>
                          <p className="truncate text-sm font-medium text-gray-400 group-hover:text-gray-600">
                            {article.title}
                          </p>
                          <p className="mt-1 flex items-center gap-1 text-xs text-gray-300">
                            <Clock className="h-3 w-3" />
                            {article.time}
                          </p>
                        </div>
                      );
                    })}
                  </div>
                )}
              </div>
            </div>
          </div>

          {/* Section 4: Analytics & Activity */}
          <div className="grid gap-6 lg:grid-cols-2">
            <KBAnalyticsPanel />
            <KBActivityFeed />
          </div>
        </div>
      </main>

      <Dialog open={previewOpen} onOpenChange={setPreviewOpen}>
        <DialogContent className="left-auto right-0 top-0 h-[100dvh] max-h-[100dvh] w-full max-w-2xl translate-x-0 translate-y-0 overflow-hidden rounded-none border-y-0 border-l border-r-0 p-0 sm:max-w-2xl">
          {previewItem && (
            <div className="flex h-full min-h-0 flex-col overflow-hidden">
              <DialogHeader className="border-b border-gray-200 px-6 py-4">
                <DialogTitle className="pr-8 text-base text-gray-900">
                  {previewItem.title}
                </DialogTitle>
                <DialogDescription className="text-xs text-gray-500">
                  {t.knowledgeBase.previewSubtitle}
                </DialogDescription>
              </DialogHeader>

              <div className="min-h-0 flex-1 space-y-4 overflow-y-auto px-6 py-4">
                {previewItem.docType && previewItem.docType !== "GENERAL" && (
                  <div className="flex items-center gap-2 text-xs text-gray-500">
                    <span className="rounded bg-gray-100 px-2 py-0.5">
                      {
                        t.knowledgeBase.docType[
                          previewItem.docType as DocTypeKey
                        ]
                      }
                    </span>
                  </div>
                )}
                <div className="flex flex-wrap items-center gap-3 text-xs text-gray-500">
                  <span>
                    {t.knowledgeBase.previewMetaSource}: {previewSourceLabel}
                  </span>
                  <span>
                    {t.knowledgeBase.previewMetaLength}: {previewCharCount}
                  </span>
                  {previewItem.createdBy && (
                    <span>
                      {t.knowledgeBase.createdBy}: {previewItem.createdBy}
                    </span>
                  )}
                </div>

                {previewLoading && (
                  <div className="flex items-center gap-2 text-sm text-gray-500">
                    <Loader2 className="h-4 w-4 animate-spin" />
                    {t.knowledgeBase.previewLoading}
                  </div>
                )}

                {!previewLoading && previewError && (
                  <PageState
                    variant="error"
                    title={previewError}
                    layout="center"
                    className="border border-dashed border-gray-200 bg-white"
                  />
                )}

                {!previewLoading && !previewError && (
                  <>
                    <div className="rounded-lg border border-gray-200 bg-gray-50 p-4 text-sm leading-7 text-gray-700">
                      {previewText ? (
                        <div className="whitespace-pre-wrap break-words">
                          {renderHighlightedText(previewText, searchKeywords)}
                        </div>
                      ) : (
                        <span className="text-gray-500">
                          {t.knowledgeBase.previewNoContent}
                        </span>
                      )}
                    </div>
                  </>
                )}

                <p className="text-xs text-gray-500">
                  {t.knowledgeBase.previewDocumentExcerptHint}
                </p>
              </div>

              <div className="border-t border-gray-200 px-6 py-4">
                <Button
                  onClick={() => openOriginalResult(previewItem)}
                  className="gap-1.5"
                >
                  {t.knowledgeBase.open}
                </Button>
              </div>
            </div>
          )}
        </DialogContent>
      </Dialog>

      {/* AI Chatbot Floating Button */}
      <KBChatbotButton />
    </div>
  );
}
