import { TestBed } from '@angular/core/testing';
import { beforeEach, describe, expect, it } from 'vitest';
import { ProductCarouselComponent } from './product-carousel.component';

describe('ProductCarouselComponent', () => {
  const mockImages = [
    'https://example.com/img1.png',
    'https://example.com/img2.png',
    'https://example.com/img3.png'
  ];

  beforeEach(() => {
    TestBed.resetTestingModule();
  });

  async function createComponent(images: string[] = [], discount: number | null = null) {
    await TestBed.configureTestingModule({
      imports: [ProductCarouselComponent]
    }).compileComponents();

    const fixture = TestBed.createComponent(ProductCarouselComponent);
    const component = fixture.componentInstance;

    // Set signals input values
    fixture.componentRef.setInput('images', images);
    fixture.componentRef.setInput('discount', discount);

    fixture.detectChanges();

    return { fixture, component };
  }

  it('should create and start at activeIndex 0', async () => {
    const { component } = await createComponent(mockImages);
    expect(component).toBeTruthy();
    expect(component.activeIndex()).toBe(0);
  });

  it('should cycle through images on nextImage', async () => {
    const { component } = await createComponent(mockImages);
    expect(component.activeIndex()).toBe(0);

    component.nextImage();
    expect(component.activeIndex()).toBe(1);

    component.nextImage();
    expect(component.activeIndex()).toBe(2);

    component.nextImage(); // Should wrap around to 0
    expect(component.activeIndex()).toBe(0);
  });

  it('should cycle backwards on prevImage', async () => {
    const { component } = await createComponent(mockImages);
    expect(component.activeIndex()).toBe(0);

    component.prevImage(); // Should wrap around to end (2)
    expect(component.activeIndex()).toBe(2);

    component.prevImage();
    expect(component.activeIndex()).toBe(1);
  });

  it('should set activeIndex on selectImage', async () => {
    const { component } = await createComponent(mockImages);
    expect(component.activeIndex()).toBe(0);

    component.selectImage(2);
    expect(component.activeIndex()).toBe(2);

    // If out of bounds, should not change
    component.selectImage(5);
    expect(component.activeIndex()).toBe(2);
  });

  it('should render discount badge if provided', async () => {
    const { fixture } = await createComponent(mockImages, 20);
    const element = fixture.nativeElement as HTMLElement;
    const badge = element.querySelector('.product-carousel__discount-badge');
    expect(badge).not.toBeNull();
    expect(badge?.textContent?.trim()).toBe('-20%');
  });

  it('should not render discount badge if not provided', async () => {
    const { fixture } = await createComponent(mockImages);
    const element = fixture.nativeElement as HTMLElement;
    const badge = element.querySelector('.product-carousel__discount-badge');
    expect(badge).toBeNull();
  });
});
