/**
 * WHMCS Subscriptions Provider - Raw Types
 * 
 * Type definitions for the WHMCS subscriptions API contract:
 * - Request parameter types (API inputs)
 * - Response types (API outputs)
 */

import { z } from "zod";

const normalizeRequiredNumber = z.preprocess(
  value => {
    if (typeof value === "number") return value;
    if (typeof value === "string" && value.trim().length > 0) {
      const parsed = Number(value);
      return Number.isFinite(parsed) ? parsed : value;
    }
    return value;
  },
  z.number()
);

const normalizeOptionalNumber = z.preprocess(
  value => {
    if (value === undefined || value === null || value === "") return undefined;
    if (typeof value === "number") return value;
    if (typeof value === "string") {
      const parsed = Number(value);
      return Number.isFinite(parsed) ? parsed : undefined;
    }
    return undefined;
  },
  z.number().optional()
);

const optionalStringField = () =>
  z
    .union([z.string(), z.number()])
    .optional()
    .nullable()
    .transform(value => {
      if (value === undefined || value === null) return undefined;
      const text = String(value).trim();
      return text.length > 0 ? text : undefined;
    });

// ============================================================================
// Request Parameter Types
// ============================================================================

/**
 * Parameters for WHMCS GetClientsProducts API
 */
export interface WhmcsGetClientsProductsParams {
  clientid: number;
  serviceid?: number;
  pid?: number;
  domain?: string;
  limitstart?: number;
  limitnum?: number;
  orderby?: "id" | "productname" | "regdate" | "nextduedate";
  order?: "ASC" | "DESC";
  [key: string]: unknown;
}

// ============================================================================
// Response Types
// ============================================================================

// Custom field structure
export const whmcsCustomFieldSchema = z.object({
  id: z.number().optional(),
  name: z.string().optional(),
  value: z.string().optional(),
});

export const whmcsCustomFieldsContainerSchema = z.object({
  customfield: z.union([whmcsCustomFieldSchema, z.array(whmcsCustomFieldSchema)]),
});

// Raw WHMCS Product/Service (Subscription)
export const whmcsProductRawSchema = z.object({
  id: normalizeRequiredNumber,
  clientid: normalizeRequiredNumber,
  serviceid: normalizeOptionalNumber,
  pid: normalizeOptionalNumber,
  orderid: normalizeOptionalNumber,
  ordernumber: optionalStringField(),
  regdate: z.string(),
  name: z.string(),
  translated_name: z.string().optional(),
  groupname: z.string().optional(),
  translated_groupname: z.string().optional(),
  domain: optionalStringField(),
  dedicatedip: optionalStringField(),
  serverid: normalizeOptionalNumber,
  servername: optionalStringField(),
  serverip: optionalStringField(),
  serverhostname: optionalStringField(),
  suspensionreason: z.string().optional(),
  promoid: normalizeOptionalNumber,
  subscriptionid: z.string().optional(),
  
  // Pricing
  firstpaymentamount: z.union([z.string(), z.number()]).optional(),
  amount: z.union([z.string(), z.number()]).optional(),
  recurringamount: z.union([z.string(), z.number()]).optional(),
  billingcycle: z.string().optional(),
  paymentmethod: z.string().optional(),
  paymentmethodname: z.string().optional(),
  
  // Dates
  nextduedate: z.string().optional(),
  nextinvoicedate: z.string().optional(),
  
  // Status
  status: z.string(),
  username: z.string().optional(),
  password: z.string().optional(),
  
  // Notes
  notes: z.string().optional(),
  diskusage: normalizeOptionalNumber,
  disklimit: normalizeOptionalNumber,
  bwusage: normalizeOptionalNumber,
  bwlimit: normalizeOptionalNumber,
  lastupdate: z.string().optional(),
  
  // Custom fields
  customfields: whmcsCustomFieldsContainerSchema.optional(),
  
  // Pricing details
  pricing: z.object({
    amount: z.union([z.string(), z.number()]).optional(),
    currency: z.string().optional(),
    currencyprefix: z.string().optional(),
    currencysuffix: z.string().optional(),
  }).optional(),
});

export type WhmcsProductRaw = z.infer<typeof whmcsProductRawSchema>;
export type WhmcsCustomField = z.infer<typeof whmcsCustomFieldSchema>;

// ============================================================================
// WHMCS Product List Response (GetClientsProducts API)
// ============================================================================

/**
 * WHMCS GetClientsProducts API response schema
 */
export const whmcsProductListResponseSchema = z.object({
  result: z.enum(["success", "error"]).optional(),
  message: z.string().optional(),
  clientid: z.union([z.number(), z.string()]).optional(),
  serviceid: z.union([z.number(), z.string(), z.null()]).optional(),
  pid: z.union([z.number(), z.string(), z.null()]).optional(),
  domain: z.string().nullable().optional(),
  totalresults: z.union([z.number(), z.string()]).optional(),
  startnumber: normalizeOptionalNumber,
  numreturned: normalizeOptionalNumber,
  products: z.object({
    product: z
      .preprocess(value => {
        if (value === null || value === undefined || value === "") {
          return undefined;
        }
        return value;
      }, z.union([whmcsProductRawSchema, z.array(whmcsProductRawSchema)]).optional())
  }).optional(),
});

export type WhmcsProductListResponse = z.infer<typeof whmcsProductListResponseSchema>;
