import { TestBed } from '@angular/core/testing';
import { vi } from 'vitest';
import { ToastService } from './toast.service';

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

  beforeEach(() => {
    TestBed.configureTestingModule({
      providers: [ToastService]
    });
    service = TestBed.inject(ToastService);
    vi.useFakeTimers();
  });

  afterEach(() => {
    vi.useRealTimers();
  });

  it('should be created', () => {
    expect(service).toBeTruthy();
  });

  it('should initialize with an empty list of toasts', () => {
    expect(service.toasts()).toEqual([]);
  });

  it('should show a toast and assign an id', () => {
    const id = service.show('Hello world', 'info');
    expect(id).toBeTruthy();
    expect(service.toasts().length).toBe(1);
    expect(service.toasts()[0]).toEqual({
      id,
      message: 'Hello world',
      type: 'info',
      duration: 3000
    });
  });

  it('should add specific variant toasts via helper methods', () => {
    const infoId = service.info('Info message');
    const dangerId = service.danger('Danger message', 5000);
    const successId = service.success('Success message', 0);

    const toasts = service.toasts();
    expect(toasts.length).toBe(3);

    expect(toasts.find((t) => t.id === infoId)).toEqual({
      id: infoId,
      message: 'Info message',
      type: 'info',
      duration: 3000
    });

    expect(toasts.find((t) => t.id === dangerId)).toEqual({
      id: dangerId,
      message: 'Danger message',
      type: 'danger',
      duration: 5000
    });

    expect(toasts.find((t) => t.id === successId)).toEqual({
      id: successId,
      message: 'Success message',
      type: 'success',
      duration: 0
    });
  });

  it('should dismiss a toast manually by id', () => {
    const id1 = service.show('Toast 1');
    const id2 = service.show('Toast 2');

    expect(service.toasts().length).toBe(2);

    service.dismiss(id1);

    expect(service.toasts().length).toBe(1);
    expect(service.toasts()[0].id).toBe(id2);
  });

  it('should automatically dismiss a toast after the duration', () => {
    service.show('Auto dismiss toast', 'info', 2000);

    expect(service.toasts().length).toBe(1);

    vi.advanceTimersByTime(2000);

    expect(service.toasts().length).toBe(0);
  });

  it('should not dismiss a toast automatically if duration is 0', () => {
    service.show('Persistent toast', 'info', 0);

    expect(service.toasts().length).toBe(1);

    vi.advanceTimersByTime(10000);

    expect(service.toasts().length).toBe(1);
  });
});
