/**
 * conflictUtils.spec.ts - 资源冲突检测工具单元测试
 */

import { describe, it, expect } from 'vitest'
import {
  detectConflicts,
  getTimeIntersection,
  getConflictLevel,
  type ConflictZone,
} from '../../../src/utils/conflictUtils'
import type { Task } from '../../../src/models/classes/Task'

describe('conflictUtils', () => {
  describe('getConflictLevel', () => {
    it('应该返回 light 等级（100%-120%）', () => {
      expect(getConflictLevel(100)).toBe('light')
      expect(getConflictLevel(110)).toBe('light')
      expect(getConflictLevel(120)).toBe('light')
    })

    it('应该返回 medium 等级（120%-150%）', () => {
      expect(getConflictLevel(121)).toBe('medium')
      expect(getConflictLevel(130)).toBe('medium')
      expect(getConflictLevel(150)).toBe('medium')
    })

    it('应该返回 severe 等级（>150%）', () => {
      expect(getConflictLevel(151)).toBe('severe')
      expect(getConflictLevel(200)).toBe('severe')
      expect(getConflictLevel(300)).toBe('severe')
    })
  })

  describe('getTimeIntersection', () => {
    it('应该正确计算两个任务的时间交集', () => {
      const task1: Task = {
        id: 1,
        name: '任务1',
        startDate: '2026-01-10',
        endDate: '2026-01-15',
      } as Task

      const task2: Task = {
        id: 2,
        name: '任务2',
        startDate: '2026-01-12',
        endDate: '2026-01-20',
      } as Task

      const intersection = getTimeIntersection(task1, task2)

      expect(intersection).not.toBeNull()
      expect(intersection?.start).toEqual(new Date(2026, 0, 12))
      expect(intersection?.end).toEqual(new Date(2026, 0, 15))
    })

    it('应该在无交集时返回null', () => {
      const task1: Task = {
        id: 1,
        name: '任务1',
        startDate: '2026-01-10',
        endDate: '2026-01-15',
      } as Task

      const task2: Task = {
        id: 2,
        name: '任务2',
        startDate: '2026-01-20',
        endDate: '2026-01-25',
      } as Task

      const intersection = getTimeIntersection(task1, task2)

      expect(intersection).toBeNull()
    })

    it('应该处理边界相接的情况（不算交集）', () => {
      const task1: Task = {
        id: 1,
        name: '任务1',
        startDate: '2026-01-10',
        endDate: '2026-01-15',
      } as Task

      const task2: Task = {
        id: 2,
        name: '任务2',
        startDate: '2026-01-15',
        endDate: '2026-01-20',
      } as Task

      const intersection = getTimeIntersection(task1, task2)

      // 边界相接不算交集
      expect(intersection).toBeNull()
    })

    it('应该处理完全包含的情况', () => {
      const task1: Task = {
        id: 1,
        name: '任务1',
        startDate: '2026-01-10',
        endDate: '2026-01-25',
      } as Task

      const task2: Task = {
        id: 2,
        name: '任务2',
        startDate: '2026-01-15',
        endDate: '2026-01-20',
      } as Task

      const intersection = getTimeIntersection(task1, task2)

      expect(intersection).not.toBeNull()
      expect(intersection?.start).toEqual(new Date(2026, 0, 15))
      expect(intersection?.end).toEqual(new Date(2026, 0, 20))
    })

    it('应该处理缺少日期的情况', () => {
      const task1: Task = {
        id: 1,
        name: '任务1',
        startDate: '2026-01-10',
      } as Task

      const task2: Task = {
        id: 2,
        name: '任务2',
        startDate: '2026-01-15',
        endDate: '2026-01-20',
      } as Task

      const intersection = getTimeIntersection(task1, task2)

      expect(intersection).toBeNull()
    })
  })

  describe('detectConflicts', () => {
    it('应该检测不出无冲突场景', () => {
      const tasks: Task[] = [
        {
          id: 1,
          name: '任务1',
          startDate: '2026-01-10',
          endDate: '2026-01-15',
          resources: [{ id: 'r1', capacity: 50 }],
        } as Task,
        {
          id: 2,
          name: '任务2',
          startDate: '2026-01-20',
          endDate: '2026-01-25',
          resources: [{ id: 'r1', capacity: 60 }],
        } as Task,
      ]

      const conflicts = detectConflicts(tasks, 'r1')

      expect(conflicts).toHaveLength(0)
    })

    it('应该检测出轻度冲突（总占比100%-120%）', () => {
      const tasks: Task[] = [
        {
          id: 1,
          name: '任务1',
          startDate: '2026-01-10',
          endDate: '2026-01-15',
          resources: [{ id: 'r1', capacity: 60 }],
        } as Task,
        {
          id: 2,
          name: '任务2',
          startDate: '2026-01-12',
          endDate: '2026-01-20',
          resources: [{ id: 'r1', capacity: 50 }],
        } as Task,
      ]

      const conflicts = detectConflicts(tasks, 'r1')

      expect(conflicts).toHaveLength(1)
      expect(conflicts[0].level).toBe('light')
      expect(conflicts[0].totalPercent).toBe(110)
      expect(conflicts[0].tasks).toHaveLength(2)
    })

    it('应该检测出中度冲突（总占比120%-150%）', () => {
      const tasks: Task[] = [
        {
          id: 1,
          name: '任务1',
          startDate: '2026-01-10',
          endDate: '2026-01-15',
          resources: [{ id: 'r1', capacity: 70 }],
        } as Task,
        {
          id: 2,
          name: '任务2',
          startDate: '2026-01-12',
          endDate: '2026-01-20',
          resources: [{ id: 'r1', capacity: 65 }],
        } as Task,
      ]

      const conflicts = detectConflicts(tasks, 'r1')

      expect(conflicts).toHaveLength(1)
      expect(conflicts[0].level).toBe('medium')
      expect(conflicts[0].totalPercent).toBe(135)
    })

    it('应该检测出严重冲突（总占比>150%）', () => {
      const tasks: Task[] = [
        {
          id: 1,
          name: '任务1',
          startDate: '2026-01-10',
          endDate: '2026-01-15',
          resources: [{ id: 'r1', capacity: 80 }],
        } as Task,
        {
          id: 2,
          name: '任务2',
          startDate: '2026-01-12',
          endDate: '2026-01-20',
          resources: [{ id: 'r1', capacity: 90 }],
        } as Task,
      ]

      const conflicts = detectConflicts(tasks, 'r1')

      expect(conflicts).toHaveLength(1)
      expect(conflicts[0].level).toBe('severe')
      expect(conflicts[0].totalPercent).toBe(170)
    })

    it('应该检测出多任务冲突', () => {
      const tasks: Task[] = [
        {
          id: 1,
          name: '任务1',
          startDate: '2026-01-10',
          endDate: '2026-01-20',
          resources: [{ id: 'r1', capacity: 40 }],
        } as Task,
        {
          id: 2,
          name: '任务2',
          startDate: '2026-01-12',
          endDate: '2026-01-18',
          resources: [{ id: 'r1', capacity: 50 }],
        } as Task,
        {
          id: 3,
          name: '任务3',
          startDate: '2026-01-15',
          endDate: '2026-01-25',
          resources: [{ id: 'r1', capacity: 30 }],
        } as Task,
      ]

      const conflicts = detectConflicts(tasks, 'r1')

      expect(conflicts.length).toBeGreaterThan(0)
      expect(conflicts[0].tasks.length).toBeGreaterThanOrEqual(2)
      expect(conflicts[0].totalPercent).toBeGreaterThan(100)
    })

    it('应该正确过滤指定资源的任务', () => {
      const tasks: Task[] = [
        {
          id: 1,
          name: '任务1',
          startDate: '2026-01-10',
          endDate: '2026-01-15',
          resources: [{ id: 'r1', capacity: 60 }],
        } as Task,
        {
          id: 2,
          name: '任务2',
          startDate: '2026-01-12',
          endDate: '2026-01-20',
          resources: [{ id: 'r2', capacity: 80 }], // 不同资源
        } as Task,
        {
          id: 3,
          name: '任务3',
          startDate: '2026-01-12',
          endDate: '2026-01-20',
          resources: [{ id: 'r1', capacity: 50 }],
        } as Task,
      ]

      const conflicts = detectConflicts(tasks, 'r1')

      // 应该只检测r1的冲突，不包含r2的任务
      expect(conflicts).toHaveLength(1)
      expect(conflicts[0].tasks.every(t =>
        tasks.find(task => task.id === t.id)?.resources?.some(r => r.id === 'r1')
      )).toBe(true)
    })

    it('应该处理没有资源的任务', () => {
      const tasks: Task[] = [
        {
          id: 1,
          name: '任务1',
          startDate: '2026-01-10',
          endDate: '2026-01-15',
        } as Task,
        {
          id: 2,
          name: '任务2',
          startDate: '2026-01-12',
          endDate: '2026-01-20',
          resources: [{ id: 'r1', capacity: 50 }],
        } as Task,
      ]

      const conflicts = detectConflicts(tasks, 'r1')

      expect(conflicts).toHaveLength(0)
    })

    it('应该处理占比未超载的情况（<=100%）', () => {
      const tasks: Task[] = [
        {
          id: 1,
          name: '任务1',
          startDate: '2026-01-10',
          endDate: '2026-01-15',
          resources: [{ id: 'r1', capacity: 40 }],
        } as Task,
        {
          id: 2,
          name: '任务2',
          startDate: '2026-01-12',
          endDate: '2026-01-20',
          resources: [{ id: 'r1', capacity: 50 }],
        } as Task,
      ]

      const conflicts = detectConflicts(tasks, 'r1')

      // 总占比90%，未超载，不应检测出冲突
      expect(conflicts).toHaveLength(0)
    })

    it('应该处理单个任务的情况', () => {
      const tasks: Task[] = [
        {
          id: 1,
          name: '任务1',
          startDate: '2026-01-10',
          endDate: '2026-01-15',
          resources: [{ id: 'r1', capacity: 120 }], // 单个任务占比>100%也不算冲突
        } as Task,
      ]

      const conflicts = detectConflicts(tasks, 'r1')

      expect(conflicts).toHaveLength(0)
    })

    it('应该合并重叠的冲突区域', () => {
      const tasks: Task[] = [
        {
          id: 1,
          name: '任务1',
          startDate: '2026-01-10',
          endDate: '2026-01-20',
          resources: [{ id: 'r1', capacity: 60 }],
        } as Task,
        {
          id: 2,
          name: '任务2',
          startDate: '2026-01-12',
          endDate: '2026-01-18',
          resources: [{ id: 'r1', capacity: 50 }],
        } as Task,
        {
          id: 3,
          name: '任务3',
          startDate: '2026-01-15',
          endDate: '2026-01-25',
          resources: [{ id: 'r1', capacity: 55 }],
        } as Task,
      ]

      const conflicts = detectConflicts(tasks, 'r1')

      // 应该将连续重叠的区域合并
      expect(conflicts.length).toBeGreaterThan(0)
      expect(conflicts.length).toBeLessThanOrEqual(2)
    })
  })
})
