import { createComponentFactory, Spectator } from '@ngneat/spectator/jest';
import { DialogComponent } from './dialog.component';
import { DialogContentDirective } from './dialog-content.directive';
import { DIALOG_CLASS_LIST, DIALOG_CONTENT, DIALOG_TITLE } from './tokens';
import { Component } from '@angular/core';
import { DialogRef, DIALOG_DATA } from '@angular/cdk/dialog';
import { NgComponentOutlet } from '@angular/common';

// Mock dialog content component
@Component({
  selector: 'ui-mock-dialog-content',
  template: '<div>Mock Content</div>',
  standalone: true,
})
class MockDialogContentComponent extends DialogContentDirective<
  unknown,
  unknown
> {}

describe('DialogComponent', () => {
  let spectator: Spectator<
    DialogComponent<unknown, unknown, MockDialogContentComponent>
  >;
  const mockTitle = 'Test Dialog Title';
  const mockDialogRef = { close: jest.fn() };

  const createComponent = createComponentFactory({
    component: DialogComponent,
    imports: [NgComponentOutlet, MockDialogContentComponent], // Use imports instead of declarations for standalone components
    providers: [
      { provide: DIALOG_TITLE, useValue: mockTitle },
      { provide: DIALOG_CONTENT, useValue: MockDialogContentComponent },
      { provide: DialogRef, useValue: mockDialogRef },
      { provide: DIALOG_DATA, useValue: {} },
      { provide: DIALOG_CLASS_LIST, useValue: [] },
    ],
  });

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

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

  it('should display the title from injection token', () => {
    const titleElement = spectator.query('[data-what="title"]');
    expect(titleElement).toHaveText(mockTitle);
  });

  it('should have the correct component type', () => {
    expect(spectator.component.component).toBe(MockDialogContentComponent);
  });

  it('should apply the ui-dialog class to the host element', () => {
    expect(spectator.element).toHaveClass('ui-dialog');
  });

  it('should call dialogRef.close when close method is called', () => {
    // Act
    spectator.component.close();

    // Assert
    expect(mockDialogRef.close).toHaveBeenCalledWith();
    expect(mockDialogRef.close).toHaveBeenCalledTimes(1);
  });
});
