import { EntityDTOContainerOfShoppingCartItemDTO } from '@generated/swagger/checkout-api';
import { ProductNumberAdapter } from './product-number.adapter';

/**
 * Shopping cart item interface compatible with catalogue-api
 */
export interface CatalogueShoppingCartItem {
  id: number;
  data?: {
    product?: {
      ean: string;
      catalogProductNumber?: number;
    };
    quantity?: number;
    availability?: {
      price?: number;
      lastRequest?: string;
    };
    features?: Record<string, any>;
  };
}

/**
 * Adapter for converting between checkout-api EntityDTOContainer structure
 * and catalogue-api ShoppingCartItem interface.
 *
 * Handles:
 * - Unwrapping EntityDTOContainer wrapper
 * - Converting catalogProductNumber from string to number
 * - Preserving all required fields for availability operations
 */
export class ShoppingCartItemAdapter {
  private static readonly ADAPTER_NAME = 'ShoppingCartItemAdapter';

  /**
   * Converts checkout-api shopping cart item to catalogue-api format.
   *
   * @param item - EntityDTOContainer from checkout-api
   * @returns ShoppingCartItem compatible with catalogue-api
   * @throws Error if item structure is invalid
   */
  static toCatalogueFormat(
    item: EntityDTOContainerOfShoppingCartItemDTO,
  ): CatalogueShoppingCartItem {
    if (!item.id) {
      const error = new Error('Shopping cart item missing required id');
      console.error(
        `[${this.ADAPTER_NAME}] Invalid shopping cart item for conversion:`,
        item,
      );
      throw error;
    }

    if (!item.data) {
      const error = new Error('Shopping cart item missing data property');
      console.error(
        `[${this.ADAPTER_NAME}] Invalid shopping cart item for conversion:`,
        item,
      );
      throw error;
    }

    // Extract and convert product information
    const catalogProductNumber = item.data.product?.catalogProductNumber
      ? ProductNumberAdapter.toNumber(item.data.product.catalogProductNumber)
      : undefined;

    // Build catalogue-api compatible structure
    const catalogueItem: CatalogueShoppingCartItem = {
      id: item.id,
      data: {
        product: item.data.product
          ? {
              ean: item.data.product.ean || '',
              catalogProductNumber,
            }
          : undefined,
        quantity: item.data.quantity,
        availability: item.data.availability
          ? {
              price: item.data.availability.price?.value?.value,
              lastRequest: item.data.availability.lastRequest,
            }
          : undefined,
        features: item.data.features,
      },
    };

    return catalogueItem;
  }

  /**
   * Converts array of checkout-api items to catalogue-api format.
   *
   * @param items - Array of EntityDTOContainer from checkout-api
   * @returns Array of ShoppingCartItem compatible with catalogue-api
   */
  static toCatalogueFormatBulk(
    items: EntityDTOContainerOfShoppingCartItemDTO[],
  ): CatalogueShoppingCartItem[] {
    return items
      .map((item) => {
        try {
          return this.toCatalogueFormat(item);
        } catch (error) {
          console.warn(
            `[${this.ADAPTER_NAME}] Skipping invalid item during bulk conversion:`,
            item.id,
            error,
          );
          return null;
        }
      })
      .filter((item): item is CatalogueShoppingCartItem => item !== null);
  }

  /**
   * Type guard to validate ShoppingCartItem structure
   */
  static isValidCatalogueItem(
    value: unknown,
  ): value is CatalogueShoppingCartItem {
    if (typeof value !== 'object' || value === null) return false;

    const item = value as CatalogueShoppingCartItem;
    return (
      typeof item.id === 'number' &&
      (item.data === undefined || typeof item.data === 'object')
    );
  }
}
