'use client';

import { useCallback, useEffect, useMemo, useState } from 'react';
import { useRouter } from 'next/navigation';
import { Search, FileText, Palette, ClipboardList, Code2, ClipboardCheck, Bug as BugIcon, ExternalLink, CheckCircle2, ChevronRight, ChevronDown, FolderOpen, Layers } from 'lucide-react';
import { useProductStore } from '@/stores/useProductStore';
import { useVersionPlanStore } from '@/stores/useVersionPlanStore';
import { useRequirementStore } from '@/stores/useRequirementStore';
import { useDevTaskStore } from '@/stores/useDevTaskStore';
import { useTestCaseStore } from '@/stores/useTestCaseStore';
import { useBugStore } from '@/stores/useBugStore';
import { useAuthStore } from '@/stores/useAuthStore';
import { useTaskWorklogStore } from '@/stores/useTaskWorklogStore';
import { useWorkActivityStore } from '@/stores/useWorkActivityStore';
import { flattenVersions } from '@/lib/derive';
import { aggregateWorkItems, getWorkspacePendingCountByVersion, WORK_ITEM_TYPE_LABEL } from '@/lib/workspace-engine';
import type { WorkItem, WorkItemType } from '@/lib/workspace-engine';
import { DailyReportPanel } from '@/components/workspace/DailyReportPanel';
import { PlanDetailDrawer } from '@/components/version/PlanDetailDrawer';
import { DevTaskDetailDrawer } from '@/components/dev-task/DevTaskDetailDrawer';
import { TestCaseDetailDrawer } from '@/components/test-case/TestCaseDetailDrawer';
import { BugDetailDrawer } from '@/components/bug/BugDetailDrawer';
import { BugCreateModal } from '@/components/bug/BugCreateModal';
import { DEV_TASK_STATUS_LABEL, DEV_TASK_STATUS_COLOR, getEstimateHours, getActualHours } from '@/lib/dev-task';
import { formatDateTime, formatLocalDate } from '@/lib/format';
import { formatShortTime, formatWorkHours } from '@/lib/work-hours';
import { TEST_CASE_STATUS_LABEL, TEST_CASE_STATUS_COLOR } from '@/lib/test-case';
import { BUG_STATUS_LABEL, BUG_STATUS_COLOR, BUG_SEVERITY_LABEL, BUG_SEVERITY_COLOR } from '@/lib/bug';
import { getWorkspaceDailyReport } from '@/lib/workspace-daily-report';
import { VERSION_STATUS_BG, VERSION_STATUS_LABEL, getVersionReadonlyNotice, isVersionReadonly, type VersionStatus } from '@/lib/version-status';
import { loadV22WorkspaceData, type V22WorkspaceData } from '@/lib/v22-api';
import { selectWorkspaceCollections } from '@/lib/workspace-v22-source';

type TabKey = 'all' | 'plan_research' | 'plan_product' | 'plan_ui' | 'devTask' | 'testCase' | 'bug';
type WorkspaceVersionContext = { id: string; name: string; productName: string; projectName: string; status: VersionStatus };
type TreeVersion = { id: string; name: string; status: VersionStatus; pendingCount: number };
type ProductTree = Map<string, { name: string; projects: Map<string, { name: string; versions: TreeVersion[] }> }>;

const TABS: { key: TabKey; label: string; icon: any }[] = [
  { key: 'all', label: '全部', icon: ClipboardList },
  { key: 'plan_research', label: '调研', icon: Search },
  { key: 'plan_product', label: '产品方案', icon: FileText },
  { key: 'plan_ui', label: 'UI设计', icon: Palette },
  { key: 'devTask', label: '开发任务', icon: Code2 },
  { key: 'testCase', label: '测试用例', icon: ClipboardCheck },
  { key: 'bug', label: 'Bug', icon: BugIcon },
];

const PLAN_STATUS_STYLE: Record<string, string> = {
  pending: 'bg-zinc-100 text-zinc-600',
  in_progress: 'bg-blue-50 text-blue-600',
  completed: 'bg-emerald-50 text-emerald-600',
};
const PLAN_STATUS_LABEL: Record<string, string> = { pending: '未开始', in_progress: '进行中', completed: '已完成' };

export default function WorkspacePage() {
  const router = useRouter();
  const { overview, fetchOverview } = useProductStore();
  const { plans, fetchPlans, loaded: plansLoaded } = useVersionPlanStore();
  const { requirements, fetchRequirements, loaded: requirementsLoaded } = useRequirementStore();
  const { tasks: devTasks, fetchTasks, loaded: devTasksLoaded } = useDevTaskStore();
  const { testCases, fetchTestCases, loaded: testCasesLoaded } = useTestCaseStore();
  const { bugs, fetchBugs, loaded: bugsLoaded } = useBugStore();
  const { worklogs, fetchWorklogs } = useTaskWorklogStore();
  const { activities, fetchActivities } = useWorkActivityStore();
  const user = useAuthStore((s) => s.user);
  const [activeTab, setActiveTab] = useState<TabKey>('all');
  const [showCompleted, setShowCompleted] = useState(true);
  const [selectedVersionId, setSelectedVersionId] = useState<string | null>(null);
  const [drawerItem, setDrawerItem] = useState<WorkItem | null>(null);
  const [bugFromTestCaseId, setBugFromTestCaseId] = useState<string | null>(null);
  const [v22WorkspaceData, setV22WorkspaceData] = useState<V22WorkspaceData | null>(null);
  const [v22WorkspaceLoaded, setV22WorkspaceLoaded] = useState(false);
  const [v22WorkspaceFailed, setV22WorkspaceFailed] = useState(false);

  useEffect(() => { fetchOverview(); }, [fetchOverview]);
  useEffect(() => { fetchWorklogs(); }, [fetchWorklogs]);
  useEffect(() => { fetchActivities(); }, [fetchActivities]);

  const userName = user?.name ?? '';
  const workspaceUserKey = userName || user?.id || '';

  useEffect(() => {
    if (!workspaceUserKey.trim()) {
      setV22WorkspaceData(null);
      setV22WorkspaceLoaded(false);
      setV22WorkspaceFailed(false);
      return;
    }

    let cancelled = false;
    setV22WorkspaceLoaded(false);
    setV22WorkspaceFailed(false);
    loadV22WorkspaceData(workspaceUserKey)
      .then((data) => {
        if (cancelled) return;
        setV22WorkspaceData(data);
        setV22WorkspaceLoaded(true);
      })
      .catch(() => {
        if (cancelled) return;
        setV22WorkspaceData(null);
        setV22WorkspaceFailed(true);
      });

    return () => {
      cancelled = true;
    };
  }, [workspaceUserKey]);

  useEffect(() => {
    if (!workspaceUserKey.trim() || !v22WorkspaceFailed) return;
    void fetchPlans();
    void fetchRequirements();
    void fetchTasks();
    void fetchTestCases();
    void fetchBugs();
  }, [
    fetchBugs,
    fetchPlans,
    fetchRequirements,
    fetchTasks,
    fetchTestCases,
    v22WorkspaceFailed,
    workspaceUserKey,
  ]);

  const allVersions = useMemo(() => flattenVersions(overview), [overview]);

  const versionMap = useMemo(() => {
    const map = new Map<string, WorkspaceVersionContext>();
    allVersions.forEach((v) => map.set(v.id, { id: v.id, name: v.name, productName: v.productName, projectName: v.projectName, status: v.status }));
    return map;
  }, [allVersions]);

  const requirementVersionMap = useMemo(() => {
    const map = new Map<string, string>();
    requirements.forEach((r) => { if (r.versionId) map.set(r.id, r.versionId); });
    return map;
  }, [requirements]);

  const workspaceCollections = useMemo(
    () => selectWorkspaceCollections({
      v22Loaded: v22WorkspaceLoaded,
      v22Failed: v22WorkspaceFailed,
      v22Data: v22WorkspaceData,
      appData: { plans, devTasks, testCases, bugs },
    }),
    [bugs, devTasks, plans, testCases, v22WorkspaceData, v22WorkspaceFailed, v22WorkspaceLoaded],
  );

  const workItems = useMemo(() =>
    aggregateWorkItems(
      userName,
      workspaceCollections.versionPlans,
      workspaceCollections.devTasks,
      workspaceCollections.testCases,
      workspaceCollections.bugs,
      versionMap,
      requirementVersionMap,
    ),
    [userName, workspaceCollections, versionMap, requirementVersionMap]
  );
  const pendingCountByVersion = useMemo(() => getWorkspacePendingCountByVersion(workItems), [workItems]);

  // 构建树：只显示跟自己有关的产品/项目/版本
  const tree = useMemo(() => {
    const myVersionIds = new Set(workItems.map((i) => i.versionId).filter(Boolean));
    const productMap: ProductTree = new Map();

    allVersions.forEach((v) => {
      if (!myVersionIds.has(v.id)) return;
      if (!productMap.has(v.productName)) productMap.set(v.productName, { name: v.productName, projects: new Map() });
      const prod = productMap.get(v.productName)!;
      if (!prod.projects.has(v.projectName)) prod.projects.set(v.projectName, { name: v.projectName, versions: [] });
      const proj = prod.projects.get(v.projectName)!;
      const pending = pendingCountByVersion.get(v.id) ?? 0;
      if (!proj.versions.find((ver) => ver.id === v.id)) {
        proj.versions.push({ id: v.id, name: v.name, status: v.status, pendingCount: pending });
      }
    });

    return productMap;
  }, [allVersions, pendingCountByVersion, workItems]);

  const filteredItems = useMemo(() => {
    let items = workItems;
    if (selectedVersionId) items = items.filter((i) => i.versionId === selectedVersionId);
    if (activeTab !== 'all') items = items.filter((i) => i.type === activeTab);
    if (!showCompleted) items = items.filter((i) => !i.completed);
    return items.sort((a, b) => (a.completed !== b.completed ? (a.completed ? 1 : -1) : 0));
  }, [workItems, activeTab, showCompleted, selectedVersionId]);

  const today = useMemo(() => formatLocalDate(), []);

  const dailyReport = useMemo(() =>
    getWorkspaceDailyReport({
      activities,
      worklogs,
      workItems,
      userId: userName,
      date: today,
    }),
    [activities, worklogs, workItems, userName, today]
  );

  // 待办数量按 tab 分（受 version filter 影响）
  const pendingByTab = useMemo(() => {
    const base = selectedVersionId ? workItems.filter((i) => i.versionId === selectedVersionId) : workItems;
    return {
      all: base.filter((i) => !i.completed).length,
      plan_research: base.filter((i) => i.type === 'plan_research' && !i.completed).length,
      plan_product: base.filter((i) => i.type === 'plan_product' && !i.completed).length,
      plan_ui: base.filter((i) => i.type === 'plan_ui' && !i.completed).length,
      devTask: base.filter((i) => i.type === 'devTask' && !i.completed).length,
      testCase: base.filter((i) => i.type === 'testCase' && !i.completed).length,
      bug: base.filter((i) => i.type === 'bug' && !i.completed).length,
    };
  }, [workItems, selectedVersionId]);

  const pendingCount = pendingByTab.all;
  const completedCount = (selectedVersionId ? workItems.filter((i) => i.versionId === selectedVersionId) : workItems).filter((i) => i.completed).length;
  const selectedVersion = selectedVersionId ? versionMap.get(selectedVersionId) : undefined;
  const drawerVersionStatus = drawerItem ? versionMap.get(drawerItem.versionId)?.status : undefined;
  const drawerReadOnly = drawerVersionStatus ? isVersionReadonly(drawerVersionStatus) : false;
  const ensureWorkspaceDrawerStores = useCallback(async (item: WorkItem) => {
    const pendingLoads: Array<Promise<void>> = [];
    if (!requirementsLoaded) pendingLoads.push(fetchRequirements());
    if ((item.type === 'plan_research' || item.type === 'plan_product' || item.type === 'plan_ui') && !plansLoaded) {
      pendingLoads.push(fetchPlans());
    }
    if (item.type === 'devTask' && !devTasksLoaded) pendingLoads.push(fetchTasks());
    if (item.type === 'testCase' && !testCasesLoaded) pendingLoads.push(fetchTestCases());
    if (item.type === 'bug' && !bugsLoaded) pendingLoads.push(fetchBugs());
    await Promise.all(pendingLoads);
  }, [
    bugsLoaded,
    devTasksLoaded,
    fetchBugs,
    fetchPlans,
    fetchRequirements,
    fetchTasks,
    fetchTestCases,
    plansLoaded,
    requirementsLoaded,
    testCasesLoaded,
  ]);
  const openWorkItemDrawer = useCallback(async (item: WorkItem) => {
    await ensureWorkspaceDrawerStores(item);
    setDrawerItem(item);
  }, [ensureWorkspaceDrawerStores]);

  return (
    <div className="flex h-full">
      {/* 左侧第一列：产品/项目/版本树 */}
      <div className="w-64 shrink-0 border-r border-[var(--line)] bg-[var(--bg-card)] flex flex-col">
        <div className="flex h-14 items-center px-4 border-b border-[var(--line)]">
          <h1 className="text-[14px] font-semibold text-[var(--ink)]">与我相关</h1>
        </div>
        <div className="flex-1 overflow-y-auto p-2">
          <button
            onClick={() => setSelectedVersionId(null)}
            className={`w-full flex items-center gap-2 px-3 py-1.5 rounded-lg text-[12px] mb-1 transition-colors ${!selectedVersionId ? 'bg-[var(--accent-soft)] text-[var(--accent)] font-medium' : 'text-[var(--ink-soft)] hover:bg-[var(--bg-subtle)]'}`}
          >
            <Layers className="h-3 w-3" />
            <span className="flex-1 text-left">全部</span>
            {pendingByTab.all > 0 && !selectedVersionId && (
              <span className="text-[10px] bg-red-500 text-white rounded-full px-1.5 min-w-[18px] text-center">{pendingByTab.all}</span>
            )}
          </button>
          {Array.from(tree.entries()).map(([prodName, prod]) => (
            <ProductNode key={prodName} name={prodName} prod={prod} selectedVersionId={selectedVersionId} onSelect={setSelectedVersionId} />
          ))}
        </div>
      </div>

      {/* 左侧第二列：环节分类 */}
      <div className="w-56 shrink-0 border-r border-[var(--line)] bg-[var(--bg-card)] flex flex-col">
        <div className="flex h-14 items-center px-4 border-b border-[var(--line)]">
          <div className="flex items-center gap-3 text-[11px]">
            <span className="text-[var(--ink-muted)]">待办 <span className="font-medium text-[var(--ink)]">{pendingCount}</span></span>
            <span className="text-[var(--ink-muted)]">完成 <span className="font-medium text-emerald-600">{completedCount}</span></span>
          </div>
        </div>
        <nav className="flex-1 p-2 space-y-0.5">
          {TABS.map((tab) => {
            const Icon = tab.icon;
            const pending = pendingByTab[tab.key];
            const active = activeTab === tab.key;
            return (
              <button
                key={tab.key}
                onClick={() => setActiveTab(tab.key)}
                className={`w-full flex items-center gap-2 px-3 py-2 rounded-lg text-[12px] transition-colors ${active ? 'bg-[var(--accent-soft)] text-[var(--accent)] font-medium' : 'text-[var(--ink-soft)] hover:bg-[var(--bg-subtle)]'}`}
              >
                <Icon className="h-3.5 w-3.5" />
                <span className="flex-1 text-left">{tab.label}</span>
                {pending > 0 && (
                  <span className="text-[10px] bg-red-500 text-white rounded-full px-1.5 min-w-[18px] text-center">{pending}</span>
                )}
              </button>
            );
          })}
        </nav>
        <div className="p-3 border-t border-[var(--line)]">
          <label className="flex items-center gap-2 text-[11px] text-[var(--ink-soft)] cursor-pointer">
            <input type="checkbox" checked={showCompleted} onChange={(e) => setShowCompleted(e.target.checked)} className="h-3.5 w-3.5 rounded" />
            显示已完成
          </label>
        </div>
      </div>

      {/* 右侧：任务列表 */}
      <div className="min-w-0 flex-1 flex flex-col overflow-hidden">
        <header className="flex h-14 shrink-0 items-center border-b border-[var(--line)] bg-[var(--bg-card)] px-5">
          <h2 className="text-[14px] font-semibold text-[var(--ink)]">{TABS.find((t) => t.key === activeTab)?.label}</h2>
          <span className="ml-2 text-[12px] text-[var(--ink-muted)]">{filteredItems.length} 项</span>
          {selectedVersion && (
            <span className="ml-3 inline-flex items-center gap-1.5 rounded-full bg-[var(--accent-soft)] px-2 py-0.5 text-[11px] text-[var(--accent)]">
              <span>{selectedVersion.name}</span>
              <VersionStatusTag status={selectedVersion.status} />
            </span>
          )}
        </header>

        <div className="flex-1 overflow-y-auto p-5 bg-[var(--bg)]">
          {filteredItems.length === 0 ? (
            <div className="rounded-xl border border-dashed border-[var(--line)] bg-[var(--bg-card)] p-12 text-center">
              <p className="text-[13px] text-[var(--ink-muted)]">暂无相关任务</p>
            </div>
          ) : (
            <div className="space-y-2">
              {filteredItems.map((item) => (
                <WorkItemCard
                  key={item.id}
                  item={item}
                  versionStatus={versionMap.get(item.versionId)?.status}
                  onNavigate={() => item.versionId && router.push(`/versions/${item.versionId}`)}
                  onClick={() => { void openWorkItemDrawer(item); }}
                />
              ))}
            </div>
          )}
        </div>
      </div>

      <DailyReportPanel report={dailyReport} />

      {/* Detail Drawers */}
      {drawerItem && (drawerItem.type === 'plan_research' || drawerItem.type === 'plan_product' || drawerItem.type === 'plan_ui') && (
        <PlanDetailDrawer planId={drawerItem.id} readOnly={drawerReadOnly} onClose={() => setDrawerItem(null)} contextLabel={`${drawerItem.productName} / ${drawerItem.projectName} / ${drawerItem.versionName}`} />
      )}
      {drawerItem && drawerItem.type === 'devTask' && (
        <DevTaskDetailDrawer taskId={drawerItem.id} allTaskIds={devTasks.map((t) => t.id)} readOnly={drawerReadOnly} onClose={() => setDrawerItem(null)} contextLabel={`${drawerItem.productName} / ${drawerItem.projectName} / ${drawerItem.versionName}`} />
      )}
      {drawerItem && drawerItem.type === 'testCase' && (
        <TestCaseDetailDrawer testCaseId={drawerItem.id} readOnly={drawerReadOnly} onClose={() => setDrawerItem(null)} onCreateBug={(tcId) => { if (!drawerReadOnly) { setDrawerItem(null); setBugFromTestCaseId(tcId); } }} contextLabel={`${drawerItem.productName} / ${drawerItem.projectName} / ${drawerItem.versionName}`} />
      )}
      {drawerItem && drawerItem.type === 'bug' && (
        <BugDetailDrawer bugId={drawerItem.id} readOnly={drawerReadOnly} onClose={() => setDrawerItem(null)} contextLabel={`${drawerItem.productName} / ${drawerItem.projectName} / ${drawerItem.versionName}`} />
      )}
      {bugFromTestCaseId && (
        <BugCreateModal testCaseId={bugFromTestCaseId} onClose={() => setBugFromTestCaseId(null)} />
      )}
    </div>
  );
}

function ProductNode({ name, prod, selectedVersionId, onSelect }: {
  name: string;
  prod: { name: string; projects: Map<string, { name: string; versions: TreeVersion[] }> };
  selectedVersionId: string | null;
  onSelect: (id: string | null) => void;
}) {
  const [expanded, setExpanded] = useState(true);
  return (
    <div className="mb-0.5">
      <button onClick={() => setExpanded(!expanded)} className="w-full flex items-center gap-1.5 px-2 py-1 rounded text-[11px] font-medium text-[var(--ink-soft)] hover:bg-[var(--bg-subtle)]">
        {expanded ? <ChevronDown className="h-3 w-3 shrink-0" /> : <ChevronRight className="h-3 w-3 shrink-0" />}
        <span className="truncate">{name}</span>
      </button>
      {expanded && Array.from(prod.projects.entries()).map(([projName, proj]) => (
        <ProjectNode key={projName} name={projName} versions={proj.versions} selectedVersionId={selectedVersionId} onSelect={onSelect} />
      ))}
    </div>
  );
}

function ProjectNode({ name, versions, selectedVersionId, onSelect }: {
  name: string;
  versions: TreeVersion[];
  selectedVersionId: string | null;
  onSelect: (id: string | null) => void;
}) {
  const [expanded, setExpanded] = useState(true);
  return (
    <div className="ml-3">
      <button onClick={() => setExpanded(!expanded)} className="w-full flex items-center gap-1.5 px-2 py-1 rounded text-[11px] text-[var(--ink-muted)] hover:bg-[var(--bg-subtle)]">
        {expanded ? <ChevronDown className="h-2.5 w-2.5 shrink-0" /> : <ChevronRight className="h-2.5 w-2.5 shrink-0" />}
        <FolderOpen className="h-3 w-3 shrink-0 text-[var(--ink-muted)]" />
        <span className="truncate">{name}</span>
      </button>
      {expanded && versions.map((v) => (
        <button
          key={v.id}
          onClick={() => onSelect(selectedVersionId === v.id ? null : v.id)}
          className={`w-full flex items-center gap-1.5 ml-5 px-2 py-1 rounded text-[11px] transition-colors ${selectedVersionId === v.id ? 'bg-[var(--accent-soft)] text-[var(--accent)] font-medium' : 'text-[var(--ink-soft)] hover:bg-[var(--bg-subtle)]'}`}
        >
          <span className="flex-1 text-left truncate">{v.name}</span>
          <VersionStatusTag status={v.status} readonlyOnly />
          {v.pendingCount > 0 && (
            <span className="text-[9px] bg-red-500 text-white rounded-full px-1.5 min-w-[16px] text-center">{v.pendingCount}</span>
          )}
        </button>
      ))}
    </div>
  );
}

function VersionStatusTag({ status, readonlyOnly = false }: { status?: VersionStatus; readonlyOnly?: boolean }) {
  if (!status) return null;
  const readonlyNotice = getVersionReadonlyNotice(status);
  if (readonlyOnly && !readonlyNotice) return null;

  return (
    <span
      className={`shrink-0 rounded-md px-1.5 py-0.5 text-[10px] font-medium leading-none ${VERSION_STATUS_BG[status]}`}
      title={readonlyNotice ?? VERSION_STATUS_LABEL[status]}
    >
      {VERSION_STATUS_LABEL[status]}
    </span>
  );
}

function WorkItemCard({ item, versionStatus, onNavigate, onClick }: {
  item: WorkItem;
  versionStatus?: VersionStatus;
  onNavigate: () => void;
  onClick: () => void;
}) {
  const statusBadge = getStatusBadge(item);
  const isDevTask = item.type === 'devTask';
  const devTaskRaw = isDevTask ? (item.raw as any) : null;
  const devEstimate = devTaskRaw ? getEstimateHours(devTaskRaw) : 0;
  const devActual = devTaskRaw ? getActualHours(devTaskRaw) : 0;
  const devOverrun = devActual > devEstimate && devEstimate > 0;
  const devTimeRange = devTaskRaw ? (
    devTaskRaw.actualStartAt
      ? `实际 ${formatShortTime(devTaskRaw.actualStartAt)} → ${devTaskRaw.actualEndAt ? formatShortTime(devTaskRaw.actualEndAt) : '进行中'}`
      : (devTaskRaw.expectedStartAt && devTaskRaw.expectedEndAt
        ? `预计 ${formatShortTime(devTaskRaw.expectedStartAt)} → ${formatShortTime(devTaskRaw.expectedEndAt)}`
        : '')
  ) : '';

  return (
    <div onClick={onClick} className={`rounded-xl border border-[var(--line)] bg-[var(--bg-card)] px-4 py-3 transition-colors hover:border-[var(--accent)] cursor-pointer ${item.completed ? 'opacity-60' : ''}`}>
      <div className="flex items-center gap-3">
        {item.completed && <CheckCircle2 className="h-4 w-4 text-emerald-500 shrink-0" />}
        <span className="text-[10px] font-medium px-2 py-0.5 rounded-full bg-[var(--bg-subtle)] text-[var(--ink-muted)] shrink-0">
          {WORK_ITEM_TYPE_LABEL[item.type]}
        </span>
        {statusBadge}
        {item.extra?.taskNo && <span className="text-[11px] font-mono text-[var(--ink-muted)] shrink-0">{item.extra.taskNo}</span>}
        {item.extra?.caseNo && <span className="text-[11px] font-mono text-[var(--ink-muted)] shrink-0">{item.extra.caseNo}</span>}
        {item.extra?.bugNo && <span className="text-[11px] font-mono text-[var(--ink-muted)] shrink-0">{item.extra.bugNo}</span>}
        <span className="text-[13px] font-medium text-[var(--ink)] flex-1 truncate">{item.title}</span>
        {item.priority && <span className="text-[10px] text-[var(--ink-muted)] shrink-0">{item.priority}</span>}
        {item.extra?.severity && (
          <span className={`text-[10px] px-1.5 py-0.5 rounded shrink-0 ${BUG_SEVERITY_COLOR[item.extra.severity as keyof typeof BUG_SEVERITY_COLOR] || ''}`}>
            {BUG_SEVERITY_LABEL[item.extra.severity as keyof typeof BUG_SEVERITY_LABEL] || ''}
          </span>
        )}
        <button onClick={(e) => { e.stopPropagation(); onNavigate(); }} className="h-6 w-6 flex items-center justify-center rounded text-[var(--ink-muted)] hover:text-[var(--accent)] hover:bg-[var(--bg-subtle)] shrink-0" title="跳转到版本详情">
          <ExternalLink className="h-3.5 w-3.5" />
        </button>
      </div>
      <div className="flex items-center gap-2 mt-1.5 text-[11px] text-[var(--ink-muted)]">
        <span>{item.productName}</span>
        <span className="text-[var(--line)]">/</span>
        <span>{item.projectName}</span>
        <span className="text-[var(--line)]">/</span>
        <button onClick={(e) => { e.stopPropagation(); onNavigate(); }} className="text-[var(--accent)] hover:underline">{item.versionName}</button>
        <VersionStatusTag status={versionStatus} readonlyOnly />
        {isDevTask && devTimeRange && (
          <>
            <span className="ml-2 tabular-nums">{devTimeRange}</span>
            {devEstimate > 0 && (
              <span className={`ml-2 tabular-nums ${devActual > 0 ? (devOverrun ? 'text-red-600' : (devActual < devEstimate ? 'text-emerald-600' : '')) : ''}`}>
                {devActual > 0 ? `${formatWorkHours(devActual)} / ${formatWorkHours(devEstimate)}` : `预 ${formatWorkHours(devEstimate)}`}
              </span>
            )}
          </>
        )}
        {item.extra?.startTime && <span className="ml-2">{formatDateTime(item.extra.startTime)} → {formatDateTime(item.extra.endTime)}</span>}
      </div>
    </div>
  );
}

function getStatusBadge(item: WorkItem) {
  if (item.type === 'devTask') {
    return (
      <span className={`text-[10px] font-medium px-2 py-0.5 rounded-full shrink-0 ${DEV_TASK_STATUS_COLOR[item.status as keyof typeof DEV_TASK_STATUS_COLOR] || 'bg-zinc-100 text-zinc-600'}`}>
        {DEV_TASK_STATUS_LABEL[item.status as keyof typeof DEV_TASK_STATUS_LABEL] || item.status}
      </span>
    );
  }
  if (item.type === 'testCase') {
    return (
      <span className={`text-[10px] font-medium px-2 py-0.5 rounded-full shrink-0 ${TEST_CASE_STATUS_COLOR[item.status as keyof typeof TEST_CASE_STATUS_COLOR] || 'bg-zinc-100 text-zinc-600'}`}>
        {TEST_CASE_STATUS_LABEL[item.status as keyof typeof TEST_CASE_STATUS_LABEL] || item.status}
      </span>
    );
  }
  if (item.type === 'bug') {
    return (
      <span className={`text-[10px] font-medium px-2 py-0.5 rounded-full shrink-0 ${BUG_STATUS_COLOR[item.status as keyof typeof BUG_STATUS_COLOR] || 'bg-zinc-100 text-zinc-600'}`}>
        {BUG_STATUS_LABEL[item.status as keyof typeof BUG_STATUS_LABEL] || item.status}
      </span>
    );
  }
  return (
    <span className={`text-[10px] font-medium px-2 py-0.5 rounded-full shrink-0 ${PLAN_STATUS_STYLE[item.status] || 'bg-zinc-100 text-zinc-600'}`}>
      {PLAN_STATUS_LABEL[item.status] || item.status}
    </span>
  );
}
