import { FileManagerService } from '@app/adapters/shared/services/file-manager.service';
import { TestBed } from '@angular/core/testing';

// 1. Mock de la librairie externe
// Cela empêche Jest d'essayer de compresser réellement (ce qui échouerait dans l'environnement de test)
jest.mock('browser-image-compression', () => {
  return {
    __esModule: true,
    // On simule une fonction qui renvoie une Promesse résolue avec un fichier "compressé"
    default: jest
      .fn()
      .mockImplementation((file) =>
        Promise.resolve(new File([file], 'compressed.jpg', { type: 'image/jpeg' }))
      ),
  };
});

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

  beforeEach(() => {
    TestBed.configureTestingModule({
      providers: [FileManagerService],
    });
    service = TestBed.inject(FileManagerService);
  });

  it('devrait être créé', () => {
    expect(service).toBeTruthy();
  });

  describe('Validation du fichier', () => {
    // 2. AJOUT DE 'async' ICI
    it('devrait accepter et compresser une image JPEG valide', async () => {
      const validFile = new File(['test content'], 'test.jpg', { type: 'image/jpeg' });
      Object.defineProperty(validFile, 'size', { value: 1024 * 1024 }); // 1MB

      const event = { target: { files: [validFile], value: 'test.jpg' } } as unknown as Event;

      await service.onPictureChange(event);

      // 4. VÉRIFICATION
      const currentFile = service.file();
      expect(currentFile).not.toBeNull();

      // On s'attend à recevoir le fichier compressé par le Mock (nommé 'compressed.jpg')
      // et non le fichier original 'test.jpg'
      expect(currentFile?.name).toBe('compressed.jpg');
      expect(service.fileError()).toBeNull();
    });

    it("devrait rejeter un fichier qui n'est pas une image", async () => {
      const invalidFile = new File([''], 'test.pdf', { type: 'application/pdf' });
      const event = { target: { files: [invalidFile], value: '' } } as unknown as Event;

      await service.onPictureChange(event);

      expect(service.file()).toBeNull();
      expect(service.fileError()).toContain('Le fichier doit être une image');
    });

    it('devrait rejeter une extension non autorisée (ex: gif)', async () => {
      const invalidFile = new File([''], 'test.gif', { type: 'image/gif' });
      const event = { target: { files: [invalidFile], value: '' } } as unknown as Event;

      await service.onPictureChange(event);

      expect(service.file()).toBeNull();
      expect(service.fileError()).toContain('Le fichier doit être une image (JPEG, PNG ou WebP)');
    });
  });

  describe('Gestion du fichier', () => {
    it('devrait supprimer le fichier et réinitialiser les signaux', () => {
      service.file.set(new File([''], 'test.jpg'));
      service.imagePreviewUrl.set('data:image...');
      service.fileError.set('error');

      service.removeFile();

      expect(service.file()).toBeNull();
      expect(service.imagePreviewUrl()).toBeNull();
      expect(service.fileError()).toBeNull();
    });
  });

  describe('Utilitaires', () => {
    it('devrait formater correctement la taille des fichiers', () => {
      expect(service.formatFileSize(0)).toBe('0 Octets');
      expect(service.formatFileSize(1024)).toBe('1 Ko');
      expect(service.formatFileSize(1024 * 1024)).toBe('1 Mo');
      expect(service.formatFileSize(2.5 * 1024 * 1024)).toBe('2.5 Mo');
    });
  });
});
