import { TestBed } from '@angular/core/testing';
import { ProjectFacade } from '@app/adapters/projects/project.facade';
import { FakeProjectRepository } from '@app/testing/domain/projects/fake-project.repository';
import { PROJECT_REPOSITORY_TOKEN } from '@app/infrastructure/projects/project-repository.token';
import { mockProjects } from '@app/testing/project.mock';
import { CreateProjectDto } from '@app/domain/projects/dto/create-project.dto';
import { ToastrService } from 'ngx-toastr';
import { mockToastR } from '@app/testing/toastr.mock';

describe('ProjectFacade', () => {
  let facade: ProjectFacade;

  beforeEach(() => {
    TestBed.configureTestingModule({
      providers: [
        ProjectFacade,
        { provide: PROJECT_REPOSITORY_TOKEN, useClass: FakeProjectRepository },
        { provide: ToastrService, useValue: mockToastR },
      ],
    });

    facade = TestBed.inject(ProjectFacade);
  });

  // ------------------------------------------
  // 🔹 TEST : Chargement des projets (load)
  // ------------------------------------------
  it('devrait charger les projets pour un utilisateur', (done) => {
    const userId = 'user_001';
    facade.load(userId);

    setTimeout(() => {
      const projets = facade.projects();
      expect(projets.length).toBe(mockProjects.filter((p) => p.utilisateur === userId).length);
      expect(facade.loading().isLoading).toBe(false);
      expect(facade.error().hasError).toBe(false);
      done();
    }, 0);
  });

  // ------------------------------------------
  // 🔹 TEST : Chargement d’un projet unique
  // ------------------------------------------
  it('devrait charger un projet par son ID', (done) => {
    const projectId = '1';
    facade.loadOne(projectId);

    setTimeout(() => {
      const project = facade.project();
      expect(project?.id).toBe(projectId);
      expect(facade.error().hasError).toBe(false);
      done();
    }, 0);
  });

  // ------------------------------------------
  // 🔹 TEST : Création d’un nouveau projet
  // ------------------------------------------
  it('devrait créer un nouveau projet', (done) => {
    const dto: CreateProjectDto = {
      nom: 'Projet test création',
      lien: 'https://test-create.example.com',
      description: 'Projet ajouté via façade',
      utilisateur: 'user_010',
    };

    facade.create(dto);

    setTimeout(() => {
      const dernier = facade.projects().find((p) => p.nom === dto.nom);
      expect(dernier).toBeDefined();
      expect(facade.project()?.nom).toBe(dto.nom);
      expect(facade.loading().isLoading).toBe(false);
      expect(facade.error().hasError).toBe(false);
      done();
    }, 0);
  });

  // ------------------------------------------
  // 🔹 TEST : Mise à jour d’un projet
  // ------------------------------------------
  it('devrait mettre à jour un projet existant', (done) => {
    const projectId = '1';
    const data = { nom: 'Projet mis à jour' };

    facade.update(projectId, data);

    setTimeout(() => {
      const updated = facade.project();
      expect(updated?.nom).toBe('Projet mis à jour');
      expect(facade.error().hasError).toBe(false);
      done();
    }, 0);
  });
});
