'use client';

import { useEffect, useMemo, useState } from 'react';
import { useParams, useRouter } from 'next/navigation';
import { ChevronLeft, Package, Calendar, Clock, ExternalLink, FileText, Palette, Layout, Link2, Settings, Plus, X } from 'lucide-react';
import { useProductStore } from '@/stores/useProductStore';
import { useRequirementStore } from '@/stores/useRequirementStore';
import { useOvertimeStore } from '@/stores/useOvertimeStore';
import { getVersionDetail } from '@/lib/derive';
import { STAGES, Role } from '@/lib/stage';
import { VersionStatus, VERSION_STATUS_LABEL, VERSION_STATUS_BG, getVersionDisplayStatus, calcVersionExecutionStatus, EXECUTION_STATUS_LABEL, EXECUTION_STATUS_COLOR } from '@/lib/version-status';
import { CapsuleStages } from '@/components/version/CapsuleStages';
import { MemberChips } from '@/components/version/MemberChips';
import { HealthTrend, generateMockTrend } from '@/components/version/HealthTrend';
import { calcHealthScore, getHealthLevel, calcRiskTags, HEALTH_LEVEL_COLOR, HEALTH_LEVEL_DOT, HEALTH_LEVEL_LABEL, getTagStyle } from '@/lib/health';
import { REQ_STATUS_LABEL, REQ_STATUS_COLOR } from '@/lib/requirement';
import { OVERTIME_REASON_LABEL } from '@/lib/overtime';
import { VersionRequirementsTab } from '@/components/version/VersionRequirementsTab';
import { PlanTab } from '@/components/version/PlanTab';
import { DevTaskTab } from '@/components/dev-task/DevTaskTab';
import { TestCaseTab } from '@/components/test-case/TestCaseTab';
import { BugTab } from '@/components/bug/BugTab';
import { useVersionPlanStore } from '@/stores/useVersionPlanStore';
import { useDevTaskStore } from '@/stores/useDevTaskStore';
import { useTestCaseStore } from '@/stores/useTestCaseStore';
import { useBugStore } from '@/stores/useBugStore';
import { useAuthStore } from '@/stores/useAuthStore';
import { useMemberStore } from '@/stores/useMemberStore';
import { calcGroupProgress as calcDevTaskProgress, calcActualHoursByDates } from '@/lib/dev-task';

const PRIORITY_STYLE: Record<string, string> = {
  P0: 'bg-red-500/10 text-red-600',
  P1: 'bg-orange-500/10 text-orange-600',
  P2: 'bg-blue-500/10 text-blue-600',
  P3: 'bg-zinc-100 text-zinc-600',
  P4: 'bg-zinc-100 text-zinc-500',
};

const TABS = [
  { key: 'overview', label: '概览' },
  { key: 'requirements', label: '关联需求' },
  { key: 'research', label: '调研' },
  { key: 'product', label: '产品方案' },
  { key: 'ui', label: 'UI设计' },
  { key: 'tasks', label: '开发任务' },
  { key: 'testcases', label: '测试用例' },
  { key: 'bugs', label: 'BUG' },
];

export default function VersionDetailPage() {
  const params = useParams();
  const router = useRouter();
  const versionId = params.id as string;
  const { overview, fetchOverview, updateVersion, deleteVersion } = useProductStore();
  const { requirements, fetchRequirements, updateRequirement } = useRequirementStore();
  const { records, fetchRecords } = useOvertimeStore();
  const { plans, fetchPlans, createPlan, updatePlan, completePlan, deletePlan } = useVersionPlanStore();
  const { tasks: devTasks, fetchTasks: fetchDevTasks, deleteTask: deleteDevTask } = useDevTaskStore();
  const { testCases, fetchTestCases, deleteTestCase } = useTestCaseStore();
  const { bugs, fetchBugs, deleteBug } = useBugStore();
  const user = useAuthStore((s) => s.user);
  const { members: allMembers } = useMemberStore();
  const [activeTab, setActiveTab] = useState('overview');
  const [showMemberModal, setShowMemberModal] = useState(false);

  useEffect(() => { fetchOverview(); }, [fetchOverview]);
  useEffect(() => { fetchRequirements(); }, [fetchRequirements]);
  useEffect(() => { fetchRecords(); }, [fetchRecords]);
  useEffect(() => { fetchPlans(); }, [fetchPlans]);
  useEffect(() => { fetchDevTasks(); }, [fetchDevTasks]);
  useEffect(() => { fetchTestCases(); }, [fetchTestCases]);
  useEffect(() => { fetchBugs(); }, [fetchBugs]);

  const version = useMemo(() => getVersionDetail(overview, versionId), [overview, versionId]);

  // 自动同步版本状态：有计划开始时间<=今天，版本应进入对应阶段
  useEffect(() => {
    if (!version || !plans.length) return;
    if (version.status !== 'planned' && version.status !== 'developing') return;
    const today = new Date().toISOString().slice(0, 10);
    const stageMap = { research: 'requirement', product: 'product_design', ui: 'ui_design' } as const;
    const stageOrder: string[] = ['requirement', 'product_design', 'ui_design'];
    const versionPlans = plans.filter((p) => p.versionId === versionId && p.startTime <= today);
    if (versionPlans.length === 0) return;
    let targetStage = '';
    for (const p of versionPlans) {
      const s = stageMap[p.type];
      if (!targetStage || stageOrder.indexOf(s) > stageOrder.indexOf(targetStage)) {
        targetStage = s;
      }
    }
    if (version.status === 'planned' || (version.currentStage && stageOrder.indexOf(targetStage) > stageOrder.indexOf(version.currentStage))) {
      updateVersion(version.productId, version.id, { status: 'developing', currentStage: targetStage as any });
    }
  }, [plans, version, versionId, updateVersion]);

  const elapsedDays = useMemo(() => {
    if (!version) return 0;
    // 从所有阶段中取最早的实际开始时间
    const vPlans = plans.filter((p) => p.versionId === version.id);
    const vReqs = requirements.filter((r) => r.versionId === version.id);
    const vReqIds = new Set(vReqs.map((r) => r.id));
    const vDevTasks = devTasks.filter((t) => vReqIds.has(t.requirementId));
    const vTCs = testCases.filter((c) => c.versionId === version.id);

    const startDates: string[] = [];
    vPlans.forEach((p) => {
      if (p.actualStartAt) startDates.push(p.actualStartAt);
      else if (p.status === 'pending' && p.startTime && new Date(p.startTime) <= new Date()) startDates.push(p.startTime);
    });
    vDevTasks.forEach((t) => { if (t.startDate) startDates.push(t.startDate); });
    vTCs.forEach((c) => { if (c.startedAt) startDates.push(c.startedAt); });

    if (startDates.length === 0 && !version.startDate) return 0;
    const earliest = startDates.length > 0 ? startDates.sort()[0] : version.startDate!;
    const start = new Date(earliest);
    start.setHours(0, 0, 0, 0);
    const now = new Date();
    now.setHours(0, 0, 0, 0);
    return Math.max(0, Math.floor((now.getTime() - start.getTime()) / (1000 * 60 * 60 * 24)));
  }, [version, plans, requirements, devTasks, testCases]);

  if (!version) {
    return (
      <div className="flex h-full flex-col items-center justify-center gap-3">
        <p className="text-sm text-[var(--ink-muted)]">版本不存在</p>
        <button onClick={() => router.push('/versions')} className="text-xs text-[var(--accent)] hover:underline">返回版本列表</button>
      </div>
    );
  }

  // 权限校验：只有参与人员可以访问
  const currentUserName = user?.name || '';
  const isMember = (version.members ?? []).length === 0 || (version.members ?? []).some((m) => m.name === currentUserName);
  if (!isMember) {
    return (
      <div className="flex h-full flex-col items-center justify-center gap-3">
        <p className="text-sm text-[var(--ink-muted)]">您不是该版本的参与人员，无权访问</p>
        <button onClick={() => router.push('/versions')} className="text-xs text-[var(--accent)] hover:underline">返回版本列表</button>
      </div>
    );
  }

  const healthScore = calcHealthScore(version.status, version.startDate, version.expectedReleaseDate, version.progress);
  const healthLevel = getHealthLevel(healthScore);
  const riskTags = calcRiskTags(version.status, version.startDate, version.expectedReleaseDate, version.progress, version.currentStage, version.members);

  const renderActions = () => {
    const buttons: { label: string; action: () => void; danger?: boolean }[] = [];
    if (version.status === 'planned') {
      buttons.push({ label: '删除', action: () => {
        if (confirm('确认删除该版本？关联的需求会回到需求池，版本下的计划、开发任务、测试用例、Bug 将被清除。')) {
          // 释放关联需求
          requirements.filter((r) => r.versionId === version.id).forEach((r) => updateRequirement(r.id, { versionId: undefined, addedToVersionBy: undefined }));
          // 清理计划任务
          plans.filter((p) => p.versionId === version.id).forEach((p) => deletePlan(p.id));
          // 清理开发任务
          const versionReqIds = new Set(requirements.filter((r) => r.versionId === version.id).map((r) => r.id));
          devTasks.filter((t) => versionReqIds.has(t.requirementId)).forEach((t) => deleteDevTask(t.id));
          // 清理测试用例和Bug
          testCases.filter((c) => c.versionId === version.id).forEach((c) => deleteTestCase(c.id));
          bugs.filter((b) => b.versionId === version.id).forEach((b) => deleteBug(b.id));
          deleteVersion(version.productId, version.id);
          router.push('/versions');
        }
      }, danger: true });
      buttons.push({ label: '关闭', action: () => updateVersion(version.productId, version.id, { status: 'closed' }), danger: true });
    } else if (version.status === 'developing') {
      buttons.push({ label: '暂停', action: () => updateVersion(version.productId, version.id, { status: 'paused' }) });
      buttons.push({ label: '关闭', action: () => updateVersion(version.productId, version.id, { status: 'closed' }), danger: true });
    } else if (version.status === 'paused') {
      buttons.push({ label: '恢复', action: () => updateVersion(version.productId, version.id, { status: 'developing' }) });
      buttons.push({ label: '关闭', action: () => updateVersion(version.productId, version.id, { status: 'closed' }), danger: true });
    }
    return buttons.map((btn) => (
      <button
        key={btn.label}
        onClick={btn.action}
        className={`h-7 px-3 rounded-md text-[12px] font-medium border transition-colors ${btn.danger ? 'border-red-200 text-red-600 hover:bg-red-50' : 'border-[var(--line)] text-[var(--ink-soft)] hover:bg-[var(--bg-subtle)]'}`}
      >
        {btn.label}
      </button>
    ));
  };

  return (
    <div className="flex h-full flex-col">
      {/* Header */}
      <header className="flex h-14 shrink-0 items-center justify-between border-b border-[var(--line)] bg-[var(--bg-card)] px-5">
        <div className="flex items-center">
          <button onClick={() => router.push('/versions')} className="flex items-center gap-1 rounded-md px-1.5 py-1 text-[12px] text-[var(--ink-muted)] hover:bg-[var(--bg-subtle)] hover:text-[var(--ink)]">
            <ChevronLeft className="h-3.5 w-3.5" strokeWidth={2} />版本
          </button>
          <span className="ml-2 text-[var(--ink-muted)]">/</span>
          <button onClick={() => router.push('/products')} className="ml-2 text-[12px] text-[var(--ink-muted)] hover:text-[var(--accent)] hover:underline">{version.productName}</button>
          {version.projectName && version.projectName !== '未关联' && (
            <>
              <span className="ml-1.5 text-[var(--ink-muted)]">/</span>
              <span className="ml-1.5 text-[12px] text-[var(--ink-muted)]">{version.projectName}</span>
            </>
          )}
          <span className="ml-1.5 text-[var(--ink-muted)]">/</span>
          <span className="ml-1.5 text-[15px] font-semibold text-[var(--ink)]">{version.name}</span>
        </div>
        <div className="flex items-center gap-2">{renderActions()}</div>
      </header>

      {/* Tab bar */}
      <div className="flex items-center gap-0 border-b border-[var(--line)] bg-[var(--bg-card)] px-5">
        {TABS.map((tab) => (
          <button
            key={tab.key}
            onClick={() => setActiveTab(tab.key)}
            className={`px-4 py-2.5 text-[13px] font-medium border-b-2 transition-colors ${activeTab === tab.key ? 'border-[var(--accent)] text-[var(--ink)]' : 'border-transparent text-[var(--ink-muted)] hover:text-[var(--ink-soft)]'}`}
          >
            {tab.label}
          </button>
        ))}
      </div>

      {/* Content */}
      <div className="flex-1 overflow-y-auto p-5 bg-[var(--bg)]">
        {activeTab === 'overview' ? (
          (() => {
            const versionReqs = requirements.filter((r) => r.versionId === version.id);
            const versionOT = records.filter((r) => r.versionId === version.id);
            const totalOTHours = Math.round(versionOT.reduce((sum, r) => sum + r.duration, 0) * 10) / 10;

            // 人员加班排名
            const personOT: Record<string, number> = {};
            versionOT.forEach((r) => { personOT[r.person] = (personOT[r.person] || 0) + r.duration; });
            const otRanking = Object.entries(personOT).sort((a, b) => b[1] - a[1]).map(([name, hours]) => ({ name, hours: Math.round(hours * 10) / 10 }));

            // 加班原因占比
            const reasonMap: Record<string, number> = {};
            versionOT.forEach((r) => { reasonMap[r.reasonId] = (reasonMap[r.reasonId] || 0) + r.duration; });
            const reasonRanking = Object.entries(reasonMap).sort((a, b) => b[1] - a[1]);
            const reasonTotal = reasonRanking.reduce((s, [, v]) => s + v, 0) || 1;

            // DevTask 真实统计
            const versionDevTasks = devTasks.filter((t) => versionReqs.some((r) => r.id === t.requirementId));
            const devTaskTodo = versionDevTasks.filter((t) => t.status === 'todo').length;
            const devTaskInProgress = versionDevTasks.filter((t) => t.status === 'in_progress' || t.status === 'testing').length;
            const devTaskBlocked = versionDevTasks.filter((t) => t.isBlocked).length;
            const versionBugs = bugs.filter((b) => b.versionId === version.id);
            const bugOpenCount = versionBugs.filter((b) => b.status === 'open' || b.status === 'fixing').length;

            // 版本执行态推导
            const versionTCs = testCases.filter((c) => c.versionId === version.id);
            const executionStatus = calcVersionExecutionStatus({
              manualStatus: version.status,
              devTasks: versionDevTasks,
              testCases: versionTCs,
              bugs: versionBugs,
            });

            return (
              <div className="space-y-4">
                {/* 1. 风险详情 - 最上方 */}
                {riskTags.length > 0 && (
                  <div className="rounded-xl border border-orange-200 bg-orange-50/40 p-4 max-h-[200px] overflow-y-auto">
                    <div className="flex items-center gap-2 mb-3">
                      <span className="text-[12px] font-semibold text-orange-700">风险详情</span>
                      <span className="text-[10px] text-orange-600">健康度 {healthScore} · {HEALTH_LEVEL_LABEL[healthLevel]}</span>
                    </div>
                    <div className="space-y-2">
                      {riskTags.map((tag) => (
                        <div key={tag.key} className="flex gap-2.5 pb-2 border-b border-orange-100 last:border-b-0 last:pb-0">
                          <span className={`shrink-0 inline-flex items-center rounded border px-1.5 py-0.5 text-[10px] font-medium h-fit mt-0.5 ${getTagStyle(tag.severity)}`}>
                            {tag.label}
                          </span>
                          <div className="flex-1 space-y-0.5 text-[11px]">
                            {tag.reason && <div className="text-[var(--ink-soft)]"><span className="text-[var(--ink-muted)]">原因：</span>{tag.reason}</div>}
                            {tag.suggestion && <div className="text-[var(--ink-soft)]"><span className="text-[var(--ink-muted)]">建议：</span>{tag.suggestion}</div>}
                          </div>
                        </div>
                      ))}
                    </div>
                  </div>
                )}

                {/* 2. 统计卡片 */}
                {(() => {
                  const vPlans = plans.filter((p) => p.versionId === version.id);
                  const pendingResearch = vPlans.filter((p) => p.type === 'research' && p.status !== 'completed').length;
                  const pendingProduct = vPlans.filter((p) => p.type === 'product' && p.status !== 'completed').length;
                  return (
                    <div className="grid grid-cols-4 gap-3 sm:grid-cols-7">
                      <StatCard label="关联需求" value={versionReqs.length} />
                      <StatCard label="待调研" value={pendingResearch} warn={pendingResearch > 0} />
                      <StatCard label="待方案设计" value={pendingProduct} warn={pendingProduct > 0} />
                      <StatCard label="待开发" value={devTaskTodo} />
                      <StatCard label="开发中" value={devTaskInProgress} accent />
                      <StatCard label="未关闭Bug" value={bugOpenCount} warn={bugOpenCount > 0} />
                      <StatCard label="加班时长" value={`${totalOTHours}h`} accent />
                    </div>
                  );
                })()}

                {/* 3. 状态胶囊 */}
                {(() => {
                  const vPlans = plans.filter((p) => p.versionId === version.id);
                  const researchPlans = vPlans.filter((p) => p.type === 'research');
                  const productPlans = vPlans.filter((p) => p.type === 'product');
                  const uiPlans = vPlans.filter((p) => p.type === 'ui');

                  const calcGroupProgress = (group: typeof vPlans, type: 'research' | 'product' | 'ui') => {
                    if (group.length === 0) return 0;
                    // 分子=已完成子任务数，分母=所有plan的子任务总数
                    // completed 的 plan：其子任务全算已完成
                    let totalItems = 0;
                    let doneItems = 0;
                    for (const p of group) {
                      if (type === 'research') {
                        const tasks = p.tasks || [];
                        const count = Math.max(tasks.length, 1);
                        totalItems += count;
                        if (p.status === 'completed') {
                          doneItems += count;
                        } else {
                          doneItems += tasks.filter((t) => t.status === 'completed').length;
                        }
                      } else {
                        const linked = p.linkedRequirementIds || [];
                        const count = Math.max(linked.length, 1);
                        totalItems += count;
                        if (p.status === 'completed') {
                          doneItems += count;
                        } else {
                          const completed = p.completedRequirementIds || [];
                          doneItems += completed.filter((id) => linked.includes(id)).length;
                        }
                      }
                    }
                    return totalItems > 0 ? Math.round((doneItems / totalItems) * 100) : 0;
                  };

                  const getPlanStatus = (group: typeof vPlans): 'idle' | 'active' | 'done' => {
                    if (group.length === 0) return 'idle';
                    if (group.every((p) => p.status === 'completed')) return 'done';
                    if (group.some((p) => p.status === 'in_progress')) return 'active';
                    return 'idle';
                  };

                  type StageProgressItem = { percent: number; status: 'idle' | 'active' | 'done' };
                  const stageProgress: Partial<Record<string, StageProgressItem>> = {};

                  if (researchPlans.length > 0) stageProgress['requirement'] = { percent: calcGroupProgress(researchPlans, 'research'), status: getPlanStatus(researchPlans) };
                  if (productPlans.length > 0) stageProgress['product_design'] = { percent: calcGroupProgress(productPlans, 'product'), status: getPlanStatus(productPlans) };
                  if (uiPlans.length > 0) stageProgress['ui_design'] = { percent: calcGroupProgress(uiPlans, 'ui'), status: getPlanStatus(uiPlans) };

                  // 开发阶段
                  if (versionDevTasks.length > 0) {
                    const devProgress = calcDevTaskProgress(versionDevTasks);
                    const allSubmitted = versionDevTasks.every((t) => t.status === 'submitted');
                    const hasActive = versionDevTasks.some((t) => t.status === 'in_progress' || t.status === 'testing');
                    stageProgress['dev'] = { percent: devProgress, status: allSubmitted ? 'done' : hasActive ? 'active' : 'idle' };
                  }

                  // 测试阶段
                  if (versionTCs.length > 0) {
                    const executed = versionTCs.filter((c) => c.status === 'passed' || c.status === 'failed' || c.status === 'blocked').length;
                    const testPercent = Math.round((executed / versionTCs.length) * 100);
                    const allPassed = versionTCs.every((c) => c.status === 'passed');
                    const hasRunning = versionTCs.some((c) => c.status === 'running');
                    stageProgress['testing'] = { percent: testPercent, status: allPassed ? 'done' : (hasRunning || executed > 0) ? 'active' : 'idle' };
                  }

                  // BUG 阶段：已关闭Bug / 总Bug
                  if (versionBugs.length > 0) {
                    const closedBugs = versionBugs.filter((b) => b.status === 'closed' || b.status === 'rejected').length;
                    const bugPercent = Math.round((closedBugs / versionBugs.length) * 100);
                    const allClosed = versionBugs.every((b) => b.status === 'closed' || b.status === 'rejected');
                    stageProgress['bug'] = { percent: bugPercent, status: allClosed ? 'done' : closedBugs > 0 || versionBugs.length > 0 ? 'active' : 'idle' };
                  }

                  return <CapsuleStages stageProgress={stageProgress as any} />;
                })()}

                {/* 4. 项目总耗时 + 参与人员 + 相关链接 */}
                <div className="space-y-4">
                  <div className="rounded-xl border border-[var(--line)] bg-[var(--bg-card)] p-4">
                    {(() => {
                      // 实际开始日期
                      const vPlansAll = plans.filter((p) => p.versionId === version.id);
                      const vReqsAll = requirements.filter((r) => r.versionId === version.id);
                      const vReqIdsAll = new Set(vReqsAll.map((r) => r.id));
                      const vDTs = devTasks.filter((t) => vReqIdsAll.has(t.requirementId));
                      const vTCsAll = testCases.filter((c) => c.versionId === version.id);
                      const vBugsAll = bugs.filter((b) => b.versionId === version.id);

                      const startDates: string[] = [];
                      vPlansAll.forEach((p) => {
                        if (p.actualStartAt) startDates.push(p.actualStartAt);
                        else if (p.status === 'pending' && p.startTime && new Date(p.startTime) <= new Date()) startDates.push(p.startTime);
                      });
                      vDTs.forEach((t) => { if (t.startDate) startDates.push(t.startDate); });
                      vTCsAll.forEach((c) => { if (c.startedAt) startDates.push(c.startedAt); });
                      const actualStart = startDates.length > 0 ? startDates.sort()[0].slice(0, 16).replace('T', ' ') : (version.startDate ?? null);

                      // 实际截止日期
                      const endDates: string[] = [];
                      vPlansAll.forEach((p) => { if (p.completedAt) endDates.push(p.completedAt); });
                      vDTs.forEach((t) => { if (t.completedAt) endDates.push(t.completedAt); });
                      vTCsAll.forEach((c) => { if (c.completedAt) endDates.push(c.completedAt); });
                      vBugsAll.forEach((b) => { if (b.closedAt) endDates.push(b.closedAt); });
                      const actualEnd = endDates.length > 0 ? endDates.sort().reverse()[0].slice(0, 16).replace('T', ' ') : null;

                      // 逾期天数
                      const deadline = version.expectedReleaseDate;
                      let overdueDays = 0;
                      if (deadline && actualEnd) {
                        overdueDays = Math.floor((new Date(actualEnd.replace(' ', 'T')).getTime() - new Date(deadline).getTime()) / (1000 * 60 * 60 * 24));
                      }

                      // 总耗时 = 日历天数 + 加班时长
                      const versionOTForTime = records.filter((r) => r.versionId === version.id);
                      const otHoursTotal = Math.round(versionOTForTime.reduce((sum, r) => sum + r.duration, 0) * 10) / 10;

                      return (
                        <div className="flex flex-wrap items-center gap-x-4 gap-y-2 text-[13px]">
                          <div className="flex items-center gap-1.5">
                            <Calendar className="h-3.5 w-3.5 text-[var(--ink-muted)]" />
                            <span className="text-[var(--ink-muted)]">开始</span>
                            <span className="text-[var(--ink)]">{actualStart ?? '未开始'}</span>
                          </div>
                          <div className="flex items-center gap-1.5">
                            <span className="text-[var(--ink-muted)]">预计截止</span>
                            <span className="text-[var(--ink)]">{deadline ?? '未设置'}</span>
                          </div>
                          {actualEnd && (
                            <div className="flex items-center gap-1.5">
                              <span className="text-[var(--ink-muted)]">实际截止</span>
                              <span className="text-[var(--ink)]">{actualEnd}</span>
                            </div>
                          )}
                          {overdueDays > 0 && (
                            <span className="text-[11px] font-medium px-2 py-0.5 rounded-full bg-red-50 text-red-600">逾期 {overdueDays} 天</span>
                          )}
                          <div className="flex items-center gap-1.5 text-[var(--ink-soft)]">
                            <Clock className="h-3.5 w-3.5 text-[var(--ink-muted)]" />
                            已耗时 <span className="font-medium text-[var(--ink)]">{elapsedDays}</span> 天
                            {otHoursTotal > 0 && (
                              <span className="text-[var(--ink-muted)]">（含加班 <span className="font-medium text-orange-600">{otHoursTotal}h</span>）</span>
                            )}
                          </div>
                        </div>
                      );
                    })()}
                  </div>
                  <div className="grid grid-cols-2 gap-4">
                    <div className="rounded-xl border border-[var(--line)] bg-[var(--bg-card)] p-4">
                      <div className="flex items-center justify-between mb-2">
                        <div className="text-[11px] text-[var(--ink-muted)] font-medium">参与人员</div>
                        <button onClick={() => setShowMemberModal(true)} className="flex items-center gap-1 text-[11px] text-[var(--accent)] hover:underline">
                          <Settings className="h-3 w-3" />设置
                        </button>
                      </div>
                      {(() => {
                        const membersList = version.members ?? [];
                        const roleLabel: Record<string, string> = { research: '调研', product: '产品', ui: 'UI', frontend: '前端', backend: '后端', testing: '测试' };
                        if (membersList.length === 0) return <span className="text-[12px] text-[var(--ink-muted)]">暂无成员，请点击设置添加</span>;
                        return (
                          <div className="flex flex-wrap gap-1.5">
                            {membersList.map((m, i) => (
                              <span key={`${m.name}-${i}`} className="inline-flex items-center gap-1 rounded-full bg-[var(--bg-subtle)] px-2.5 py-1 text-[11px] text-[var(--ink-soft)]">
                                <span className="text-[var(--ink-muted)]">{roleLabel[m.role] ?? m.role}</span>
                                <span className="font-medium text-[var(--ink)]">{m.name}</span>
                              </span>
                            ))}
                          </div>
                        );
                      })()}
                    </div>
                    <div className="rounded-xl border border-[var(--line)] bg-[var(--bg-card)] p-4">
                      <div className="text-[11px] text-[var(--ink-muted)] mb-3 font-medium">相关链接</div>
                      {(() => {
                        const vPlansCompleted = plans.filter((p) => p.versionId === version.id && p.status === 'completed' && p.resultUrl);
                        const typeLabel: Record<string, string> = { research: '调研', product: '产品方案', ui: 'UI设计' };
                        const grouped = ['research', 'product', 'ui'].map((type) => ({
                          type,
                          label: typeLabel[type],
                          items: vPlansCompleted.filter((p) => p.type === type),
                        })).filter((g) => g.items.length > 0);

                        if (grouped.length === 0) {
                          return <span className="text-[12px] text-[var(--ink-muted)]">暂无成果链接</span>;
                        }
                        return (
                          <div className="space-y-3">
                            {grouped.map((g) => (
                              <div key={g.type}>
                                <div className="text-[10px] text-[var(--ink-muted)] mb-1">{g.label}</div>
                                <div className="space-y-1.5">
                                  {g.items.map((p) => (
                                    <a key={p.id} href={p.resultUrl} target="_blank" rel="noopener noreferrer" className="flex items-center gap-1.5 text-[12px] text-[var(--accent)] hover:underline">
                                      {p.resultType === 'file' ? <FileText className="h-3 w-3" /> : <Link2 className="h-3 w-3" />}
                                      <span className="truncate">{p.resultFileName || p.title}</span>
                                    </a>
                                  ))}
                                </div>
                              </div>
                            ))}
                          </div>
                        );
                      })()}
                    </div>
                  </div>
                </div>

                {/* 5. 加班时长排名 + 加班原因占比 */}
                <div className="grid grid-cols-2 gap-4">
                  {/* 参与人员加班排名 */}
                  <div className="rounded-xl border border-[var(--line)] bg-[var(--bg-card)] p-4">
                    <div className="text-[11px] text-[var(--ink-muted)] mb-3 font-medium">加班时长排名</div>
                    {otRanking.length === 0 ? (
                      <span className="text-[12px] text-[var(--ink-muted)]">暂无数据</span>
                    ) : (
                      <div className="space-y-2">
                        {otRanking.slice(0, 8).map((item, i) => (
                          <div key={item.name} className="flex items-center gap-2">
                            <span className={`flex h-5 w-5 items-center justify-center rounded-full text-[10px] font-semibold ${i < 3 ? 'bg-[var(--accent-soft)] text-[var(--accent)]' : 'bg-[var(--bg-subtle)] text-[var(--ink-muted)]'}`}>{i + 1}</span>
                            <span className="flex-1 text-[12px] text-[var(--ink)]">{item.name}</span>
                            <span className="text-[12px] font-medium tabular-nums text-[var(--ink-soft)]">{item.hours}h</span>
                          </div>
                        ))}
                      </div>
                    )}
                  </div>

                  {/* 加班原因占比 - 饼图 */}
                  <div className="rounded-xl border border-[var(--line)] bg-[var(--bg-card)] p-4">
                    <div className="text-[11px] text-[var(--ink-muted)] mb-3 font-medium">加班原因占比</div>
                    {reasonRanking.length === 0 ? (
                      <span className="text-[12px] text-[var(--ink-muted)]">暂无数据</span>
                    ) : (
                      <div className="flex items-center gap-4">
                        {/* SVG 环形饼图 */}
                        <svg viewBox="0 0 100 100" className="h-28 w-28 shrink-0">
                          {(() => {
                            const colors = ['#3b82f6', '#f97316', '#8b5cf6', '#10b981', '#ef4444', '#f59e0b', '#6366f1', '#ec4899'];
                            let cumPercent = 0;
                            return reasonRanking.map(([reasonId, hours], i) => {
                              const percent = hours / reasonTotal;
                              const startAngle = cumPercent * 360;
                              cumPercent += percent;
                              const endAngle = cumPercent * 360;
                              const largeArc = percent > 0.5 ? 1 : 0;
                              const startRad = ((startAngle - 90) * Math.PI) / 180;
                              const endRad = ((endAngle - 90) * Math.PI) / 180;
                              const x1 = 50 + 40 * Math.cos(startRad);
                              const y1 = 50 + 40 * Math.sin(startRad);
                              const x2 = 50 + 40 * Math.cos(endRad);
                              const y2 = 50 + 40 * Math.sin(endRad);
                              if (percent >= 1) {
                                return <circle key={reasonId} cx="50" cy="50" r="40" fill={colors[i % colors.length]} />;
                              }
                              return (
                                <path
                                  key={reasonId}
                                  d={`M 50 50 L ${x1} ${y1} A 40 40 0 ${largeArc} 1 ${x2} ${y2} Z`}
                                  fill={colors[i % colors.length]}
                                />
                              );
                            });
                          })()}
                          <circle cx="50" cy="50" r="22" fill="var(--bg-card)" />
                        </svg>
                        {/* 图例 */}
                        <div className="space-y-1.5 flex-1">
                          {reasonRanking.map(([reasonId, hours], i) => {
                            const colors = ['#3b82f6', '#f97316', '#8b5cf6', '#10b981', '#ef4444', '#f59e0b', '#6366f1', '#ec4899'];
                            const percent = Math.round((hours / reasonTotal) * 100);
                            const reasonName = OVERTIME_REASON_LABEL[reasonId] || reasonId;
                            return (
                              <div key={reasonId} className="flex items-center gap-2 text-[11px]">
                                <span className="h-2.5 w-2.5 rounded-sm shrink-0" style={{ backgroundColor: colors[i % colors.length] }} />
                                <span className="flex-1 text-[var(--ink-soft)] truncate">{reasonName}</span>
                                <span className="tabular-nums text-[var(--ink-muted)]">{percent}%</span>
                              </div>
                            );
                          })}
                        </div>
                      </div>
                    )}
                  </div>
                </div>

                {/* 阶段耗时 + 个人耗时排名 */}
                {(() => {
                  const versionPlans = plans.filter((p) => p.versionId === version.id);

                  // 各阶段日历天数计算辅助函数
                  const calcCalendar = (starts: string[], ends: string[]) => {
                    const sortedStarts = starts.filter(Boolean).sort();
                    const sortedEnds = ends.filter(Boolean).sort().reverse();
                    const start = sortedStarts[0] || null;
                    const end = sortedEnds[0] || null;
                    const days = start && end ? Math.max(1, Math.ceil((new Date(end).getTime() - new Date(start).getTime()) / (1000 * 60 * 60 * 24)) + 1) : 0;
                    return { start, end, days };
                  };

                  // 调研阶段
                  const researchPlans = versionPlans.filter((p) => p.type === 'research');
                  const researchCal = calcCalendar(
                    researchPlans.filter((p) => p.actualStartAt).map((p) => p.actualStartAt!),
                    researchPlans.filter((p) => p.completedAt).map((p) => p.completedAt!),
                  );

                  // 产品方案阶段
                  const productPlans = versionPlans.filter((p) => p.type === 'product');
                  const productCal = calcCalendar(
                    productPlans.filter((p) => p.actualStartAt).map((p) => p.actualStartAt!),
                    productPlans.filter((p) => p.completedAt).map((p) => p.completedAt!),
                  );

                  // UI设计阶段
                  const uiPlans = versionPlans.filter((p) => p.type === 'ui');
                  const uiCal = calcCalendar(
                    uiPlans.filter((p) => p.actualStartAt).map((p) => p.actualStartAt!),
                    uiPlans.filter((p) => p.completedAt).map((p) => p.completedAt!),
                  );

                  // 开发阶段
                  const devCal = calcCalendar(
                    versionDevTasks.filter((t) => t.startDate).map((t) => t.startDate!),
                    versionDevTasks.filter((t) => t.completedAt).map((t) => t.completedAt!),
                  );

                  // 测试阶段
                  const tcCal = calcCalendar(
                    versionTCs.filter((c) => c.startedAt).map((c) => c.startedAt!),
                    versionTCs.filter((c) => c.completedAt).map((c) => c.completedAt!),
                  );

                  const stages = [
                    { label: '调研', ...researchCal, color: 'bg-orange-400' },
                    { label: '产品方案', ...productCal, color: 'bg-pink-400' },
                    { label: 'UI设计', ...uiCal, color: 'bg-indigo-400' },
                    { label: '开发', ...devCal, color: 'bg-blue-400' },
                    { label: '测试', ...tcCal, color: 'bg-purple-400' },
                  ];
                  const maxDays = Math.max(...stages.map((s) => s.days), 1);

                  // 个人维度：每人耗时汇总
                  const personalHours = new Map<string, { research: number; product: number; ui: number; dev: number; test: number }>();
                  const addHours = (name: string, key: 'research' | 'product' | 'ui' | 'dev' | 'test', hours: number) => {
                    const prev = personalHours.get(name) || { research: 0, product: 0, ui: 0, dev: 0, test: 0 };
                    prev[key] += hours;
                    personalHours.set(name, prev);
                  };

                  // 调研/产品/UI 用 startTime→endTime 计算
                  versionPlans.forEach((p) => {
                    if (!p.owner || !p.actualStartAt) return;
                    const hours = calcActualHoursByDates(p.actualStartAt, p.completedAt);
                    addHours(p.owner, p.type === 'research' ? 'research' : p.type === 'product' ? 'product' : 'ui', hours);
                  });
                  versionDevTasks.forEach((t) => {
                    if (!t.startDate || !t.assigneeId) return;
                    addHours(t.assigneeId, 'dev', calcActualHoursByDates(t.startDate, t.completedAt));
                  });
                  versionTCs.forEach((c) => {
                    if (!c.startedAt || !c.assigneeId) return;
                    addHours(c.assigneeId, 'test', calcActualHoursByDates(c.startedAt, c.completedAt));
                  });

                  const personalRanking = Array.from(personalHours.entries())
                    .map(([name, h]) => ({ name, ...h, total: h.research + h.product + h.ui + h.dev + h.test }))
                    .sort((a, b) => b.total - a.total);
                  const maxHours = personalRanking[0]?.total || 1;
                  const totalHours = personalRanking.reduce((s, p) => s + p.total, 0);

                  return (
                    <div className="grid grid-cols-2 gap-4">
                      {/* 阶段日历耗时 */}
                      <div className="rounded-xl border border-[var(--line)] bg-[var(--bg-card)] p-4">
                        <div className="text-[11px] text-[var(--ink-muted)] mb-3 font-medium">阶段耗时（项目维度）</div>
                        <div className="space-y-2.5">
                          {stages.map((s) => (
                            <div key={s.label}>
                              <div className="flex items-center justify-between mb-1">
                                <span className="text-[12px] text-[var(--ink-soft)]">{s.label}</span>
                                <span className="text-[12px] font-medium tabular-nums text-[var(--ink)]">{s.days > 0 ? `${s.days}天` : '-'}</span>
                              </div>
                              <div className="flex items-center gap-2">
                                <div className="flex-1 h-1.5 rounded-full bg-[var(--bg-subtle)] overflow-hidden">
                                  <div className={`h-full rounded-full ${s.color}`} style={{ width: `${(s.days / maxDays) * 100}%` }} />
                                </div>
                                {s.start && <span className="text-[9px] text-[var(--ink-muted)] shrink-0 tabular-nums">{s.start.slice(5)}{s.end ? ` → ${s.end.slice(5)}` : ' →'}</span>}
                              </div>
                            </div>
                          ))}
                          <div className="pt-2 border-t border-[var(--line)]">
                            <div className="flex items-center justify-between">
                              <span className="text-[12px] text-[var(--ink-soft)]">总人天投入</span>
                              <span className="text-[12px] font-medium tabular-nums text-[var(--ink)]">{totalHours}h（{Math.round(totalHours / 8)}人天）</span>
                            </div>
                          </div>
                        </div>
                      </div>

                      {/* 个人耗时排名 */}
                      <div className="rounded-xl border border-[var(--line)] bg-[var(--bg-card)] p-4">
                        <div className="text-[11px] text-[var(--ink-muted)] mb-3 font-medium">个人耗时排名</div>
                        {personalRanking.length === 0 ? (
                          <span className="text-[12px] text-[var(--ink-muted)]">暂无数据</span>
                        ) : (
                          <div className="space-y-2">
                            {personalRanking.slice(0, 8).map((item, i) => (
                              <div key={item.name}>
                                <div className="flex items-center gap-2 mb-1">
                                  <span className={`flex h-5 w-5 items-center justify-center rounded-full text-[10px] font-semibold ${i < 3 ? 'bg-[var(--accent-soft)] text-[var(--accent)]' : 'bg-[var(--bg-subtle)] text-[var(--ink-muted)]'}`}>{i + 1}</span>
                                  <span className="flex-1 text-[12px] text-[var(--ink)]">{item.name}</span>
                                  <span className="text-[12px] font-medium tabular-nums text-[var(--ink-soft)]">{item.total}h</span>
                                </div>
                                <div className="ml-7 flex items-center gap-0.5 h-1.5">
                                  {item.research > 0 && <div className="h-full rounded-full bg-orange-400" style={{ width: `${(item.research / maxHours) * 100}%` }} title={`调研 ${item.research}h`} />}
                                  {item.product > 0 && <div className="h-full rounded-full bg-pink-400" style={{ width: `${(item.product / maxHours) * 100}%` }} title={`产品 ${item.product}h`} />}
                                  {item.ui > 0 && <div className="h-full rounded-full bg-indigo-400" style={{ width: `${(item.ui / maxHours) * 100}%` }} title={`UI ${item.ui}h`} />}
                                  {item.dev > 0 && <div className="h-full rounded-full bg-blue-400" style={{ width: `${(item.dev / maxHours) * 100}%` }} title={`开发 ${item.dev}h`} />}
                                  {item.test > 0 && <div className="h-full rounded-full bg-purple-400" style={{ width: `${(item.test / maxHours) * 100}%` }} title={`测试 ${item.test}h`} />}
                                </div>
                              </div>
                            ))}
                            <div className="flex items-center gap-3 pt-2 text-[10px] text-[var(--ink-muted)] flex-wrap">
                              <span className="flex items-center gap-1"><span className="h-2 w-2 rounded-full bg-orange-400" />调研</span>
                              <span className="flex items-center gap-1"><span className="h-2 w-2 rounded-full bg-pink-400" />产品</span>
                              <span className="flex items-center gap-1"><span className="h-2 w-2 rounded-full bg-indigo-400" />UI</span>
                              <span className="flex items-center gap-1"><span className="h-2 w-2 rounded-full bg-blue-400" />开发</span>
                              <span className="flex items-center gap-1"><span className="h-2 w-2 rounded-full bg-purple-400" />测试</span>
                            </div>
                          </div>
                        )}
                      </div>
                    </div>
                  );
                })()}

                {/* 健康趋势 - 暂时不显示 */}
                {/* <div className="rounded-xl border border-[var(--line)] bg-[var(--bg-card)] p-4 max-w-[320px]">
                  <span className="text-[11px] font-medium text-[var(--ink-muted)] mb-2 block">健康趋势</span>
                  <HealthTrend data={generateMockTrend(healthScore, 7)} />
                </div> */}
              </div>
            );
          })()
        ) : activeTab === 'requirements' ? (
          <VersionRequirementsTab
            versionId={version.id}
            projectId={version.projectId}
            requirements={requirements}
            devTasks={devTasks}
            currentUserName={user?.name ?? ''}
            onLink={(ids, addedBy) => {
              ids.forEach((id) => updateRequirement(id, { versionId: version.id, addedToVersionBy: addedBy }));
            }}
            onUnlink={(id) => updateRequirement(id, { versionId: undefined, addedToVersionBy: undefined })}
          />
        ) : (activeTab === 'research' || activeTab === 'product' || activeTab === 'ui') ? (
          (() => {
            const pt = activeTab as 'research' | 'product' | 'ui';
            const versionReqs = requirements.filter((r) => r.versionId === version.id);
            const linkedReqs = versionReqs.map((r) => ({ id: r.id, title: r.title, code: r.code, productOwner: r.productOwner }));
            return (
              <PlanTab
                plans={plans}
                versionId={version.id}
                versionDeadline={version.expectedReleaseDate ?? undefined}
                currentUserName={user?.name ?? ''}
                planType={pt}
                linkedRequirements={pt !== 'research' ? linkedReqs : undefined}
                onCreate={(data) => {
                  createPlan(data);
                  if ((pt === 'product') && data.linkedRequirementIds?.length) {
                    data.linkedRequirementIds.forEach((rid) => updateRequirement(rid, { productOwner: data.owner }));
                  }
                  // 同步版本状态：计划开始时间<=今天，版本进入对应阶段
                  const today = new Date().toISOString().slice(0, 10);
                  if (data.startTime <= today && (version.status === 'planned' || version.status === 'developing')) {
                    const stageMap = { research: 'requirement', product: 'product_design', ui: 'ui_design' } as const;
                    updateVersion(version.productId, version.id, { status: 'developing', currentStage: stageMap[pt] });
                  }
                }}
                onUpdate={(id, data) => {
                  updatePlan(id, data);
                  if ((pt === 'product') && data.linkedRequirementIds && data.owner) {
                    data.linkedRequirementIds.forEach((rid) => updateRequirement(rid, { productOwner: data.owner }));
                  }
                }}
                onComplete={completePlan}
                onDelete={deletePlan}
              />
            );
          })()
        ) : activeTab === 'tasks' ? (
          (() => {
            const versionReqs = requirements.filter((r) => r.versionId === version.id);
            return (
              <DevTaskTab
                versionId={version.id}
                requirementIds={versionReqs.map((r) => r.id)}
                versionDeadline={version.expectedReleaseDate ?? undefined}
              />
            );
          })()
        ) : activeTab === 'testcases' ? (
          (() => {
            const versionReqs = requirements.filter((r) => r.versionId === version.id);
            return <TestCaseTab versionId={version.id} requirementIds={versionReqs.map((r) => r.id)} />;
          })()
        ) : activeTab === 'bugs' ? (
          (() => {
            const versionReqs = requirements.filter((r) => r.versionId === version.id);
            return <BugTab versionId={version.id} requirementIds={versionReqs.map((r) => r.id)} />;
          })()
        ) : (
          <div className="rounded-xl border border-[var(--line)] bg-[var(--bg-card)] p-12 flex items-center justify-center">
            <span className="text-[13px] text-[var(--ink-muted)]">功能开发中，敬请期待</span>
          </div>
        )}
      </div>

      {/* 参与人员设置弹窗 */}
      {showMemberModal && (
        <MemberSettingModal
          members={version.members ?? []}
          allMembers={allMembers}
          onSave={(newMembers) => {
            updateVersion(version.productId, version.id, { members: newMembers });
            setShowMemberModal(false);
          }}
          onClose={() => setShowMemberModal(false)}
        />
      )}
    </div>
  );
}

function StatCard({ label, value, accent, warn }: { label: string; value: string | number; accent?: boolean; warn?: boolean }) {
  const color = warn ? 'text-red-500' : accent ? 'text-[var(--accent)]' : 'text-[var(--ink)]';
  return (
    <div className="rounded-xl border border-[var(--line)] bg-[var(--bg-card)] p-3 text-center">
      <div className={`text-[18px] font-semibold tabular-nums ${color}`}>{value}</div>
      <div className="text-[11px] text-[var(--ink-muted)] mt-0.5">{label}</div>
    </div>
  );
}

function LinkItem({ icon, label, url }: { icon: React.ReactNode; label: string; url?: string }) {
  return (
    <div className="flex items-center gap-2">
      <span className="text-[var(--ink-muted)]">{icon}</span>
      {url ? (
        <a href={url} target="_blank" rel="noopener noreferrer" className="text-[12px] text-[var(--accent)] hover:underline flex items-center gap-1">
          {label}<ExternalLink className="h-3 w-3" />
        </a>
      ) : (
        <span className="text-[12px] text-[var(--ink-muted)]">{label} · 未设置</span>
      )}
    </div>
  );
}

function MemberSettingModal({ members, allMembers, onSave, onClose }: {
  members: { role: Role; name: string }[];
  allMembers: { id: string; name: string }[];
  onSave: (members: { role: Role; name: string }[]) => void;
  onClose: () => void;
}) {
  const [list, setList] = useState<{ role: Role; name: string }[]>([...members]);
  const [newName, setNewName] = useState('');
  const [newRole, setNewRole] = useState<Role>('frontend');
  const roleOptions = [
    { value: 'product', label: '产品' },
    { value: 'ui', label: 'UI' },
    { value: 'frontend', label: '前端' },
    { value: 'backend', label: '后端' },
    { value: 'testing', label: '测试' },
  ];

  const handleAdd = () => {
    if (!newName) return;
    if (list.some((m) => m.name === newName && m.role === newRole)) return;
    setList([...list, { role: newRole, name: newName }]);
    setNewName('');
  };

  const handleRemove = (idx: number) => {
    setList(list.filter((_, i) => i !== idx));
  };

  return (
    <div className="fixed inset-0 z-[60] flex items-center justify-center bg-black/40" onClick={onClose}>
      <div className="w-full max-w-md rounded-2xl bg-[var(--bg-card)] border border-[var(--line)] p-6 shadow-[var(--shadow-md)]" onClick={(e) => e.stopPropagation()}>
        <div className="flex items-center justify-between mb-4">
          <h3 className="text-[14px] font-semibold text-[var(--ink)]">设置参与人员</h3>
          <button onClick={onClose} className="rounded-md p-1 hover:bg-[var(--bg-subtle)]"><X className="h-4 w-4 text-[var(--ink-muted)]" /></button>
        </div>

        {/* 已有成员 */}
        <div className="space-y-1.5 mb-4 max-h-[240px] overflow-y-auto">
          {list.length === 0 && <span className="text-[12px] text-[var(--ink-muted)]">暂无成员</span>}
          {list.map((m, i) => (
            <div key={`${m.name}-${m.role}-${i}`} className="flex items-center justify-between px-3 py-1.5 rounded-lg bg-[var(--bg-subtle)]">
              <div className="flex items-center gap-2 text-[12px]">
                <span className="text-[var(--ink-muted)]">{roleOptions.find((r) => r.value === m.role)?.label || m.role}</span>
                <span className="font-medium text-[var(--ink)]">{m.name}</span>
              </div>
              <button onClick={() => handleRemove(i)} className="text-red-400 hover:text-red-600"><X className="h-3.5 w-3.5" /></button>
            </div>
          ))}
        </div>

        {/* 添加新成员 */}
        <div className="flex items-center gap-2 mb-4">
          <select value={newRole} onChange={(e) => setNewRole(e.target.value as Role)} className="h-8 rounded-lg border border-[var(--line)] px-2 text-[12px] focus:border-[var(--accent)] focus:outline-none">
            {roleOptions.map((r) => <option key={r.value} value={r.value}>{r.label}</option>)}
          </select>
          <select value={newName} onChange={(e) => setNewName(e.target.value)} className="h-8 flex-1 rounded-lg border border-[var(--line)] px-2 text-[12px] focus:border-[var(--accent)] focus:outline-none">
            <option value="">选择成员</option>
            {allMembers.filter((m) => !list.some((l) => l.name === m.name && l.role === newRole)).map((m) => <option key={m.id} value={m.name}>{m.name}</option>)}
          </select>
          <button onClick={handleAdd} disabled={!newName} className="h-8 px-3 rounded-lg text-[12px] font-medium bg-[var(--accent)] text-white disabled:opacity-50 flex items-center gap-1">
            <Plus className="h-3 w-3" />添加
          </button>
        </div>

        <div className="flex justify-end gap-2 pt-3 border-t border-[var(--line)]">
          <button onClick={onClose} className="h-8 px-3 rounded-lg text-[12px] font-medium border border-[var(--line)] text-[var(--ink-soft)] hover:bg-[var(--bg-subtle)]">取消</button>
          <button onClick={() => onSave(list)} className="h-8 px-4 rounded-lg text-[12px] font-medium bg-[var(--accent)] text-white">保存</button>
        </div>
      </div>
    </div>
  );
}
