import { useMemo, useState, type ReactNode } from "react"
import type { ProjectSessionSummary } from "@qjclaw/shared-types"
import { Sidebar } from "./Sidebar"
import { ExpertTree, type ExpertCategoryId, type ExpertVisualKey, type SidebarExpertEntry } from "./ExpertTree"
import { SessionList } from "./SessionList"

type ViewMode = "chat" | "experts" | "tasks" | "automation" | "plugins" | "settings" | "knowledge"
type SendPhase = "idle" | "preparing" | "streaming" | "finalizing"

interface AppSidebarProps {
  viewMode: ViewMode
  prompt: string
  activeProjectId?: string
  ui: {
    knowledge: string
    plugins: string
    settings: string
    closeSession: string
  }
  showBindEntry: boolean
  projectActionPending: boolean
  sessions: ProjectSessionSummary[]
  activeSessionId: string
  sidebarSessionTitles: Record<string, string>
  sendPhase: SendPhase
  activeStreamSessionId?: string
  sidebarSessionLabel: string
  formatSessionTitle(title: string, index: number): string
  isCollapsed: boolean
  onToggleCollapsed(): void
  navIcon(kind: ViewMode): ReactNode
  onNavSelection(mode: ViewMode): void
  sidebarNewSessionAction: ReactNode
  sidebarExpertEntries: SidebarExpertEntry[]
  expandedCategories: Record<string, boolean>
  onToggleCategory(categoryId: string): void
  onExpertSelect(entry: SidebarExpertEntry): void
  renderCategoryIcon(categoryId: ExpertCategoryId): ReactNode
  renderExpertIcon(expertKey: ExpertVisualKey): ReactNode
  onOpenSession(session: ProjectSessionSummary): void
  onCloseSession(sessionId: string): void
}

export function AppSidebar({
  viewMode,
  prompt,
  activeProjectId,
  ui,
  showBindEntry,
  projectActionPending,
  sessions,
  activeSessionId,
  sidebarSessionTitles,
  sendPhase,
  activeStreamSessionId,
  sidebarSessionLabel,
  formatSessionTitle,
  isCollapsed,
  onToggleCollapsed,
  navIcon,
  onNavSelection,
  sidebarNewSessionAction,
  sidebarExpertEntries,
  expandedCategories,
  onToggleCategory,
  onExpertSelect,
  renderCategoryIcon,
  renderExpertIcon,
  onOpenSession,
  onCloseSession
}: AppSidebarProps) {
  const [sidebarSearchQuery, setSidebarSearchQuery] = useState("")
  const normalizedSidebarSearchQuery = sidebarSearchQuery.trim().toLocaleLowerCase()
  const isSearchingSidebar = normalizedSidebarSearchQuery.length > 0
  const matchesSidebarSearch = (value: string) => value.toLocaleLowerCase().includes(normalizedSidebarSearchQuery)
  const filteredSessions = useMemo(
    () => {
      if (!isSearchingSidebar) {
        return sessions
      }

      if (matchesSidebarSearch(sidebarSessionLabel)) {
        return sessions
      }

      return sessions.filter((session, index) => {
        const title = sidebarSessionTitles[session.id] ?? formatSessionTitle(session.title, index)
        return matchesSidebarSearch(title)
      })
    },
    [formatSessionTitle, isSearchingSidebar, normalizedSidebarSearchQuery, sessions, sidebarSessionLabel, sidebarSessionTitles]
  )
  const headerContent = (
    <label className="sidebar-search app-no-drag">
      <span className="sidebar-search-icon" aria-hidden="true">
        <svg viewBox="0 0 20 20" focusable="false">
          <path d="m14.2 14.2 2.8 2.8M8.9 15.1a6.2 6.2 0 1 1 0-12.4 6.2 6.2 0 0 1 0 12.4Z" />
        </svg>
      </span>
      <input
        type="search"
        value={sidebarSearchQuery}
        placeholder="搜索"
        aria-label="搜索侧栏"
        onChange={(event) => setSidebarSearchQuery(event.target.value)}
      />
    </label>
  )

  const topContent = (
    <>
      <nav className="nav-list" aria-label="主导航">
        {[
          { id: "chat" as const, label: "对话" },
          { id: "tasks" as const, label: "工作台" },
          { id: "knowledge" as const, label: ui.knowledge },
          { id: "automation" as const, label: "自动化任务" },
          { id: "settings" as const, label: ui.settings }
        ].filter((item) => !isSearchingSidebar || matchesSidebarSearch(item.label)).map((item) => (
          <button
            key={item.id}
            type="button"
            className={"nav-item app-no-drag" + (viewMode === item.id ? " active" : "")}
            aria-current={viewMode === item.id ? "page" : undefined}
            onClick={() => onNavSelection(item.id)}
          >
            <span className="nav-item-icon" aria-hidden="true">
              {navIcon(item.id)}
            </span>
            <span className="nav-item-label">{item.label}</span>
          </button>
        ))}
      </nav>
      {!showBindEntry ? <div className="conversation-sidebar-action">{sidebarNewSessionAction}</div> : null}
    </>
  )

  const bottomContent = (
    <>
      <ExpertTree
        entries={sidebarExpertEntries}
        expandedCategories={expandedCategories}
        viewMode={viewMode}
        prompt={prompt}
        activeProjectId={activeProjectId}
        searchQuery={normalizedSidebarSearchQuery}
        onToggleCategory={onToggleCategory}
        onExpertSelect={onExpertSelect}
        renderCategoryIcon={renderCategoryIcon}
        renderExpertIcon={renderExpertIcon}
      />
      <SessionList
        visible={!showBindEntry}
        label={sidebarSessionLabel}
        sessions={filteredSessions}
        totalSessionCount={sessions.length}
        activeSessionId={activeSessionId}
        sessionTitles={sidebarSessionTitles}
        projectActionPending={projectActionPending}
        sendPhase={sendPhase}
        activeStreamSessionId={activeStreamSessionId}
        closeLabel={ui.closeSession}
        formatSessionTitle={formatSessionTitle}
        isFiltering={isSearchingSidebar}
        onOpenSession={onOpenSession}
        onCloseSession={onCloseSession}
      />
    </>
  )

  return (
    <Sidebar
      topContent={topContent}
      bottomContent={bottomContent}
      headerContent={headerContent}
      isCollapsed={isCollapsed}
      onToggleCollapsed={onToggleCollapsed}
    />
  )
}
