/**
 * WHMCS Provider - Mapper
 *
 * Maps WHMCS API responses to domain types.
 * Minimal transformation - validates and normalizes only address structure.
 */

import type { WhmcsClient, Address } from "../../schema.js";
import { whmcsClientSchema, addressSchema } from "../../schema.js";
import {
  whmcsClientSchema as whmcsRawClientSchema,
  whmcsClientResponseSchema,
  type WhmcsClient as WhmcsRawClient,
  type WhmcsClientResponse,
} from "./raw.types.js";

/**
 * Parse and validate WHMCS client response
 */
export const parseWhmcsClientResponse = (raw: unknown): WhmcsClientResponse =>
  whmcsClientResponseSchema.parse(raw);

/**
 * Transform WHMCS client response to domain WhmcsClient
 */
export function transformWhmcsClientResponse(response: unknown): WhmcsClient {
  const parsed = parseWhmcsClientResponse(response);
  return transformWhmcsClient(parsed.client);
}

/**
 * Transform raw WHMCS client to domain WhmcsClient
 *
 * Keeps raw WHMCS field names, only normalizes:
 * - Address structure to domain Address type
 * - Type coercions (strings to numbers/booleans)
 */
export function transformWhmcsClient(raw: WhmcsRawClient): WhmcsClient {
  return whmcsClientSchema.parse({
    ...raw,
    // Only normalize address to our domain structure
    address: normalizeAddress(raw),
  });
}

/**
 * Normalize WHMCS address fields to domain Address structure
 */
function normalizeAddress(client: WhmcsRawClient): Address | undefined {
  const address = addressSchema.parse({
    address1: client.address1 ?? null,
    address2: client.address2 ?? null,
    city: client.city ?? null,
    state: client.fullstate ?? client.state ?? null,
    postcode: client.postcode ?? null,
    country: client.country ?? null,
    countryCode: client.countrycode ?? null,
    phoneNumber: client.phonenumberformatted ?? client.phonenumber ?? null,
    phoneCountryCode: client.phonecc ?? null,
  });

  const hasValues = Object.values(address).some(v => v !== undefined && v !== null && v !== "");
  return hasValues ? address : undefined;
}

/**
 * Transform WHMCS client address to domain Address
 */
export const transformWhmcsClientAddress = (raw: unknown): Address | undefined => {
  const client = whmcsRawClientSchema.parse(raw);
  return normalizeAddress(client);
};

/**
 * Mapping from domain Address keys to WHMCS API field names
 */
const ADDRESS_FIELD_MAP: Record<keyof Address, string> = {
  address1: "address1",
  address2: "address2",
  city: "city",
  state: "state",
  postcode: "postcode",
  country: "country",
  countryCode: "countrycode",
  phoneNumber: "phonenumber",
  phoneCountryCode: "phonecc",
};

/**
 * Prepare address update for WHMCS API
 * Converts domain Address to WHMCS field names
 */
export const prepareWhmcsClientAddressUpdate = (
  address: Partial<Address>
): Record<string, unknown> => {
  const update: Record<string, unknown> = {};
  for (const [domainKey, whmcsKey] of Object.entries(ADDRESS_FIELD_MAP)) {
    const value = address[domainKey as keyof Address];
    if (value !== undefined) {
      update[whmcsKey] = value ?? "";
    }
  }
  return update;
};
