/**
 * Tests unitaires pour ManagerSummaryService
 */

/* eslint-disable @typescript-eslint/no-explicit-any */
import { describe, it, expect, beforeEach, afterEach, vi } from 'vitest';
import { ManagerSummaryService } from '../manager-summary';
import { prisma } from '@/services/core/database';

// Mock de prisma
vi.mock('@/services/core/database', () => ({
  prisma: {
    task: {
      findMany: vi.fn(),
    },
    dailyCheckbox: {
      findMany: vi.fn(),
      count: vi.fn(),
    },
  },
}));

describe('ManagerSummaryService', () => {
  const userId = 'test-user-id';
  const mockDate = new Date('2024-01-15T12:00:00Z');

  beforeEach(() => {
    vi.clearAllMocks();
    vi.useFakeTimers();
    vi.setSystemTime(mockDate);
  });

  afterEach(() => {
    vi.useRealTimers();
  });

  describe('getManagerSummary', () => {
    it('devrait générer un résumé pour les 7 derniers jours', async () => {
      const mockTasks = [
        {
          id: '1',
          title: 'Tâche complétée',
          description: 'Description',
          priority: 'high',
          completedAt: new Date('2024-01-12'),
          createdAt: new Date('2024-01-10'),
          updatedAt: new Date('2024-01-12'),
          taskTags: [],
        },
      ];

      const mockCheckboxes = [
        {
          id: '1',
          text: 'Todo complété',
          isChecked: true,
          type: 'task',
          date: new Date('2024-01-13'),
          createdAt: new Date('2024-01-13'),
          task: null,
        },
      ];

      vi.mocked(prisma.task.findMany).mockResolvedValue(mockTasks as any);
      vi.mocked(prisma.dailyCheckbox.findMany).mockResolvedValue(
        mockCheckboxes as any
      );
      vi.mocked(prisma.dailyCheckbox.count).mockResolvedValue(0);

      const result = await ManagerSummaryService.getManagerSummary(userId);

      expect(result).toHaveProperty('period');
      expect(result).toHaveProperty('keyAccomplishments');
      expect(result).toHaveProperty('upcomingChallenges');
      expect(result).toHaveProperty('metrics');
      expect(result).toHaveProperty('narrative');

      expect(result.period.start).toBeInstanceOf(Date);
      expect(result.period.end).toBeInstanceOf(Date);
      expect(result.keyAccomplishments.length).toBeGreaterThan(0);
    });

    it('devrait extraire les accomplissements clés des tâches', async () => {
      const mockTasks = [
        {
          id: '1',
          title: 'Tâche haute priorité',
          description: 'Description importante',
          priority: 'high',
          completedAt: new Date('2024-01-12'),
          createdAt: new Date('2024-01-10'),
          updatedAt: new Date('2024-01-12'),
          taskTags: [
            {
              tag: {
                name: 'important',
              },
            },
          ],
        },
      ];

      vi.mocked(prisma.task.findMany).mockResolvedValue(mockTasks as any);
      vi.mocked(prisma.dailyCheckbox.findMany).mockResolvedValue([]);
      vi.mocked(prisma.dailyCheckbox.count).mockResolvedValue(0);

      const result = await ManagerSummaryService.getManagerSummary(userId);

      const accomplishment = result.keyAccomplishments.find(
        (a) => a.id === 'task-1'
      );
      expect(accomplishment).toBeDefined();
      expect(accomplishment?.impact).toBe('high');
      expect(accomplishment?.tags).toContain('important');
    });

    it('devrait inclure les todos standalone comme accomplissements', async () => {
      const mockCheckboxes = [
        {
          id: '1',
          text: 'Réunion importante',
          isChecked: true,
          type: 'meeting',
          date: new Date('2024-01-13'),
          createdAt: new Date('2024-01-13'),
          task: null,
        },
      ];

      vi.mocked(prisma.task.findMany).mockResolvedValue([]);
      vi.mocked(prisma.dailyCheckbox.findMany).mockResolvedValue(
        mockCheckboxes as any
      );

      const result = await ManagerSummaryService.getManagerSummary(userId);

      const accomplishment = result.keyAccomplishments.find(
        (a) => a.id === 'todo-1'
      );
      expect(accomplishment).toBeDefined();
      expect(accomplishment?.title).toContain('Réunion importante');
      expect(accomplishment?.impact).toBe('low');
    });

    it('devrait identifier les défis à venir', async () => {
      const mockUpcomingTasks = [
        {
          id: '1',
          title: 'Tâche à venir',
          description: 'Description',
          priority: 'high',
          createdAt: new Date('2024-01-10'),
          taskTags: [],
        },
      ];

      const mockUpcomingCheckboxes = [
        {
          id: '1',
          text: 'Todo à venir',
          isChecked: false,
          type: 'task',
          date: new Date('2024-01-20'),
          createdAt: new Date('2024-01-10'),
          task: {
            id: '1',
            title: 'Tâche à venir',
            priority: 'high',
            taskTags: [],
          },
        },
      ];

      // Mock pour getCompletedTasks
      vi.mocked(prisma.task.findMany)
        .mockResolvedValueOnce([]) // Tâches complétées
        .mockResolvedValueOnce(mockUpcomingTasks as any); // Tâches à venir

      vi.mocked(prisma.dailyCheckbox.findMany)
        .mockResolvedValueOnce([]) // Checkboxes complétées
        .mockResolvedValueOnce(mockUpcomingCheckboxes as any); // Checkboxes à venir

      vi.mocked(prisma.dailyCheckbox.count).mockResolvedValue(0);

      const result = await ManagerSummaryService.getManagerSummary(userId);

      expect(result.upcomingChallenges.length).toBeGreaterThan(0);
      const challenge = result.upcomingChallenges.find(
        (c) => c.id === 'task-1'
      );
      expect(challenge).toBeDefined();
      expect(challenge?.priority).toBe('high');
    });

    it('devrait calculer les métriques correctement', async () => {
      const mockTasks = [
        {
          id: '1',
          title: 'Tâche haute priorité',
          description: 'Description',
          priority: 'high',
          completedAt: new Date('2024-01-12'),
          createdAt: new Date('2024-01-10'),
          updatedAt: new Date('2024-01-12'),
          taskTags: [],
        },
      ];

      const mockCheckboxes = [
        {
          id: '1',
          text: 'Réunion',
          isChecked: true,
          type: 'meeting',
          date: new Date('2024-01-13'),
          createdAt: new Date('2024-01-13'),
          task: null,
        },
      ];

      vi.mocked(prisma.task.findMany).mockResolvedValue(mockTasks as any);
      vi.mocked(prisma.dailyCheckbox.findMany).mockResolvedValue(
        mockCheckboxes as any
      );
      vi.mocked(prisma.dailyCheckbox.count).mockResolvedValue(0);

      const result = await ManagerSummaryService.getManagerSummary(userId);

      expect(result.metrics.totalTasksCompleted).toBe(1);
      expect(result.metrics.totalCheckboxesCompleted).toBe(1);
      expect(result.metrics.highPriorityTasksCompleted).toBe(1);
      expect(result.metrics.meetingCheckboxesCompleted).toBe(1);
    });

    it('devrait générer un narratif', async () => {
      const mockTasks = [
        {
          id: '1',
          title: 'Tâche importante',
          description: 'Description',
          priority: 'high',
          completedAt: new Date('2024-01-12'),
          createdAt: new Date('2024-01-10'),
          updatedAt: new Date('2024-01-12'),
          taskTags: [
            {
              tag: {
                name: 'important',
              },
            },
          ],
        },
      ];

      vi.mocked(prisma.task.findMany).mockResolvedValue(mockTasks as any);
      vi.mocked(prisma.dailyCheckbox.findMany).mockResolvedValue([]);
      vi.mocked(prisma.dailyCheckbox.count).mockResolvedValue(0);

      const result = await ManagerSummaryService.getManagerSummary(userId);

      expect(result.narrative).toHaveProperty('weekHighlight');
      expect(result.narrative).toHaveProperty('mainChallenges');
      expect(result.narrative).toHaveProperty('nextWeekFocus');
      expect(result.narrative.weekHighlight.length).toBeGreaterThan(0);
    });

    it('devrait utiliser une date personnalisée si fournie', async () => {
      const customDate = new Date('2024-02-01');

      vi.mocked(prisma.task.findMany).mockResolvedValue([]);
      vi.mocked(prisma.dailyCheckbox.findMany).mockResolvedValue([]);

      const result = await ManagerSummaryService.getManagerSummary(
        userId,
        customDate
      );

      expect(result.period.end).toEqual(customDate);
    });

    it('devrait trier les accomplissements par impact', async () => {
      const mockTasks = [
        {
          id: '1',
          title: 'Tâche haute priorité',
          description: 'Description',
          priority: 'high',
          completedAt: new Date('2024-01-12'),
          createdAt: new Date('2024-01-10'),
          updatedAt: new Date('2024-01-12'),
          taskTags: [],
        },
        {
          id: '2',
          title: 'Tâche basse priorité',
          description: 'Description',
          priority: 'low',
          completedAt: new Date('2024-01-13'),
          createdAt: new Date('2024-01-11'),
          updatedAt: new Date('2024-01-13'),
          taskTags: [],
        },
      ];

      vi.mocked(prisma.task.findMany).mockResolvedValue(mockTasks as any);
      vi.mocked(prisma.dailyCheckbox.findMany).mockResolvedValue([]);
      vi.mocked(prisma.dailyCheckbox.count).mockResolvedValue(0);

      const result = await ManagerSummaryService.getManagerSummary(userId);

      expect(result.keyAccomplishments[0].impact).toBe('high');
    });
  });
});
