import { ComponentFixture, TestBed } from '@angular/core/testing';
import { By } from '@angular/platform-browser';

import { AlertComponent } from './alert';

describe('AlertComponent', () => {
  let component: AlertComponent;
  let fixture: ComponentFixture<AlertComponent>;

  beforeEach(async () => {
    await TestBed.configureTestingModule({
      imports: [AlertComponent]
    })
    .compileComponents();

    fixture = TestBed.createComponent(AlertComponent);
    component = fixture.componentInstance;
    fixture.detectChanges();
  });

  it('should create', () => {
    expect(component).toBeTruthy();
  });

  describe('Input Properties', () => {
    it('should have default values', () => {
      expect(component.variant).toBe('info');
      expect(component.message).toBe('');
      expect(component.dismissible).toBe(false);
      expect(component.showIcon).toBe(true);
      expect(component.title).toBeUndefined();
      expect(component.icon).toBeUndefined();
    });

    it('should accept variant input', () => {
      component.variant = 'success';
      fixture.detectChanges();
      expect(component.variant).toBe('success');
    });

    it('should accept message input', () => {
      component.message = 'Test message';
      fixture.detectChanges();
      expect(component.message).toBe('Test message');
    });

    it('should accept title input', () => {
      component.title = 'Test Title';
      fixture.detectChanges();
      expect(component.title).toBe('Test Title');
    });

    it('should accept dismissible input', () => {
      component.dismissible = true;
      fixture.detectChanges();
      expect(component.dismissible).toBe(true);
    });

    it('should accept showIcon input', () => {
      component.showIcon = false;
      fixture.detectChanges();
      expect(component.showIcon).toBe(false);
    });

    it('should accept icon input', () => {
      component.icon = 'custom-icon';
      fixture.detectChanges();
      expect(component.icon).toBe('custom-icon');
    });
  });

  describe('getDefaultIcon()', () => {
    it('should return correct icon for info variant', () => {
      component.variant = 'info';
      expect(component.getDefaultIcon()).toBe('ℹ');
    });

    it('should return correct icon for success variant', () => {
      component.variant = 'success';
      expect(component.getDefaultIcon()).toBe('✓');
    });

    it('should return correct icon for warning variant', () => {
      component.variant = 'warning';
      expect(component.getDefaultIcon()).toBe('⚠');
    });

    it('should return correct icon for error variant', () => {
      component.variant = 'error';
      expect(component.getDefaultIcon()).toBe('✕');
    });
  });

  describe('close()', () => {
    it('should emit closed event when close is called', () => {
      spyOn(component.closed, 'emit');
      component.close();
      expect(component.closed.emit).toHaveBeenCalled();
    });
  });

  describe('Template Rendering', () => {
    it('should display message', () => {
      component.message = 'Test alert message';
      fixture.detectChanges();
      const messageElement = fixture.debugElement.query(By.css('.ccl-alert__message'));
      expect(messageElement.nativeElement.textContent.trim()).toBe('Test alert message');
    });

    it('should display title when provided', () => {
      component.title = 'Test Title';
      fixture.detectChanges();
      const titleElement = fixture.debugElement.query(By.css('.ccl-alert__title'));
      expect(titleElement.nativeElement.textContent.trim()).toBe('Test Title');
    });

    it('should not display title when not provided', () => {
      component.title = undefined;
      fixture.detectChanges();
      const titleElement = fixture.debugElement.query(By.css('.ccl-alert__title'));
      expect(titleElement).toBeNull();
    });

    it('should display close button when dismissible is true', () => {
      component.dismissible = true;
      fixture.detectChanges();
      const closeButton = fixture.debugElement.query(By.css('.ccl-alert__close'));
      expect(closeButton).toBeTruthy();
    });

    it('should not display close button when dismissible is false', () => {
      component.dismissible = false;
      fixture.detectChanges();
      const closeButton = fixture.debugElement.query(By.css('.ccl-alert__close'));
      expect(closeButton).toBeNull();
    });

    it('should display icon when showIcon is true', () => {
      component.showIcon = true;
      component.variant = 'success';
      fixture.detectChanges();
      const iconElement = fixture.debugElement.query(By.css('.ccl-alert__icon'));
      expect(iconElement).toBeTruthy();
    });

    it('should not display icon when showIcon is false', () => {
      component.showIcon = false;
      fixture.detectChanges();
      const iconElement = fixture.debugElement.query(By.css('.ccl-alert__icon'));
      expect(iconElement).toBeNull();
    });

    it('should apply correct CSS class for variant', () => {
      component.variant = 'error';
      fixture.detectChanges();
      const alertElement = fixture.debugElement.query(By.css('.ccl-alert'));
      expect(alertElement.nativeElement.classList.contains('ccl-alert--error')).toBe(true);
    });

    it('should call close when close button is clicked', () => {
      component.dismissible = true;
      spyOn(component, 'close');
      fixture.detectChanges();
      const closeButton = fixture.debugElement.query(By.css('.ccl-alert__close'));
      closeButton.nativeElement.click();
      expect(component.close).toHaveBeenCalled();
    });
  });
});
