import { Test, TestingModule } from '@nestjs/testing';
import { SchedulerService } from './scheduler.service';
import {GiftsService} from "../gifts/gifts.service";
import {GiftServiceMock} from "../mocks/gift-service.mock";
import {StateService} from "../state/state.service";
import {StateServiceMock} from "../mocks/state-service.mock";
import {QuizService} from "../quiz/quiz.service";
import {QuizServiceMock} from "../mocks/quiz-service.mock";
import {SharedService} from "../shared/shared.service";
import {SharedServiceMock} from "../mocks/shared-service.mock";
import {FeatureflagService} from "../featureflag/featureflag.service";
import {FeatureflagServiceMock} from "../mocks/featureflag-service.mock";
import {GuestsService} from "../guests/guests.service";
import {GuestsServiceMock} from "../mocks/guests-service.mock";
import {CommandBus} from "@nestjs/cqrs";
import {CommandbusMock} from "../mocks/commandbus.mock";


describe('SchedulerService', () => {
  let service: SchedulerService;
  let giftService: GiftsService;
  let sharedService: SharedService;
  let stateService: StateService;
  let featureFlagService: FeatureflagService;
  beforeEach(async () => {
    jest.clearAllMocks();
    const module: TestingModule = await Test.createTestingModule({
      providers: [SchedulerService,
        { provide: GiftsService, useValue: GiftServiceMock },
        { provide: StateService, useValue: StateServiceMock },
        { provide: QuizService, useValue: QuizServiceMock },
        { provide: SharedService, useValue: SharedServiceMock },
        { provide: FeatureflagService, useValue: FeatureflagServiceMock },
        { provide: CommandBus, useValue: CommandbusMock },
        { provide: GuestsService, useValue: GuestsServiceMock },
      ],
    }).compile();

    service = module.get<SchedulerService>(SchedulerService);
    giftService = module.get<GiftsService>(GiftsService);
    sharedService = module.get<SharedService>(SharedService);
    stateService = module.get<StateService>(StateService);
    featureFlagService = module.get<FeatureflagService>(FeatureflagService);
  });

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

  it('should finish game if prizes count is 0', async () => {
    const getRemainingPrizeCountFn = jest.spyOn(giftService, 'getRemainingPrizeCount').mockImplementation(() => Promise.resolve(0));
    const notificationFn = jest.spyOn(sharedService,'notifyAllClients').mockImplementation();
    const setStateFn = jest.spyOn(stateService,'setState').mockImplementation((name,newstate) => Promise.resolve({ state: name, value: newstate}));
    await service.gameStatus();
    expect(getRemainingPrizeCountFn).toHaveBeenCalled();
    expect(notificationFn).toHaveBeenCalled();
    expect(notificationFn).toHaveBeenCalledWith('state_changed', expect.objectContaining({ state: 'main', value: 'finish'}));
  });

  it('should not finish game if prizes count above 0', async () => {
    const getRemainingPrizeCountFn = jest.spyOn(giftService, 'getRemainingPrizeCount').mockImplementation(() => Promise.resolve(5));
    const notificationFn = jest.spyOn(sharedService,'notifyAllClients').mockImplementation()
    await service.gameStatus();
    expect(notificationFn).not.toHaveBeenCalled();
  });
});
