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

import { AccordionItemComponent } from './accordion-item.component';
import { AccordionComponent } from './accordion.component';

@Component({
  imports: [AccordionComponent, AccordionItemComponent],
  template: `
    <app-accordion [allowMultiple]="allowMultiple()">
      <app-accordion-item title="Primer item" [(open)]="firstOpen">
        <p id="first-content">Contenido uno</p>
      </app-accordion-item>
      <app-accordion-item title="Segundo item" [(open)]="secondOpen">
        <p id="second-content">Contenido dos</p>
      </app-accordion-item>
      <app-accordion-item title="Deshabilitado" [disabled]="true">
        Contenido deshabilitado
      </app-accordion-item>
    </app-accordion>
  `,
})
class TestHostComponent {
  readonly allowMultiple = signal(false);
  readonly firstOpen = signal(false);
  readonly secondOpen = signal(false);
}

describe('AccordionComponent', () => {
  async function setup() {
    await TestBed.configureTestingModule({
      imports: [TestHostComponent],
    }).compileComponents();

    const fixture = TestBed.createComponent(TestHostComponent);
    fixture.detectChanges();

    const buttons = Array.from(
      fixture.nativeElement.querySelectorAll('.accordion-button'),
    ) as HTMLButtonElement[];

    return { fixture, component: fixture.componentInstance, buttons };
  }

  it('renders projected items with Bootstrap classes and accessible relationships', async () => {
    const { fixture, buttons } = await setup();
    const panels = fixture.nativeElement.querySelectorAll('.accordion-collapse');

    expect(fixture.nativeElement.querySelector('.accordion')).not.toBeNull();
    expect(buttons).toHaveLength(3);
    expect(buttons[0].classList.contains('collapsed')).toBe(true);
    expect(buttons[0].getAttribute('aria-controls')).toBe(panels[0].id);
    expect(panels[0].getAttribute('aria-labelledby')).toBe(buttons[0].id);
  });

  it('opens an item and closes the previously open item by default', async () => {
    const { fixture, component, buttons } = await setup();

    buttons[0].click();
    fixture.detectChanges();
    expect(component.firstOpen()).toBe(true);

    buttons[1].click();
    fixture.detectChanges();

    expect(component.firstOpen()).toBe(false);
    expect(component.secondOpen()).toBe(true);
  });

  it('keeps multiple items open when allowMultiple is enabled', async () => {
    const { fixture, component, buttons } = await setup();
    component.allowMultiple.set(true);
    fixture.detectChanges();

    buttons[0].click();
    buttons[1].click();
    fixture.detectChanges();

    expect(component.firstOpen()).toBe(true);
    expect(component.secondOpen()).toBe(true);
  });

  it('does not open a disabled item', async () => {
    const { fixture, buttons } = await setup();
    const disabledPanel = fixture.nativeElement.querySelectorAll('.accordion-collapse')[2];

    buttons[2].click();
    fixture.detectChanges();

    expect(buttons[2].disabled).toBe(true);
    expect(disabledPanel.classList.contains('show')).toBe(false);
  });
});
