import { TestBed, fakeAsync, tick } from '@angular/core/testing';
import { Toast, ToastService } from './toast.service';

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

  beforeEach(() => {
    TestBed.configureTestingModule({});
    service = TestBed.inject(ToastService);
  });

  it('show() emits a toast with correct message and type', (done) => {
    service.current$.subscribe((toast) => {
      if (toast) {
        expect(toast.message).toBe('Hello!');
        expect(toast.type).toBe('error');
        done();
      }
    });
    service.show('Hello!', 'error');
  });

  it('type defaults to success when not provided', (done) => {
    service.current$.subscribe((toast) => {
      if (toast) {
        expect(toast.type).toBe('success');
        done();
      }
    });
    service.show('Default type');
  });

  it('current$ emits null after the duration elapses', fakeAsync(() => {
    const emitted: (string | null)[] = [];
    service.current$.subscribe((t: Toast | null) => emitted.push(t ? t.message : null));
    service.show('Auto-dismiss', 'success', 500);
    tick(500);
    expect(emitted).toContain(null);
  }));

  it('calling show() again before timer fires replaces the active toast', fakeAsync(() => {
    const messages: (string | null)[] = [];
    service.current$.subscribe((t: Toast | null) => messages.push(t ? t.message : null));
    service.show('First', 'success', 1000);
    tick(200);
    service.show('Second', 'success', 1000);
    tick(0);
    const nonNull = messages.filter((m) => m !== null);
    expect(nonNull[nonNull.length - 1]).toBe('Second');
  }));
});
