import type { ReactNode } from "react"
import type { ExpertDefinition, WorkspaceSummary } from "@qjclaw/shared-types"
import { resolveExpertVisualKey } from "../experts/expertDisplay"
import { buildShortcutPrompt } from "./expertEntries"

export type ExpertProject = WorkspaceSummary["projects"][number]

export interface SidebarExpertEntry {
  definition: ExpertDefinition
  project?: ExpertProject
  displayName: string
  isAvailable: boolean
}

export const CATEGORY_CONFIG = [
  { id: "content", name: "内容营销" },
  { id: "acquisition", name: "精准获客" },
  { id: "sales", name: "销售冠军" },
  { id: "other", name: "其他专家" }
] as const

export type ExpertCategoryId = typeof CATEGORY_CONFIG[number]["id"]

export type ExpertVisualKey =
  | "xiaohongshu"
  | "douyin"
  | "browser"
  | "general"
  | "planner"
  | "zhihu"
  | "wechat"
  | "x"
  | "tiktok"
  | "poster"
  | "geo"
  | "leads"
  | "sales"

export function ExpertCategoryIcon({ kind }: { kind: ExpertCategoryId }) {
  switch (kind) {
    case "content":
      return (
        <svg viewBox="0 0 24 24" aria-hidden="true" focusable="false">
          <path d="M5.4 5.4A2.4 2.4 0 0 1 7.8 3h7.05L19 7.15v10.45a2.4 2.4 0 0 1-2.4 2.4H7.8a2.4 2.4 0 0 1-2.4-2.4V5.4Z" fill="#F5F3FF" stroke="#7C3AED" strokeLinecap="round" strokeLinejoin="round" strokeWidth="1.35" />
          <path d="M14.7 3.2v2.75c0 .78.63 1.41 1.41 1.41h2.7" fill="#EDE9FE" stroke="#A78BFA" strokeLinecap="round" strokeLinejoin="round" strokeWidth="1.25" />
          <path d="M8.5 10.05h6.35M8.5 13h4.55" fill="none" stroke="#6D5DFC" strokeLinecap="round" strokeWidth="1.35" />
          <circle cx="15.85" cy="14.85" r="1.55" fill="#F97316" />
          <path d="M15.85 13.95v1.8M14.95 14.85h1.8" stroke="#FFF7ED" strokeLinecap="round" strokeWidth="1" />
        </svg>
      )
    case "acquisition":
      return (
        <svg viewBox="0 0 24 24" aria-hidden="true" focusable="false">
          <circle cx="12" cy="12" r="7.3" fill="#ECFEFF" stroke="#06B6D4" strokeWidth="1.35" />
          <circle cx="12" cy="12" r="4.45" fill="#DBEAFE" stroke="#2563EB" strokeWidth="1.25" />
          <circle cx="12" cy="12" r="1.72" fill="#22C55E" stroke="#F0FDF4" strokeWidth="0.8" />
          <path d="M12 3.7v2.2M20.3 12h-2.2M12 20.3v-2.2M3.7 12h2.2" fill="none" stroke="#0F766E" strokeLinecap="round" strokeWidth="1.25" />
          <path d="m17.3 5.35 1.25-.8-.35 1.45 1.4.48-1.42.43.3 1.47-1.2-.86-1.1.98.2-1.46-1.45-.32 1.36-.57-.47-1.4 1.25.78.23-.18Z" fill="#F59E0B" />
        </svg>
      )
    case "sales":
      return (
        <svg viewBox="0 0 24 24" aria-hidden="true" focusable="false">
          <path d="M8 5.15h8v2.2a4 4 0 0 1-3 3.88v1.92h2.15a1.35 1.35 0 0 1 1.35 1.35V16H7.5v-1.5a1.35 1.35 0 0 1 1.35-1.35H11v-1.92a4 4 0 0 1-3-3.88v-2.2Z" fill="#FEF3C7" stroke="#D97706" strokeLinecap="round" strokeLinejoin="round" strokeWidth="1.35" />
          <path d="M8 6.05H5.85A1.6 1.6 0 0 0 4.25 7.65c0 1.72 1.39 3.1 3.1 3.1H8m8-4.7h2.15a1.6 1.6 0 0 1 1.6 1.6c0 1.72-1.39 3.1-3.1 3.1H16" fill="#FFFBEB" stroke="#F59E0B" strokeLinecap="round" strokeLinejoin="round" strokeWidth="1.25" />
          <path d="M8.75 16h6.5v3.1h-6.5z" fill="#EDE9FE" stroke="#7C3AED" strokeLinejoin="round" strokeWidth="1.2" />
          <path d="M9.75 20h4.5" stroke="#7C3AED" strokeLinecap="round" strokeWidth="1.35" />
          <path d="m12 7.15.58 1.16 1.28.19-.93.9.22 1.27L12 10.07l-1.15.6.22-1.27-.93-.9 1.28-.19L12 7.15Z" fill="#EF4444" />
        </svg>
      )
    default:
      return (
        <svg viewBox="0 0 24 24" aria-hidden="true" focusable="false">
          <path d="M4.2 7.7A2.2 2.2 0 0 1 6.4 5.5h11.2a2.2 2.2 0 0 1 2.2 2.2v8.1a2.2 2.2 0 0 1-2.2 2.2H6.4a2.2 2.2 0 0 1-2.2-2.2V7.7Z" fill="#EEF2FF" stroke="#4F46E5" strokeLinecap="round" strokeLinejoin="round" strokeWidth="1.35" />
          <path d="M4.85 9.05h14.3" stroke="#60A5FA" strokeLinecap="round" strokeWidth="1.2" />
          <circle cx="7.05" cy="7.35" r="0.72" fill="#22C55E" />
          <circle cx="9.45" cy="7.35" r="0.72" fill="#F59E0B" />
          <path d="M9 12.35h6M9 15h3.7" stroke="#7C3AED" strokeLinecap="round" strokeWidth="1.25" />
          <path d="m16.15 12.1.3.62.68.1-.49.47.12.67-.61-.32-.6.32.11-.67-.49-.47.68-.1.3-.62Z" fill="#EF4444" />
        </svg>
      )
  }
}

function expertMatchesCategory(entry: SidebarExpertEntry, categoryId: ExpertCategoryId): boolean {
  const expertSeed = `${entry.definition.id} ${entry.displayName}`.toLowerCase()
  const isContent = /xiaohongshu|xhs|rednote|小红书|douyin|抖音|content-account|内容账号规划|zhihu|知乎|wechat|公众号|微信/.test(expertSeed)
  const isAcquisition = /geo|precision-leads|精准线索|线索/.test(expertSeed)
  const isSales = /sales-champion|销售冠军|销售/.test(expertSeed)

  if (categoryId === "content") {
    return isContent
  }
  if (categoryId === "acquisition") {
    return isAcquisition
  }
  if (categoryId === "sales") {
    return isSales
  }

  return !(isContent || isAcquisition || isSales)
}

interface ExpertTreeProps {
  entries: SidebarExpertEntry[]
  expandedCategories: Record<string, boolean>
  viewMode: "chat" | "experts" | "tasks" | "automation" | "plugins" | "settings" | "knowledge"
  prompt: string
  activeProjectId?: string
  searchQuery?: string
  onToggleCategory(categoryId: string): void
  onExpertSelect(entry: SidebarExpertEntry): void
  renderCategoryIcon(categoryId: ExpertCategoryId): ReactNode
  renderExpertIcon(expertKey: ExpertVisualKey): ReactNode
}

export function ExpertTree({
  entries,
  expandedCategories,
  viewMode,
  prompt,
  activeProjectId,
  searchQuery = "",
  onToggleCategory,
  onExpertSelect,
  renderCategoryIcon,
  renderExpertIcon
}: ExpertTreeProps) {
  const normalizedSearchQuery = searchQuery.trim().toLocaleLowerCase()
  const isSearching = normalizedSearchQuery.length > 0
  const matchesSearch = (value: string) => value.toLocaleLowerCase().includes(normalizedSearchQuery)
  const sectionMatches = isSearching && matchesSearch("数字员工")
  const visibleCategories = CATEGORY_CONFIG.map((category) => {
    const categoryEntries = entries.filter((entry) => expertMatchesCategory(entry, category.id))
    const categoryMatches = sectionMatches || (isSearching && matchesSearch(category.name))
    const categoryExperts = isSearching && !categoryMatches
      ? categoryEntries.filter((entry) => matchesSearch(entry.displayName) || matchesSearch(entry.definition.id))
      : categoryEntries
    const hasMatchingExperts = categoryExperts.length > 0

    if (isSearching && !categoryMatches && !hasMatchingExperts) {
      return null
    }

    return {
      category,
      categoryExperts,
      hasExperts: categoryEntries.length > 0,
      isExpanded: isSearching ? hasMatchingExperts : expandedCategories[category.id] || false
    }
  }).filter((categoryModel): categoryModel is NonNullable<typeof categoryModel> => categoryModel !== null)

  if (isSearching && visibleCategories.length === 0) {
    return null
  }

  return (
    <section className="sidebar-section compact sidebar-experts-entry">
      <div className="sidebar-section-head sidebar-digital-workers-title">
        <div className="sidebar-section-copy">
          <span className="sidebar-section-icon" aria-hidden="true">🤖</span>
          <strong className="sidebar-section-title">数字员工</strong>
        </div>
      </div>
      <div className="sidebar-expert-scroll">
        <div className="expert-category-list">
          {visibleCategories.map(({ category, categoryExperts, hasExperts, isExpanded }) => {
            const categoryPanelId = `expert-tree-${category.id}`

            return (
              <div key={category.id} className={"expert-category-item expert-tree-category" + (isExpanded && hasExperts ? " expanded" : "")}>
                <button
                  type="button"
                  className="expert-category-header expert-tree-category-trigger app-no-drag"
                  onClick={() => onToggleCategory(category.id)}
                  disabled={!hasExperts}
                  aria-expanded={isExpanded}
                  aria-controls={categoryPanelId}
                >
                  <span className="expert-category-icon" aria-hidden="true">
                    {renderCategoryIcon(category.id)}
                  </span>
                  <div className="expert-category-title">
                    <div className="expert-category-name">{category.name}</div>
                  </div>
                  <div className={`expert-category-toggle ${isExpanded ? "expanded" : ""}`}>
                    <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
                      <path d="M6 9l6 6 6-6" />
                    </svg>
                  </div>
                </button>

                {isExpanded && hasExperts ? (
                  <div id={categoryPanelId} className="expert-category-content expert-tree-list">
                    <div className="expert-category-experts">
                      {categoryExperts.map((entry) => {
                        const expertVisualKey = resolveExpertVisualKey(entry.project, entry.definition)
                        const isStandalone = entry.definition.entryMode === "standalone"
                        const isActive = isStandalone
                          ? viewMode === "experts" && entry.project?.id === activeProjectId
                          : viewMode === "chat" && prompt.trim() === buildShortcutPrompt(entry.definition)

                        return (
                          <button
                            type="button"
                            key={entry.definition.id}
                            className={"expert-category-expert-item expert-tree-expert app-no-drag" + (isActive ? " active" : "")}
                            onClick={() => onExpertSelect(entry)}
                          >
                            <div className="expert-category-expert-icon">
                              {renderExpertIcon(expertVisualKey)}
                            </div>
                            <div className="expert-category-expert-name">{entry.displayName}</div>
                          </button>
                        )
                      })}
                    </div>
                  </div>
                ) : null}
              </div>
            )
          })}
        </div>
      </div>
    </section>
  )
}
