import { parseAmount } from "../../../providers/whmcs/utils";
import {
  whmcsCatalogProductListResponseSchema,
  type WhmcsCatalogProductListResponse,
} from "./raw.types";

export interface WhmcsCatalogPricing {
  currency: string;
  prefix?: string;
  suffix?: string;
  monthly?: number;
  quarterly?: number;
  semiannually?: number;
  annually?: number;
  biennially?: number;
  triennially?: number;
  setupFees: {
    monthly?: number;
    quarterly?: number;
    semiannually?: number;
    annually?: number;
    biennially?: number;
    triennially?: number;
  };
}

export interface WhmcsCatalogProductNormalized {
  id: string;
  groupId: number;
  name: string;
  description: string;
  module: string;
  payType: string;
  pricing: Record<string, WhmcsCatalogPricing>;
}

const cycles = [
  "monthly",
  "quarterly",
  "semiannually",
  "annually",
  "biennially",
  "triennially",
] as const;

const setupFeeKeys = [
  "msetupfee",
  "qsetupfee",
  "ssetupfee",
  "asetupfee",
  "bsetupfee",
  "tsetupfee",
] as const;

const normalizePrice = (value: string | undefined): number | undefined =>
  value === undefined ? undefined : parseAmount(value);

export function parseWhmcsCatalogProductListResponse(
  raw: unknown
): WhmcsCatalogProductListResponse {
  return whmcsCatalogProductListResponseSchema.parse(raw);
}

export function transformWhmcsCatalogProductsResponse(
  raw: unknown
): WhmcsCatalogProductNormalized[] {
  const parsed = parseWhmcsCatalogProductListResponse(raw);
  const products = parsed.products.product;

  return products.map(product => {
    const pricingEntries = Object.entries(product.pricing ?? {});
    const pricing = pricingEntries.reduce<Record<string, WhmcsCatalogPricing>>(
      (acc, [currency, cyclePricing]) => {
        const normalizedCycles: Partial<WhmcsCatalogPricing> = {
          currency,
          prefix: cyclePricing.prefix,
          suffix: cyclePricing.suffix,
        };

        cycles.forEach(cycle => {
          const value = cyclePricing[cycle];
          if (value !== undefined) {
            normalizedCycles[cycle] = normalizePrice(value);
          }
        });

        const setupFees: WhmcsCatalogPricing["setupFees"] = {};
        setupFeeKeys.forEach((feeKey, index) => {
          const value = cyclePricing[feeKey];
          if (value !== undefined) {
            setupFees[cycles[index]] = normalizePrice(value);
          }
        });

        acc[currency] = {
          currency,
          prefix: cyclePricing.prefix,
          suffix: cyclePricing.suffix,
          monthly: normalizedCycles.monthly,
          quarterly: normalizedCycles.quarterly,
          semiannually: normalizedCycles.semiannually,
          annually: normalizedCycles.annually,
          biennially: normalizedCycles.biennially,
          triennially: normalizedCycles.triennially,
          setupFees,
        };

        return acc;
      },
      {}
    );

    return {
      id: String(product.pid),
      groupId: product.gid,
      name: product.name,
      description: product.description,
      module: product.module,
      payType: product.paytype,
      pricing,
    } satisfies WhmcsCatalogProductNormalized;
  });
}
