import { z } from 'zod';
import { EntityContainerSchema } from '@isa/common/data-access';
import { AvailabilitySchema } from './availability.schema';
import { CampaignSchema } from './campaign.schema';
import { DestinationSchema } from './destination.schema';
import { ItemTypeSchema } from './item-type.schema';
import { LoyaltySchema } from './loyalty.schema';
import { PriceFlatSchema } from './price-flat.schema';
import { ProductSchema } from './product.schema';
import { PromotionSchema } from './promotion.schema';

// Base schema for all add to shopping cart items
const AddToShoppingCartBaseSchema = z.object({
  availability: AvailabilitySchema.describe('Availability'),
  campaign: CampaignSchema.describe('Campaign information').optional(),
  destination: EntityContainerSchema(DestinationSchema).describe(
    'Destination information',
  ),
  itemType: ItemTypeSchema.describe('Item type').optional(),
  loyalty: LoyaltySchema.describe('Loyalty information').optional(),
  product: ProductSchema.describe('Product').optional(),
  promotion: PromotionSchema.describe('Promotion information').optional(),
  quantity: z.number().int().positive().describe('Quantity'),
  retailPrice: PriceFlatSchema.describe('Retail price').optional(),
  shopItemId: z
    .number()
    .int()
    .positive()
    .describe('ShopItem identifier')
    .optional(),
});

// Apply business rules validation
const AddToShoppingCartSchema = AddToShoppingCartBaseSchema.refine(
  (data) => {
    // When loyalty points are used, promotion must not be present
    if (data.loyalty && data.promotion) {
      return false;
    }
    return true;
  },
  {
    message: 'Promotion is not allowed when using loyalty points',
  },
).refine(
  (data) => {
    // When loyalty points are used, price value should be 0
    if (data.loyalty && data.availability?.price?.value?.value !== 0) {
      return false;
    }
    return true;
  },
  {
    message: 'Price value must be 0 when using loyalty points for redemption',
  },
);

export const AddItemToShoppingCartParamsSchema = z.object({
  shoppingCartId: z
    .number()
    .int()
    .positive()
    .describe('Shopping cart identifier'),
  items: z.array(AddToShoppingCartSchema).min(1).describe('List of items'),
});

export type AddItemToShoppingCartParams = z.infer<
  typeof AddItemToShoppingCartParamsSchema
>;
