import { createComponentFactory, Spectator } from '@ngneat/spectator/jest';
import { ReturnProductInfoComponent } from './return-product-info.component';
import { ProductImageDirective } from '@isa/shared/product-image';
import { MockDirective } from 'ng-mocks';
import { Product } from '@isa/oms/data-access';
import { NgIcon } from '@ng-icons/core';
import { ProductRouterLinkDirective } from '@isa/shared/product-router-link';

// Mock Product data for input
const MOCK_PRODUCT: Product = {
  // Add necessary mock product properties here based on the Product interface
  catalogProductNumber: '123456',
  ean: '1234567890123',
  manufacturer: 'Example Manufacturer',
  name: 'Example Product Name',
  volume: '2',
  contributors: 'John Doe, Jane Smith',
  format: 'HC',
  formatDetail: 'Hardcover', // Corrected property name to match template usage
  // ... other required fields
};

describe('ReturnProductInfoComponent', () => {
  let spectator: Spectator<ReturnProductInfoComponent>;

  // Create the component factory using Spectator
  const createComponent = createComponentFactory({
    component: ReturnProductInfoComponent,
    overrideComponents: [
      [
        ReturnProductInfoComponent,
        {
          remove: {
            imports: [ProductImageDirective, ProductRouterLinkDirective],
          },
          add: {
            imports: [
              MockDirective(ProductImageDirective),
              MockDirective(ProductRouterLinkDirective),
            ],
          },
        },
      ],
    ],
    detectChanges: false, // Control change detection manually if needed
  });

  beforeEach(() => {
    // Create the component instance before each test
    spectator = createComponent({
      props: {
        product: MOCK_PRODUCT, // Pass the mock product as input
      },
    });
    spectator.detectChanges(); // Trigger initial change detection
  });

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

  it('should display product name and contributors', () => {
    // Assert
    const contributorsEl = spectator.query(
      '[data-what="product-contributors"]',
    );
    const nameEl = spectator.query('[data-what="product-name"]');

    expect(contributorsEl).toHaveText(MOCK_PRODUCT.contributors!);
    expect(nameEl).toHaveText(MOCK_PRODUCT.name!);
  });

  it('should pass the correct EAN to the product image directive', () => {
    // Arrange & Act
    const imgElement = spectator.query('img');
    const productImageDirective = spectator.query(ProductImageDirective);

    // Assert
    // Check that the directive is applied to the image
    expect(imgElement).toBeTruthy();
    expect(productImageDirective).toBeTruthy();

    // Verify the ean attribute is bound correctly
    expect(productImageDirective?.ean).toBe(MOCK_PRODUCT.ean);

    // Verify the alt text is set correctly
    expect(imgElement).toHaveAttribute('alt', MOCK_PRODUCT.name);
  });

  it('should display the format with correct icon', () => {
    // Arrange & Act
    const formatElement = spectator.query('[data-what="product-format"]');
    const iconComponent = spectator.query(NgIcon);
    const formatTextEl = spectator.query('[data-what="product-format"] span');

    // Assert
    expect(formatElement).toBeTruthy();
    expect(formatTextEl).toHaveText(MOCK_PRODUCT.formatDetail!);
    expect(iconComponent).toBeTruthy();
  });
});
