import { createComponentFactory, Spectator } from '@ngneat/spectator/jest';
import { ConfirmationDialogComponent, ConfirmationDialogData, ConfirmationDialogResult } from './confirmation-dialog.component';
import { DialogRef, DIALOG_DATA } from '@angular/cdk/dialog';
import { ButtonComponent } from '@isa/ui/buttons';
import { DialogComponent } from '../dialog.component';

describe('ConfirmationDialogComponent', () => {
  let spectator: Spectator<ConfirmationDialogComponent>;
  let mockDialogRef: DialogRef<ConfirmationDialogResult>;
  const mockData: ConfirmationDialogData = {
    message: 'Confirm this action?'
  };

  const createComponent = createComponentFactory({
    component: ConfirmationDialogComponent,
    imports: [ButtonComponent],
    providers: [
      { 
        provide: DialogRef,
        useValue: { close: jest.fn() }
      },
      { 
        provide: DIALOG_DATA,
        useValue: mockData
      },
      {
        provide: DialogComponent,
        useValue: {}
      }
    ],
  });

  beforeEach(() => {
    spectator = createComponent();
    mockDialogRef = spectator.inject(DialogRef);
    jest.clearAllMocks();
  });

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

  it('should display the confirmation message passed in data', () => {
    const messageElement = spectator.query('[data-what="message"]');
    expect(messageElement).toHaveText('Confirm this action?');
  });

  it('should use default button text when custom text is not provided', () => {
    const closeButton = spectator.query('[data-what="button"][data-which="close"]');
    const confirmButton = spectator.query('[data-what="button"][data-which="confirm"]');
    
    expect(closeButton).toHaveText('Schließen');
    expect(confirmButton).toHaveText('Bestätigen');
  });

  it('should close the dialog with confirmed=false when close button is clicked', () => {
    // Use spectator.query with an assertion to ensure button exists before clicking
    const closeButton = spectator.query('[data-what="button"][data-which="close"]');
    expect(closeButton).toBeTruthy();
    
    // Act - use the element directly since we verified it exists
    spectator.click('[data-what="button"][data-which="close"]');
    
    // Assert
    expect(mockDialogRef.close).toHaveBeenCalledTimes(1);
    expect(mockDialogRef.close).toHaveBeenCalledWith({ confirmed: false });
  });

  it('should close the dialog with confirmed=true when confirm button is clicked', () => {
    // Use spectator.query with an assertion to ensure button exists before clicking
    const confirmButton = spectator.query('[data-what="button"][data-which="confirm"]');
    expect(confirmButton).toBeTruthy();
    
    // Act - use the selector string directly since we verified it exists
    spectator.click('[data-what="button"][data-which="confirm"]');
    
    // Assert
    expect(mockDialogRef.close).toHaveBeenCalledTimes(1);
    expect(mockDialogRef.close).toHaveBeenCalledWith({ confirmed: true });
  });
});

// Rather than try to change providers for an existing test instance,
// create a completely separate test for the custom text scenario
describe('ConfirmationDialogComponent with custom text', () => {
  const customData: ConfirmationDialogData = {
    message: 'Test message',
    closeText: 'Cancel',
    confirmText: 'OK'
  };

  const createComponent = createComponentFactory({
    component: ConfirmationDialogComponent,
    imports: [ButtonComponent],
    providers: [
      { provide: DialogRef, useValue: { close: jest.fn() } },
      { provide: DIALOG_DATA, useValue: customData },
      { provide: DialogComponent, useValue: {} }
    ],
  });

  it('should use custom button text when provided', () => {
    const spectator = createComponent();
    const closeButton = spectator.query('[data-what="button"][data-which="close"]');
    const confirmButton = spectator.query('[data-what="button"][data-which="confirm"]');
    
    expect(closeButton).toHaveText('Cancel');
    expect(confirmButton).toHaveText('OK');
  });
});
