import { Test, TestingModule } from '@nestjs/testing';
import { CohortController } from './cohort.controller';
import { CohortService } from './cohort.service';
import { CreateCohortDto } from './dto/create-cohort.dto';
import { getRepositoryToken } from '@nestjs/typeorm';
import { CohortEntity } from './entities/cohort.entity';
import { UpdateCohortDto } from './dto/update-cohort.dto';

describe('CohortController', () => {
  let controller: CohortController;
  let service: CohortService;

  beforeEach(async () => {
    const module: TestingModule = await Test.createTestingModule({
      controllers: [CohortController],
      providers: [
        CohortService,
        {
          provide: getRepositoryToken(CohortEntity),
          useValue: {
            get: jest.fn(),
            post: jest.fn(),
            patch: jest.fn(),
            put: jest.fn(),
            delete: jest.fn(),
            findByCohortId: jest.fn(),
            findByCohortName: jest.fn(),
            update: jest.fn(),
            create: jest.fn(),
            find: jest.fn(),
          },
        },
      ],
    }).compile();

    controller = module.get<CohortController>(CohortController);
    service = module.get<CohortService>(CohortService);
  });

  it('should be defined', () => {
    expect(controller).toBeDefined();
    expect(service).toBeDefined();
  });

  describe('create', () => {
    it('should create a new cohort', async () => {
      const dto = new CreateCohortDto();
      dto.cohortId = 'testId';
      dto.cohortName = 'testName';
      dto.cohortGroupId = 1;

      jest.spyOn(service, 'findByCohortId').mockResolvedValueOnce(null);
      jest.spyOn(service, 'findByCohortName').mockResolvedValueOnce(null);
      jest.spyOn(service, 'create').mockResolvedValueOnce('created' as any);

      expect(await controller.create(dto)).toBe('created');
    });
  });

  describe('findAll', () => {
    it('should find all cohorts', async () => {
      expect(await controller.findAll()).not.toBeNull();
    });
  });

  describe('findOne', () => {
    it('should find one cohort', async () => {
      jest.spyOn(service, 'findOne').mockResolvedValueOnce('cohort1' as any);
      expect(await controller.findOne('1')).toBe('cohort1');
    });
  });

  describe('update', () => {
    it('should update a cohort', async () => {
      const dto = new UpdateCohortDto();
      dto.cohortId = '1';
      dto.cohortName = 'testName';
      dto.cohortGroupId = 1;
      jest.spyOn(service, 'findByCohortId').mockResolvedValueOnce(null);
      jest.spyOn(service, 'findByCohortName').mockResolvedValueOnce(null);
      jest.spyOn(service, 'update').mockResolvedValueOnce('updated' as any);

      expect(await controller.update('1', dto)).toBe('updated');
    });
  });

  describe('remove', () => {
    it('should remove a cohort', async () => {
      expect(await controller.remove('1')).not.toBeNull();
    });
  });

  describe('findEmployeeCohort', () => {
    it('should find employee cohort', async () => {
      expect(await controller.findEmployeeCohort('1')).not.toBeNull();
    });
  });
});
