import { Utterance } from './Utterance';

const defaultVoice = {
  name: 'Alex',
  lang: 'en-US',
  localService: true,
  voiceURI: 'Alex',
  default: true
};
describe('Utterance', () => {
  let speechSynthesisUtteranceMock: any;
  let mockSpeechSynthesisUtterance: any;
  let utterance: Utterance;

  beforeEach(() => {
    // Mock the SpeechSynthesisUtterance class
    speechSynthesisUtteranceMock = jest.fn();
    mockSpeechSynthesisUtterance = {
      onstart: jest.fn(),
      onend: jest.fn(),
      onerror: jest.fn()
    };
    // Set up the mock return values
    speechSynthesisUtteranceMock.mockReturnValue(mockSpeechSynthesisUtterance);
    window.SpeechSynthesisUtterance = speechSynthesisUtteranceMock;

    utterance = new Utterance('1', 'Hello', {});
  });

  afterEach(() => {
    jest.restoreAllMocks();
  });

  describe('constructor', () => {
    test('should initialize the utterance', () => {
      expect(typeof utterance.utterance?.onstart).toBe('function');
      expect(typeof utterance.utterance?.onend).toBe('function');
      expect(typeof utterance.utterance?.onerror).toBe('function');
    });

    test('should initialize the error as null', () => {
      expect(utterance.error).toBeNull();
    });

    test('should set the id', () => {
      expect(utterance.id).toBe('1');
    });

    test('should set the retryCount to 0', () => {
      expect(utterance.retryCount).toBe(0);
    });

    test('should set the error to null', () => {
      expect(utterance.error).toBeNull();
    });

    test('should set the status to "idle"', () => {
      expect(utterance.status).toBe('idle');
    });

    test('should set the userOptions', () => {
      expect(utterance.userOptions).toEqual({});
    });
  });

  describe('setVolume', () => {
    test('should set the volume property of the utterance', () => {
      utterance.setVolume(0.5);
      expect(utterance.utterance?.volume).toBe(0.5);
    });
  });

  describe('setRate', () => {
    test('should set the rate property of the utterance', () => {
      utterance.setRate(1.2);
      expect(utterance.utterance?.rate).toBe(1.2);
      expect(utterance.rate).toBe(1.2);
    });
  });

  describe('setVoice', () => {
    test('should set the voice property of the utterance', () => {
      const voice = defaultVoice;
      //   utterance.setVoice(voice);
      expect(utterance.utterance?.voice).toStrictEqual(voice);
    });
  });

  describe('setPitch', () => {
    test('should set the pitch property of the utterance', () => {
      utterance.setPitch(1.5);
      expect(utterance.utterance?.pitch).toBe(1.5);
    });
  });

  describe('setRetry', () => {
    test('should increment the retryCount property', () => {
      utterance.setRetry();
      expect(utterance.retryCount).toBe(1);
    });
  });
});
