import { PriceDTO } from '@generated/swagger/availability-api';
import { ItemDTO } from '@generated/swagger/cat-search-api';
import {
  AvailabilityDTO,
  OLAAvailabilityDTO,
  ShoppingCartItemDTO,
} from '@generated/swagger/checkout-api';
import { GIFT_CARD_TYPE } from '../constants';
import {
  ActionType,
  Item,
  ItemData,
  ItemPayloadWithSourceId,
  PurchaseOption,
} from './purchase-options.types';
import { OrderTypeFeature } from '@isa/checkout/data-access';

export function isItemDTO(item: any, type: ActionType): item is ItemDTO {
  return type === 'add';
}

export function isItemDTOArray(
  items: any,
  type: ActionType,
): items is ItemDTO[] {
  return type === 'add';
}

export function isShoppingCartItemDTO(
  item: any,
  type: ActionType,
): item is ShoppingCartItemDTO {
  return type === 'update';
}

export function isShoppingCartItemDTOArray(
  items: any,
  type: ActionType,
): items is ShoppingCartItemDTO[] {
  return type === 'update';
}

export function mapToItemData(item: Item, type: ActionType): ItemData {
  const price: PriceDTO = {};

  if (isItemDTO(item, type)) {
    price.value = item?.catalogAvailability?.price?.value ?? {};
    price.vat = item?.catalogAvailability?.price?.vat ?? {};

    return {
      ean: item.product.ean,
      itemId: item.id,
      price,
      sourceId: item.id,
      quantity: item.quantity ?? 1,
    };
  } else {
    price.value = item?.unitPrice?.value ?? {};
    price.vat = item?.unitPrice?.vat ?? {};

    return {
      ean: item.product.ean,
      itemId: Number(item.product.catalogProductNumber),
      price,
      sourceId: item.id,
      quantity: item.quantity ?? 1,
    };
  }
}

export function isDownload(item: Item): boolean {
  return item.product.format === 'DL' || item.product.format === 'EB';
}

export function isGiftCard(item: Item, type: ActionType): boolean {
  if (isItemDTO(item, type)) {
    return item?.type === GIFT_CARD_TYPE;
  } else {
    return item?.itemType === GIFT_CARD_TYPE;
  }
}

export function isArchive(item: Item, type: ActionType): boolean {
  if (isItemDTO(item, type)) {
    return item?.features?.some((f) => f.key === 'ARC');
  } else {
    return !!item?.features?.['ARC'];
  }
}

export function mapToItemPayload({
  item,
  quantity,
  availability,
  type,
}: {
  item: ItemDTO | ShoppingCartItemDTO;
  quantity: number;
  availability: AvailabilityDTO;
  type: ActionType;
}): ItemPayloadWithSourceId {
  return {
    availabilities: [
      mapToOlaAvailability({ item, quantity, availability, type }),
    ],
    id: String(getCatalogId(item, type)),
    sourceId: item.id,
  };
}

export function getCatalogId(
  item: ItemDTO | ShoppingCartItemDTO,
  type: ActionType,
): number | string {
  return isItemDTO(item, type) ? item.id : item.product.catalogProductNumber;
}

export function mapToOlaAvailability({
  availability,
  item,
  quantity,
  type,
}: {
  availability: AvailabilityDTO;
  item: ItemDTO | ShoppingCartItemDTO;
  quantity: number;
  type: ActionType;
}): OLAAvailabilityDTO {
  return {
    status: availability?.availabilityType,
    at: availability?.estimatedShippingDate,
    ean: item?.product?.ean,
    itemId: Number(getCatalogId(item, type)),
    format: item?.product?.format,
    isPrebooked: availability?.isPrebooked,
    logisticianId: availability?.logistician?.id,
    price: availability?.price,
    qty: quantity,
    ssc: availability?.ssc,
    sscText: availability?.sscText,
    supplierId: availability?.supplier?.id,
    supplierProductNumber: availability?.supplierProductNumber,
  };
}

export function getOrderTypeForPurchaseOption(
  purchaseOption: PurchaseOption,
): OrderTypeFeature | undefined {
  switch (purchaseOption) {
    case 'delivery':
    case 'dig-delivery':
    case 'b2b-delivery':
      return 'Versand';
    case 'pickup':
      return 'Abholung';
    case 'in-store':
      return 'Rücklage';
    case 'download':
      return 'Download';
    default:
      return undefined;
  }
}

export function getPurchaseOptionForOrderType(
  orderType: OrderTypeFeature,
): PurchaseOption | undefined {
  switch (orderType) {
    case 'Versand':
      return 'delivery';
    case 'Abholung':
      return 'pickup';
    case 'Rücklage':
      return 'in-store';
    case 'Download':
      return 'download';
    default:
      return undefined;
  }
}
