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

// Create a concrete component that extends the abstract directive for testing
@Component({
  selector: 'ui-test-dialog-content',
  template: '<div>Test dialog content</div>',
  standalone: true,
})
class TestDialogContentComponent extends DialogContentDirective<
  unknown,
  unknown
> {}

describe('DialogContentDirective', () => {
  let spectator: Spectator<TestDialogContentComponent>;
  const mockDialogRef = { close: jest.fn() };
  const mockDialog = { close: jest.fn() };
  const mockData = { message: 'Test message' };

  const createComponent = createComponentFactory({
    component: TestDialogContentComponent,
    providers: [
      { provide: DialogRef, useValue: mockDialogRef },
      { provide: DIALOG_DATA, useValue: mockData },
      { provide: DialogComponent, useValue: mockDialog },
    ],
  });

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

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

  it('should have access to dialog data', () => {
    expect(spectator.component.data).toBe(mockData);
  });

  it('should call dialogRef.close with provided result when close method is called', () => {
    const result = { success: true };

    // Act
    spectator.component.close(result);

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

  it('should have access to DialogComponent instance', () => {
    expect(spectator.component.dialog).toBe(mockDialog);
  });

  it('should have access to DialogRef instance', () => {
    expect(spectator.component.dialogRef).toBe(mockDialogRef);
  });

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

  it('should call dialogRef.close without parameters when close is called without result', () => {
    // Act
    spectator.component.close(undefined as any);

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