import type { VersionPlan } from './version-plan';
import type { DevTask } from './dev-task';
import type { TestCase } from './test-case';
import type { Bug } from './bug';

export type WorkItemType = 'plan_research' | 'plan_product' | 'plan_ui' | 'devTask' | 'testCase' | 'bug';

export interface WorkItem {
  id: string;
  type: WorkItemType;
  title: string;
  status: string;
  completed: boolean;
  productName: string;
  projectName: string;
  versionName: string;
  versionId: string;
  priority?: string;
  extra?: Record<string, any>;
  raw: VersionPlan | DevTask | TestCase | Bug;
}

interface VersionContext {
  id: string;
  name: string;
  productName: string;
  projectName: string;
}

export function aggregateWorkItems(
  userName: string,
  plans: VersionPlan[],
  devTasks: DevTask[],
  testCases: TestCase[],
  bugs: Bug[],
  versionMap: Map<string, VersionContext>,
  requirementVersionMap: Map<string, string>,
): WorkItem[] {
  const items: WorkItem[] = [];
  if (!userName.trim()) return items;

  // Plans: owner === userName
  plans.filter((p) => p.owner === userName).forEach((p) => {
    const ver = versionMap.get(p.versionId);
    items.push({
      id: p.id,
      type: p.type === 'research' ? 'plan_research' : p.type === 'product' ? 'plan_product' : 'plan_ui',
      title: p.title,
      status: p.status,
      completed: p.status === 'completed',
      productName: ver?.productName ?? '-',
      projectName: ver?.projectName ?? '-',
      versionName: ver?.name ?? '-',
      versionId: p.versionId,
      extra: { startTime: p.startTime, endTime: p.endTime },
      raw: p,
    });
  });

  // DevTasks: assigneeId === userName
  devTasks.filter((t) => t.assigneeId === userName).forEach((t) => {
    const versionId = t.versionId || requirementVersionMap.get(t.requirementId) || '';
    const ver = versionMap.get(versionId);
    items.push({
      id: t.id,
      type: 'devTask',
      title: t.title,
      status: t.status,
      completed: t.status === 'submitted',
      productName: ver?.productName ?? '-',
      projectName: ver?.projectName ?? '-',
      versionName: ver?.name ?? '-',
      versionId,
      priority: t.priority,
      extra: {
        taskNo: t.taskNo,
        expectedStartAt: t.expectedStartAt,
        expectedEndAt: t.expectedEndAt,
        actualStartAt: t.actualStartAt,
        actualEndAt: t.actualEndAt,
      },
      raw: t,
    });
  });

  // TestCases: assigneeId === userName
  testCases.filter((c) => c.assigneeId === userName).forEach((c) => {
    const ver = versionMap.get(c.versionId);
    items.push({
      id: c.id,
      type: 'testCase',
      title: c.title,
      status: c.status,
      completed: c.status === 'passed',
      productName: ver?.productName ?? '-',
      projectName: ver?.projectName ?? '-',
      versionName: ver?.name ?? '-',
      versionId: c.versionId,
      priority: c.priority,
      extra: { caseNo: c.caseNo },
      raw: c,
    });
  });

  // Bugs: assigneeId === userName
  bugs.filter((b) => b.assigneeId === userName).forEach((b) => {
    const ver = versionMap.get(b.versionId);
    items.push({
      id: b.id,
      type: 'bug',
      title: b.title,
      status: b.status,
      completed: b.status === 'closed' || b.status === 'rejected',
      productName: ver?.productName ?? '-',
      projectName: ver?.projectName ?? '-',
      versionName: ver?.name ?? '-',
      versionId: b.versionId,
      priority: b.priority,
      extra: { bugNo: b.bugNo, severity: b.severity },
      raw: b,
    });
  });

  return items;
}

export function getWorkspacePendingCount(items: ReadonlyArray<Pick<WorkItem, 'completed'>>): number {
  return items.reduce((sum, item) => sum + (item.completed ? 0 : 1), 0);
}

export function getWorkspacePendingCountByVersion(
  items: ReadonlyArray<Pick<WorkItem, 'versionId' | 'completed'>>,
): Map<string, number> {
  const map = new Map<string, number>();
  for (const item of items) {
    if (!item.versionId || item.completed) continue;
    map.set(item.versionId, (map.get(item.versionId) ?? 0) + 1);
  }
  return map;
}

export const WORK_ITEM_TYPE_LABEL: Record<WorkItemType, string> = {
  plan_research: '调研',
  plan_product: '产品方案',
  plan_ui: 'UI设计',
  devTask: '开发任务',
  testCase: '测试用例',
  bug: 'Bug',
};
