/**
 * Tests unitaires pour JiraAdvancedFiltersService
 */

import { describe, it, expect } from 'vitest';
import { JiraAdvancedFiltersService } from '../advanced-filters';
import { JiraTask, JiraAnalytics } from '@/lib/types';

describe('JiraAdvancedFiltersService', () => {
  const mockIssues: JiraTask[] = [
    {
      id: '1',
      key: 'TEST-1',
      summary: 'Task 1',
      status: { name: 'In Progress', category: 'inprogress' },
      issuetype: { name: 'Bug' },
      priority: { name: 'High' },
      assignee: { displayName: 'John Doe', emailAddress: 'john@example.com' },
      components: [{ name: 'Frontend' }],
      fixVersions: [{ name: 'v1.0' }],
      labels: ['urgent', 'bug'],
      project: { key: 'TEST', name: 'Test Project' },
      created: '2024-01-01',
      updated: '2024-01-02',
    },
    {
      id: '2',
      key: 'TEST-2',
      summary: 'Task 2',
      status: { name: 'Done', category: 'done' },
      issuetype: { name: 'Story' },
      priority: { name: 'Medium' },
      assignee: { displayName: 'Jane Smith', emailAddress: 'jane@example.com' },
      components: [{ name: 'Backend' }],
      fixVersions: [{ name: 'v2.0' }],
      labels: ['feature'],
      project: { key: 'TEST', name: 'Test Project' },
      created: '2024-01-03',
      updated: '2024-01-04',
    },
  ];

  const mockAnalytics: JiraAnalytics = {
    project: {
      key: 'TEST',
      name: 'Test Project',
      totalIssues: 2,
    },
    teamMetrics: {
      totalAssignees: 2,
      activeAssignees: 2,
      issuesDistribution: [],
    },
    velocityMetrics: {
      currentSprintPoints: 0,
      averageVelocity: 0,
      sprintHistory: [],
    },
    cycleTimeMetrics: {
      averageCycleTime: 0,
      cycleTimeByType: [],
    },
    workInProgress: {
      byStatus: [],
      byAssignee: [],
    },
  };

  describe('extractAvailableFilters', () => {
    it('devrait extraire tous les filtres disponibles', () => {
      const filters =
        JiraAdvancedFiltersService.extractAvailableFilters(mockIssues);

      expect(filters.components).toHaveLength(2);
      expect(filters.fixVersions).toHaveLength(2);
      expect(filters.issueTypes).toHaveLength(2);
      expect(filters.statuses).toHaveLength(2);
      expect(filters.assignees).toHaveLength(2);
      expect(filters.labels).toHaveLength(3);
      expect(filters.priorities).toHaveLength(2);
    });

    it('devrait compter les occurrences correctement', () => {
      const filters =
        JiraAdvancedFiltersService.extractAvailableFilters(mockIssues);

      const frontendComponent = filters.components.find(
        (c) => c.value === 'Frontend'
      );
      expect(frontendComponent?.count).toBe(1);

      const urgentLabel = filters.labels.find((l) => l.value === 'urgent');
      expect(urgentLabel?.count).toBe(1);
    });

    it('devrait gérer les issues sans assignee', () => {
      const issuesWithoutAssignee: JiraTask[] = [
        {
          ...mockIssues[0],
          assignee: undefined,
        },
      ];

      const filters = JiraAdvancedFiltersService.extractAvailableFilters(
        issuesWithoutAssignee
      );

      const unassigned = filters.assignees.find(
        (a) => a.value === 'Non assigné'
      );
      expect(unassigned).toBeDefined();
    });

    it('devrait retourner des filtres vides pour une liste vide', () => {
      const filters = JiraAdvancedFiltersService.extractAvailableFilters([]);

      expect(filters.components).toHaveLength(0);
      expect(filters.fixVersions).toHaveLength(0);
      expect(filters.issueTypes).toHaveLength(0);
    });
  });

  describe('applyFiltersToAnalytics', () => {
    it('devrait filtrer par composant', () => {
      const filtered = JiraAdvancedFiltersService.applyFiltersToAnalytics(
        mockAnalytics,
        { components: ['Frontend'] },
        mockIssues
      );

      expect(filtered.project.totalIssues).toBe(1);
    });

    it('devrait filtrer par type de ticket', () => {
      const filtered = JiraAdvancedFiltersService.applyFiltersToAnalytics(
        mockAnalytics,
        { issueTypes: ['Bug'] },
        mockIssues
      );

      expect(filtered.project.totalIssues).toBe(1);
    });

    it('devrait filtrer par statut', () => {
      const filtered = JiraAdvancedFiltersService.applyFiltersToAnalytics(
        mockAnalytics,
        { statuses: ['In Progress'] },
        mockIssues
      );

      expect(filtered.project.totalIssues).toBe(1);
    });

    it('devrait filtrer par assignee', () => {
      const filtered = JiraAdvancedFiltersService.applyFiltersToAnalytics(
        mockAnalytics,
        { assignees: ['John Doe'] },
        mockIssues
      );

      expect(filtered.project.totalIssues).toBe(1);
    });

    it('devrait filtrer par label', () => {
      const filtered = JiraAdvancedFiltersService.applyFiltersToAnalytics(
        mockAnalytics,
        { labels: ['urgent'] },
        mockIssues
      );

      expect(filtered.project.totalIssues).toBe(1);
    });

    it('devrait appliquer plusieurs filtres simultanément', () => {
      const filtered = JiraAdvancedFiltersService.applyFiltersToAnalytics(
        mockAnalytics,
        {
          components: ['Frontend'],
          issueTypes: ['Bug'],
        },
        mockIssues
      );

      expect(filtered.project.totalIssues).toBe(1);
    });

    it('devrait retourner analytics vide si aucun match', () => {
      const filtered = JiraAdvancedFiltersService.applyFiltersToAnalytics(
        mockAnalytics,
        { components: ['NonExistent'] },
        mockIssues
      );

      expect(filtered.project.totalIssues).toBe(0);
    });

    it('devrait retourner analytics original si pas de filtres', () => {
      const filtered = JiraAdvancedFiltersService.applyFiltersToAnalytics(
        mockAnalytics,
        {},
        mockIssues
      );

      expect(filtered.project.totalIssues).toBe(2);
    });
  });
});
