import test from 'node:test';
import assert from 'node:assert/strict';

import type { TaskWorklog } from './task-worklog';
import type { WorkActivity } from './work-activity';
import type { WorkItem } from './workspace-engine';
import { getWorkspaceDailyReport } from './workspace-daily-report';

const workItems: WorkItem[] = [
  {
    id: 'task-1',
    type: 'devTask',
    title: '实现登录接口',
    status: 'in_progress',
    completed: false,
    productName: 'FTB',
    projectName: '项目管理',
    versionName: 'V1.0',
    versionId: 'version-1',
    extra: { actualStartAt: '2026-06-26T01:00:00.000Z' },
    raw: {} as any,
  },
  {
    id: 'task-2',
    type: 'bug',
    title: '修复菜单错位',
    status: 'fixing',
    completed: false,
    productName: 'FTB',
    projectName: '项目管理',
    versionName: 'V1.0',
    versionId: 'version-1',
    raw: {} as any,
  },
  {
    id: 'task-3',
    type: 'devTask',
    title: '跨天开发任务',
    status: 'in_progress',
    completed: false,
    productName: 'FTB',
    projectName: '项目管理',
    versionName: 'V1.0',
    versionId: 'version-1',
    extra: { actualStartAt: '2026-06-25T02:00:00.000Z' },
    raw: {} as any,
  },
];

const worklogs: TaskWorklog[] = [
  {
    id: 'wl-1',
    taskId: 'task-1',
    userId: '张三',
    date: '2026-06-26',
    hours: 1.5,
    workContent: '完成登录接口联调',
    createdAt: '2026-06-26T02:00:00.000Z',
  },
  {
    id: 'wl-2',
    taskId: 'task-2',
    userId: '张三',
    date: '2026-06-26',
    hours: 0.5,
    workContent: '定位菜单错位原因',
    createdAt: '2026-06-26T03:00:00.000Z',
  },
  {
    id: 'wl-other-user',
    taskId: 'task-1',
    userId: '李四',
    date: '2026-06-26',
    hours: 8,
    workContent: '其他人的日报',
    createdAt: '2026-06-26T04:00:00.000Z',
  },
  {
    id: 'wl-other-date',
    taskId: 'task-1',
    userId: '张三',
    date: '2026-06-25',
    hours: 8,
    workContent: '昨天的日报',
    createdAt: '2026-06-25T04:00:00.000Z',
  },
];

const activities: WorkActivity[] = [
  {
    id: 'act-delivery',
    actorId: '张三',
    date: '2026-06-26',
    occurredAt: '2026-06-26T06:00:00.000Z',
    sourceType: 'dev_task',
    sourceId: 'task-1',
    action: 'dev_task_submitted',
    category: 'delivery',
    title: '实现登录接口',
    summary: '已提测开发任务：实现登录接口',
  },
  {
    id: 'act-risk',
    actorId: '张三',
    date: '2026-06-26',
    occurredAt: '2026-06-26T05:00:00.000Z',
    sourceType: 'bug',
    sourceId: 'task-2',
    action: 'bug_blocked',
    category: 'risk',
    title: '修复菜单错位',
    summary: '标记阻塞：等待设计确认',
    metadata: { blocker: '等待设计确认', helperId: '李四' },
  },
  {
    id: 'act-note',
    actorId: '张三',
    date: '2026-06-26',
    occurredAt: '2026-06-26T04:30:00.000Z',
    sourceType: 'manual',
    sourceId: 'task-1',
    action: 'progress_note_added',
    category: 'note',
    title: '实现登录接口',
    summary: '补充进展：完成接口联调',
    metadata: { note: '完成接口联调' },
  },
  {
    id: 'act-other-user',
    actorId: '李四',
    date: '2026-06-26',
    occurredAt: '2026-06-26T07:00:00.000Z',
    sourceType: 'dev_task',
    sourceId: 'task-1',
    action: 'dev_task_started',
    category: 'progress',
    title: '其他人的任务',
    summary: '其他人的日报活动',
  },
  {
    id: 'act-other-date',
    actorId: '张三',
    date: '2026-06-25',
    occurredAt: '2026-06-25T07:00:00.000Z',
    sourceType: 'dev_task',
    sourceId: 'task-1',
    action: 'dev_task_started',
    category: 'progress',
    title: '昨天的任务',
    summary: '昨天的日报活动',
  },
];

test('getWorkspaceDailyReport filters by current user and date', () => {
  const report = getWorkspaceDailyReport({
    worklogs,
    workItems,
    userId: '张三',
    date: '2026-06-26',
  });

  assert.equal(report.totalHours, 2);
  assert.equal(report.totalCount, 2);
  assert.deepEqual(report.items.map((item) => item.id), ['wl-2', 'wl-1']);
});

test('getWorkspaceDailyReport resolves task title and workspace context', () => {
  const report = getWorkspaceDailyReport({
    worklogs,
    workItems,
    userId: '张三',
    date: '2026-06-26',
  });

  assert.equal(report.items[0].taskTitle, '修复菜单错位');
  assert.equal(report.items[0].productName, 'FTB');
  assert.equal(report.items[0].projectName, '项目管理');
  assert.equal(report.items[0].versionName, 'V1.0');
});

test('getWorkspaceDailyReport keeps logs whose task is no longer visible', () => {
  const report = getWorkspaceDailyReport({
    worklogs: [
      {
        id: 'wl-missing',
        taskId: 'deleted-task',
        userId: '张三',
        date: '2026-06-26',
        hours: 0.5,
        workContent: '处理历史任务',
        createdAt: '2026-06-26T01:00:00.000Z',
      },
    ],
    workItems: [],
    userId: '张三',
    date: '2026-06-26',
  });

  assert.equal(report.totalHours, 0.5);
  assert.equal(report.totalCount, 1);
  assert.equal(report.items[0].taskTitle, '未知任务');
  assert.equal(report.items[0].workContent, '处理历史任务');
});

test('getWorkspaceDailyReport groups current user activities by category', () => {
  const report = getWorkspaceDailyReport({
    activities,
    worklogs,
    workItems,
    userId: '张三',
    date: '2026-06-26',
  });

  assert.deepEqual(report.groups.delivery.map((item) => item.id), ['act-delivery']);
  assert.deepEqual(report.groups.risk.map((item) => item.id), ['act-risk']);
  assert.deepEqual(report.groups.note.map((item) => item.id), ['act-note']);
  assert.equal(report.totalCount, 5);
  assert.equal(report.groups.delivery[0].context, 'FTB / 项目管理 / V1.0');
});

test('getWorkspaceDailyReport counts actual hours from today activity sources', () => {
  const report = getWorkspaceDailyReport({
    activities: [
      {
        id: 'act-started',
        actorId: 'Alice',
        date: '2026-06-26',
        occurredAt: '2026-06-26T02:00:00.000Z',
        sourceType: 'dev_task',
        sourceId: 'task-activity-hours',
        action: 'dev_task_started',
        category: 'progress',
        title: 'Daily report hours',
        summary: 'Started development: Daily report hours',
      },
      {
        id: 'act-submitted',
        actorId: 'Alice',
        date: '2026-06-26',
        occurredAt: '2026-06-26T04:00:00.000Z',
        sourceType: 'dev_task',
        sourceId: 'task-activity-hours',
        action: 'dev_task_submitted',
        category: 'delivery',
        title: 'Daily report hours',
        summary: 'Submitted development task: Daily report hours',
      },
    ],
    worklogs: [],
    workItems: [
      {
        id: 'task-activity-hours',
        type: 'devTask',
        title: 'Daily report hours',
        status: 'submitted',
        completed: true,
        productName: 'FTB',
        projectName: 'Project Management',
        versionName: 'V1.0',
        versionId: 'version-1',
        extra: {
          actualStartAt: '2026-06-26T02:00:00.000Z',
          actualEndAt: '2026-06-26T04:00:00.000Z',
        },
        raw: {
          id: 'task-activity-hours',
          actualStartAt: '2026-06-26T02:00:00.000Z',
          actualEndAt: '2026-06-26T04:00:00.000Z',
          status: 'submitted',
          updatedAt: '2026-06-26T04:00:00.000Z',
        } as any,
      },
    ],
    userId: 'Alice',
    date: '2026-06-26',
  });

  assert.equal(report.totalHours, 2);
  assert.equal(report.totalCount, 2);
});

test('getWorkspaceDailyReport does not double count overlapping activity time ranges', () => {
  const report = getWorkspaceDailyReport({
    activities: [
      {
        id: 'act-overlap-a',
        actorId: 'Alice',
        date: '2026-06-26',
        occurredAt: '2026-06-26T02:10:00.000Z',
        sourceType: 'dev_task',
        sourceId: 'task-overlap-a',
        action: 'dev_task_started',
        category: 'progress',
        title: 'Overlap A',
        summary: 'Started development: Overlap A',
      },
      {
        id: 'act-overlap-b',
        actorId: 'Alice',
        date: '2026-06-26',
        occurredAt: '2026-06-26T02:20:00.000Z',
        sourceType: 'dev_task',
        sourceId: 'task-overlap-b',
        action: 'dev_task_started',
        category: 'progress',
        title: 'Overlap B',
        summary: 'Started development: Overlap B',
      },
    ],
    worklogs: [],
    workItems: [
      {
        id: 'task-overlap-a',
        type: 'devTask',
        title: 'Overlap A',
        status: 'submitted',
        completed: true,
        productName: 'FTB',
        projectName: 'Project Management',
        versionName: 'V1.0',
        versionId: 'version-1',
        extra: {
          actualStartAt: '2026-06-26T02:00:00.000Z',
          actualEndAt: '2026-06-26T04:00:00.000Z',
        },
        raw: {
          id: 'task-overlap-a',
          actualStartAt: '2026-06-26T02:00:00.000Z',
          actualEndAt: '2026-06-26T04:00:00.000Z',
          status: 'submitted',
          updatedAt: '2026-06-26T04:00:00.000Z',
        } as any,
      },
      {
        id: 'task-overlap-b',
        type: 'devTask',
        title: 'Overlap B',
        status: 'submitted',
        completed: true,
        productName: 'FTB',
        projectName: 'Project Management',
        versionName: 'V1.0',
        versionId: 'version-1',
        extra: {
          actualStartAt: '2026-06-26T02:00:00.000Z',
          actualEndAt: '2026-06-26T04:00:00.000Z',
        },
        raw: {
          id: 'task-overlap-b',
          actualStartAt: '2026-06-26T02:00:00.000Z',
          actualEndAt: '2026-06-26T04:00:00.000Z',
          status: 'submitted',
          updatedAt: '2026-06-26T04:00:00.000Z',
        } as any,
      },
    ],
    userId: 'Alice',
    date: '2026-06-26',
  });

  assert.equal(report.totalHours, 2);
  assert.equal(report.totalCount, 2);
});

test('getWorkspaceDailyReport uses plan record work start time for daily report hours', () => {
  const report = getWorkspaceDailyReport({
    activities: [
      {
        id: 'act-plan-record',
        actorId: 'Alice',
        date: '2026-06-26',
        occurredAt: '2026-06-26T04:00:00.000Z',
        sourceType: 'version_plan',
        sourceId: 'plan-cross-day',
        action: 'version_plan_requirement_progress',
        category: 'progress',
        title: 'Product plan',
        summary: 'Updated product plan requirement progress',
        metadata: {
          workStartedAt: '2026-06-26T02:00:00.000Z',
        },
      },
    ],
    worklogs: [],
    workItems: [
      {
        id: 'plan-cross-day',
        type: 'plan_product',
        title: 'Product plan',
        status: 'in_progress',
        completed: false,
        productName: 'FTB',
        projectName: 'Project Management',
        versionName: 'V1.0',
        versionId: 'version-1',
        extra: {
          actualStartAt: '2026-06-25T01:00:00.000Z',
        },
        raw: {
          id: 'plan-cross-day',
          actualStartAt: '2026-06-25T01:00:00.000Z',
          status: 'in_progress',
        } as any,
      },
    ],
    userId: 'Alice',
    date: '2026-06-26',
    now: new Date('2026-06-26T08:00:00.000Z'),
  });

  assert.equal(report.totalHours, 2);
  assert.equal(report.totalCount, 1);
});

test('getWorkspaceDailyReport uses previous progress next start time for dev task daily hours', () => {
  const report = getWorkspaceDailyReport({
    activities: [
      {
        id: 'act-dev-progress-day-1',
        actorId: 'Alice',
        date: '2026-07-01',
        occurredAt: '2026-07-01T10:00:00.000Z',
        sourceType: 'dev_task',
        sourceId: 'task-cross-day-progress',
        action: 'progress_note_added',
        category: 'note',
        title: 'Cross-day development',
        summary: 'Updated today progress',
        metadata: {
          note: 'Finished the first part',
          nextStartAt: '2026-07-02T01:30:00.000Z',
        },
      },
      {
        id: 'act-dev-progress-day-2',
        actorId: 'Alice',
        date: '2026-07-02',
        occurredAt: '2026-07-02T10:00:00.000Z',
        sourceType: 'dev_task',
        sourceId: 'task-cross-day-progress',
        action: 'progress_note_added',
        category: 'note',
        title: 'Cross-day development',
        summary: 'Updated today progress',
        metadata: {
          note: 'Finished the second part',
          nextStartAt: '2026-07-03T01:30:00.000Z',
        },
      },
    ],
    worklogs: [],
    workItems: [
      {
        id: 'task-cross-day-progress',
        type: 'devTask',
        title: 'Cross-day development',
        status: 'in_progress',
        completed: false,
        productName: 'FTB',
        projectName: 'Project Management',
        versionName: 'V1.0',
        versionId: 'version-1',
        extra: {
          actualStartAt: '2026-07-01T01:30:00.000Z',
        },
        raw: {
          id: 'task-cross-day-progress',
          actualStartAt: '2026-07-01T01:30:00.000Z',
          status: 'in_progress',
        } as any,
      },
    ],
    userId: 'Alice',
    date: '2026-07-02',
    now: new Date('2026-07-02T10:00:00.000Z'),
  });

  assert.equal(report.totalHours, 7.5);
  assert.equal(report.totalCount, 1);
});

test('getWorkspaceDailyReport rebuilds activity evidence from persisted work item timestamps', () => {
  const report = getWorkspaceDailyReport({
    activities: [],
    worklogs: [],
    workItems: [
      {
        id: 'task-refresh-recovery',
        type: 'devTask',
        title: 'Refresh recovery',
        status: 'submitted',
        completed: true,
        productName: 'FTB',
        projectName: 'Project Management',
        versionName: 'V1.0',
        versionId: 'version-1',
        extra: {
          actualStartAt: '2026-06-26T02:00:00.000Z',
          actualEndAt: '2026-06-26T04:00:00.000Z',
        },
        raw: {
          id: 'task-refresh-recovery',
          title: 'Refresh recovery',
          actualStartAt: '2026-06-26T02:00:00.000Z',
          actualEndAt: '2026-06-26T04:00:00.000Z',
          status: 'submitted',
          updatedAt: '2026-06-26T04:00:00.000Z',
        } as any,
      },
    ],
    userId: 'Alice',
    date: '2026-06-26',
  });

  assert.deepEqual(report.groups.progress.map((item) => item.action), ['dev_task_started']);
  assert.deepEqual(report.groups.delivery.map((item) => item.action), ['dev_task_submitted']);
  assert.equal(report.totalHours, 2);
  assert.equal(report.totalCount, 2);
});

test('getWorkspaceDailyReport treats same-requirement plan progress as today evidence', () => {
  const report = getWorkspaceDailyReport({
    activities: [
      {
        id: 'act-plan-requirement-progress',
        actorId: 'Alice',
        date: '2026-07-01',
        occurredAt: '2026-07-01T03:00:00.000Z',
        sourceType: 'version_plan',
        sourceId: 'plan-product',
        action: 'version_plan_requirement_progress',
        category: 'progress',
        title: 'Product plan',
        summary: 'Updated requirement progress',
        metadata: {
          requirementId: 'req-shared',
          workStartedAt: '2026-07-01T02:00:00.000Z',
        },
      },
    ],
    worklogs: [],
    workItems: [
      {
        id: 'plan-product',
        type: 'plan_product',
        title: 'Product plan',
        status: 'in_progress',
        completed: false,
        productName: 'FTB',
        projectName: 'Project Management',
        versionName: 'V1.0',
        versionId: 'version-1',
        extra: {
          actualStartAt: '2026-06-30T01:00:00.000Z',
        },
        raw: {
          id: 'plan-product',
          actualStartAt: '2026-06-30T01:00:00.000Z',
          status: 'in_progress',
        } as any,
      },
      {
        id: 'task-same-requirement',
        type: 'devTask',
        title: 'Same requirement task',
        status: 'in_progress',
        completed: false,
        productName: 'FTB',
        projectName: 'Project Management',
        versionName: 'V1.0',
        versionId: 'version-1',
        extra: {
          actualStartAt: '2026-06-30T02:00:00.000Z',
        },
        raw: {
          id: 'task-same-requirement',
          requirementId: 'req-shared',
          actualStartAt: '2026-06-30T02:00:00.000Z',
          status: 'in_progress',
        } as any,
      },
      {
        id: 'task-other-requirement',
        type: 'devTask',
        title: 'Other requirement task',
        status: 'in_progress',
        completed: false,
        productName: 'FTB',
        projectName: 'Project Management',
        versionName: 'V1.0',
        versionId: 'version-1',
        extra: {
          actualStartAt: '2026-06-30T02:00:00.000Z',
        },
        raw: {
          id: 'task-other-requirement',
          requirementId: 'req-other',
          actualStartAt: '2026-06-30T02:00:00.000Z',
          status: 'in_progress',
        } as any,
      },
    ],
    userId: 'Alice',
    date: '2026-07-01',
    now: new Date('2026-07-01T04:00:00.000Z'),
  });

  assert.deepEqual(report.needsProgressItems.map((item) => item.id), ['task-other-requirement']);
});

test('getWorkspaceDailyReport flags multi-day in-progress items without today progress', () => {
  const report = getWorkspaceDailyReport({
    activities,
    worklogs,
    workItems,
    userId: '张三',
    date: '2026-06-26',
  });

  assert.deepEqual(report.needsProgressItems.map((item) => item.id), ['task-3']);
  assert.equal(report.needsProgressItems[0].title, '跨天开发任务');
});
