import {
  orderConfigurationsSchema,
  orderSelectionsSchema,
  type CheckoutCart,
  type OrderConfigurations,
  type CreateOrderRequest,
  type OrderSelections,
} from "./schema.js";
import { ORDER_TYPE, type OrderTypeValue } from "./contract.js";

export type CheckoutOrderTypeValue = Extract<OrderTypeValue, "Internet" | "SIM" | "VPN">;

export function isCheckoutOrderType(value: unknown): value is CheckoutOrderTypeValue {
  return value === ORDER_TYPE.INTERNET || value === ORDER_TYPE.SIM || value === ORDER_TYPE.VPN;
}

export function toCheckoutOrderType(orderType: OrderTypeValue): CheckoutOrderTypeValue | null {
  return isCheckoutOrderType(orderType) ? orderType : null;
}

export function toOrderTypeValueFromCheckout(
  orderType: string | null | undefined
): OrderTypeValue | null {
  return isCheckoutOrderType(orderType) ? orderType : null;
}

export function buildOrderConfigurations(selections: OrderSelections): OrderConfigurations {
  const normalizedSelections = orderSelectionsSchema.parse(selections);

  return orderConfigurationsSchema.parse({
    ...normalizedSelections,
    address: normalizedSelections.address
      ? {
          street: normalizedSelections.address.street ?? null,
          streetLine2: normalizedSelections.address.streetLine2 ?? null,
          city: normalizedSelections.address.city ?? null,
          state: normalizedSelections.address.state ?? null,
          postalCode: normalizedSelections.address.postalCode ?? null,
          country: normalizedSelections.address.country ?? null,
        }
      : undefined,
  });
}

export function createOrderRequest(payload: {
  orderType?: string;
  skus: string[];
  configurations?: OrderSelections | null;
}): CreateOrderRequest {
  const orderType = (payload.orderType ?? ORDER_TYPE.OTHER) as CreateOrderRequest["orderType"];
  const configurations = payload.configurations
    ? buildOrderConfigurations(payload.configurations)
    : undefined;
  return {
    orderType,
    skus: payload.skus,
    ...(configurations ? { configurations } : {}),
  };
}

/**
 * Transform CheckoutCart into CreateOrderRequest
 * Handles SKU extraction, validation, and payload formatting
 *
 * @throws Error if no products are selected
 */
export function prepareOrderFromCart(
  cart: CheckoutCart,
  orderType: OrderTypeValue
): CreateOrderRequest {
  const uniqueSkus = [
    ...new Set(
      cart.items
        .map(item => item.sku)
        .filter((sku): sku is string => typeof sku === "string" && sku.trim().length > 0)
    ),
  ];

  if (uniqueSkus.length === 0) {
    throw new Error("No products selected for order. Please go back and select products.");
  }

  // Note: Zod validation of the final structure should happen at the boundary or via schema.parse
  // This function focuses on the structural transformation logic.

  const orderData: CreateOrderRequest = {
    orderType,
    skus: uniqueSkus,
    ...(Object.keys(cart.configuration).length > 0 ? { configurations: cart.configuration } : {}),
  };

  return orderData;
}
