import { ComponentFixture, TestBed } from '@angular/core/testing';

import { PdfViewerComponent } from './pdf-viewer.component';
import { ProfileViewModel } from '../../../adapters/profiles/profile.presenter.model';

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

  const mockProfileWithCv: ProfileViewModel = {
    id: '123',
    cv: 'cvfilename.pdf',
  } as ProfileViewModel;

  const mockProfileWithoutCv: ProfileViewModel = {
    id: '123',
    cv: '',
  } as ProfileViewModel;

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

    fixture = TestBed.createComponent(PdfViewerComponent);
    component = fixture.componentInstance;
  });

  it('should create', () => {
    fixture.componentRef.setInput('profile', mockProfileWithCv);
    fixture.detectChanges();

    expect(component).toBeTruthy();
  });

  describe('CV URL generation', () => {
    it('should generate correct URL when CV exists', async () => {
      fixture.componentRef.setInput('profile', mockProfileWithCv);
      fixture.detectChanges();
      await fixture.whenStable();

      const cvUrl = component['cvUrl']();
      expect(cvUrl).toBeTruthy();
      expect(cvUrl).toContain('cvfilename.pdf');
    });

    it('should return null when CV does not exist', async () => {
      fixture.componentRef.setInput('profile', mockProfileWithoutCv);
      fixture.detectChanges();
      await fixture.whenStable();

      const cvUrl = component['cvUrl']();
      expect(cvUrl).toBeNull();
    });

    it('should handle profile with undefined cv', async () => {
      const profileWithUndefinedCv = {
        id: '123',
        cv: '',
      } as ProfileViewModel;

      fixture.componentRef.setInput('profile', profileWithUndefinedCv);
      fixture.detectChanges();
      await fixture.whenStable();

      const cvUrl = component['cvUrl']();
      expect(cvUrl).toBeNull();
    });

    it('should return full URL when CV is already a complete URL', async () => {
      const profileWithFullUrl = {
        id: '123',
        cv: 'https://example.com/cv.pdf',
      } as ProfileViewModel;

      fixture.componentRef.setInput('profile', profileWithFullUrl);
      fixture.detectChanges();
      await fixture.whenStable();

      const cvUrl = component['cvUrl']();
      expect(cvUrl).toBe('https://example.com/cv.pdf');
    });
  });

  describe('hasCv computed', () => {
    it('should return true when CV exists', async () => {
      fixture.componentRef.setInput('profile', mockProfileWithCv);
      fixture.detectChanges();
      await fixture.whenStable();

      expect(component['hasCv']()).toBe(true);
    });

    it('should return false when CV does not exist', async () => {
      fixture.componentRef.setInput('profile', mockProfileWithoutCv);
      fixture.detectChanges();
      await fixture.whenStable();

      expect(component['hasCv']()).toBe(false);
    });
  });

  describe('Template rendering', () => {
    it('should display PDF viewer when CV exists', async () => {
      fixture.componentRef.setInput('profile', mockProfileWithCv);
      fixture.detectChanges();
      await fixture.whenStable();

      const compiled = fixture.nativeElement as HTMLElement;
      const pdfViewer = compiled.querySelector('pdf-viewer');
      const noDataMessage = compiled.querySelector('h3');

      expect(pdfViewer).toBeTruthy();
      expect(noDataMessage?.textContent).not.toContain('Aucun CV disponible');
    });

    it('should display "no CV" message when CV does not exist', async () => {
      fixture.componentRef.setInput('profile', mockProfileWithoutCv);
      fixture.detectChanges();
      await fixture.whenStable();

      const compiled = fixture.nativeElement as HTMLElement;
      const pdfViewer = compiled.querySelector('pdf-viewer');
      const messageTitle = compiled.querySelector('h3');

      expect(pdfViewer).toBeNull();
      expect(messageTitle?.textContent?.trim()).toBe('Aucun CV disponible');
    });

    it('should display download button when CV exists', async () => {
      fixture.componentRef.setInput('profile', mockProfileWithCv);
      fixture.detectChanges();
      await fixture.whenStable();

      const compiled = fixture.nativeElement as HTMLElement;
      const downloadButton = compiled.querySelector('a[download]');

      expect(downloadButton).toBeTruthy();
      expect(downloadButton?.getAttribute('href')).toBeTruthy();
    });

    it('should not display download button when CV does not exist', async () => {
      fixture.componentRef.setInput('profile', mockProfileWithoutCv);
      fixture.detectChanges();
      await fixture.whenStable();

      const compiled = fixture.nativeElement as HTMLElement;
      const downloadButton = compiled.querySelector('a[download]');

      expect(downloadButton).toBeNull();
    });
  });
});
