/**
 * Tests unitaires pour JiraService
 */

/* eslint-disable @typescript-eslint/no-explicit-any */
import { describe, it, expect, beforeEach, vi } from 'vitest';
import { JiraService } from '../jira';

// Mock de fetch global
global.fetch = vi.fn();

describe('JiraService', () => {
  let service: JiraService;

  const mockConfig = {
    enabled: true,
    baseUrl: 'https://test.atlassian.net',
    email: 'test@example.com',
    apiToken: 'token123',
    projectKey: 'TEST',
    ignoredProjects: [],
  };

  beforeEach(() => {
    vi.clearAllMocks();
    service = new JiraService(mockConfig);
  });

  describe('testConnection', () => {
    it('devrait retourner true si la connexion réussit', async () => {
      vi.mocked(fetch).mockResolvedValue({
        ok: true,
        status: 200,
        text: vi.fn().mockResolvedValue(''),
      } as any);

      const result = await service.testConnection();

      expect(result).toBe(true);
      expect(fetch).toHaveBeenCalled();
    });

    it('devrait retourner false si la connexion échoue', async () => {
      vi.mocked(fetch).mockResolvedValue({
        ok: false,
        status: 401,
        text: vi.fn().mockResolvedValue('Unauthorized'),
      } as any);

      const result = await service.testConnection();

      expect(result).toBe(false);
    });

    it('devrait gérer les erreurs de réseau', async () => {
      vi.mocked(fetch).mockRejectedValue(new Error('Network error'));

      const result = await service.testConnection();

      expect(result).toBe(false);
    });
  });

  describe('validateConfig', () => {
    it('devrait valider une config complète', async () => {
      vi.mocked(fetch).mockResolvedValue({
        ok: true,
        status: 200,
        text: vi.fn().mockResolvedValue(''),
      } as any);

      const result = await service.validateConfig();

      expect(result.valid).toBe(true);
    });

    it('devrait rejeter une config sans baseUrl', async () => {
      const invalidConfig = {
        ...mockConfig,
        baseUrl: undefined,
      };
      const invalidService = new JiraService(invalidConfig as any);

      const result = await invalidService.validateConfig();

      expect(result.valid).toBe(false);
      expect(result.error).toContain('URL de base');
    });

    it('devrait rejeter une config sans email', async () => {
      const invalidConfig = {
        ...mockConfig,
        email: undefined,
      };
      const invalidService = new JiraService(invalidConfig as any);

      const result = await invalidService.validateConfig();

      expect(result.valid).toBe(false);
      expect(result.error).toContain('Email');
    });

    it('devrait rejeter une config sans apiToken', async () => {
      const invalidConfig = {
        ...mockConfig,
        apiToken: undefined,
      };
      const invalidService = new JiraService(invalidConfig as any);

      const result = await invalidService.validateConfig();

      expect(result.valid).toBe(false);
      expect(result.error).toContain('Token API');
    });
  });

  describe('validateProject', () => {
    it('devrait valider un projet existant', async () => {
      vi.mocked(fetch).mockResolvedValue({
        ok: true,
        status: 200,
        json: vi.fn().mockResolvedValue({ name: 'Test Project' }),
      } as any);

      const result = await service.validateProject('TEST');

      expect(result.exists).toBe(true);
      expect(result.name).toBe('Test Project');
    });

    it('devrait détecter un projet inexistant', async () => {
      vi.mocked(fetch).mockResolvedValue({
        ok: false,
        status: 404,
        text: vi.fn().mockResolvedValue('Not found'),
      } as any);

      const result = await service.validateProject('INVALID');

      expect(result.exists).toBe(false);
      expect(result.error).toBeDefined();
    });
  });
});
