import { z } from "zod";

import {
  whmcsRequiredNumber,
  whmcsOptionalNumber,
  whmcsOptionalBoolean,
  whmcsString,
} from "../../../common/providers/whmcs-utils/index.js";

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

/**
 * Parameters for WHMCS ValidateLogin API
 */
export interface WhmcsValidateLoginParams {
  email: string;
  password2: string;
  [key: string]: unknown;
}

/**
 * Parameters for WHMCS AddClient API
 */
export interface WhmcsAddClientParams {
  firstname: string;
  lastname: string;
  email: string;
  address1?: string | undefined;
  city?: string | undefined;
  state?: string | undefined;
  postcode?: string | undefined;
  country?: string | undefined;
  phonenumber?: string | undefined;
  password2: string;
  companyname?: string | undefined;
  currency?: string | undefined;
  groupid?: number | undefined;
  /**
   * WHMCS API expects this as a base64 encoded serialized array.
   * @see https://developers.whmcs.com/api-reference/addclient/
   */
  customfields?: string | undefined;
  language?: string | undefined;
  clientip?: string | undefined;
  notes?: string | undefined;
  marketing_emails_opt_in?: boolean | undefined;
  no_email?: boolean | undefined;
  [key: string]: unknown;
}

/**
 * Parameters for WHMCS CreateSsoToken API
 */
export interface WhmcsCreateSsoTokenParams {
  client_id: number;
  destination?: string | undefined;
  sso_redirect_path?: string | undefined;
  [key: string]: unknown;
}

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

export const whmcsCustomFieldSchema = z
  .object({
    id: whmcsRequiredNumber,
    value: z.string().optional().nullable(),
    name: z.string().optional(),
    type: z.string().optional(),
  })
  .strip();

export const whmcsUserSchema = z
  .object({
    id: whmcsRequiredNumber,
    name: z.string(),
    email: z.string(),
    is_owner: whmcsOptionalBoolean,
  })
  .strip();

export const whmcsEmailPreferencesSchema = z
  .record(z.string(), z.union([z.string(), z.number(), z.boolean()]))
  .optional();

const customFieldsSchema = z
  .union([
    z.array(whmcsCustomFieldSchema),
    z
      .object({
        customfield: z.union([whmcsCustomFieldSchema, z.array(whmcsCustomFieldSchema)]),
      })
      .strip(),
  ])
  .optional();

const usersSchema = z
  .object({ user: z.union([whmcsUserSchema, z.array(whmcsUserSchema)]) })
  .strip()
  .optional();

export const whmcsClientSchema = z
  .object({
    client_id: whmcsOptionalNumber,
    owner_user_id: whmcsOptionalNumber,
    userid: whmcsOptionalNumber,
    id: whmcsRequiredNumber,
    uuid: z.string().optional(),
    firstname: z.string().optional(),
    lastname: z.string().optional(),
    fullname: z.string().optional(),
    companyname: z.string().optional(),
    email: z.string(),
    address1: z.string().optional(),
    address2: z.string().optional(),
    city: z.string().optional(),
    state: z.string().optional(),
    fullstate: z.string().optional(),
    statecode: z.string().optional(),
    postcode: z.string().optional(),
    country: z.string().optional(),
    countrycode: z.string().optional(),
    phonecc: whmcsString.optional(),
    phonenumber: z.string().optional(),
    phonenumberformatted: z.string().optional(),
    telephoneNumber: z.string().optional(),
    tax_id: z.string().optional(),
    currency: whmcsOptionalNumber,
    currency_code: z.string().optional(),
    defaultgateway: z.string().optional(),
    defaultpaymethodid: whmcsOptionalNumber,
    language: z.string().optional(),
    status: z.string().optional(),
    notes: z.string().optional(),
    datecreated: z.string().optional(),
    lastlogin: z.string().optional(),
    email_preferences: whmcsEmailPreferencesSchema,
    allowSingleSignOn: whmcsOptionalBoolean,
    email_verified: whmcsOptionalBoolean,
    marketing_emails_opt_in: whmcsOptionalBoolean,
    isOptedInToMarketingEmails: whmcsOptionalBoolean,
    phoneNumber: z.string().optional(),
    customfields: customFieldsSchema,
    users: usersSchema,
  })
  .strip();

export const whmcsClientStatsSchema = z
  .record(z.string(), z.union([z.string(), z.number(), z.boolean()]))
  .optional();

export const whmcsClientResponseSchema = z
  .object({
    result: z.string().optional(),
    client_id: whmcsOptionalNumber,
    client: whmcsClientSchema,
    stats: whmcsClientStatsSchema,
  })
  .strip();

export type WhmcsCustomField = z.infer<typeof whmcsCustomFieldSchema>;
export type WhmcsUser = z.infer<typeof whmcsUserSchema>;
export type WhmcsClient = z.infer<typeof whmcsClientSchema>;
export type WhmcsClientResponse = z.infer<typeof whmcsClientResponseSchema>;

// ============================================================================
// WHMCS Add Client Response
// ============================================================================

/**
 * WHMCS AddClient API response schema
 */
export const whmcsAddClientResponseSchema = z.object({
  clientid: z.number(),
});

export type WhmcsAddClientResponse = z.infer<typeof whmcsAddClientResponseSchema>;

// ============================================================================
// WHMCS Validate Login Response
// ============================================================================

/**
 * WHMCS ValidateLogin API response schema
 */
export const whmcsValidateLoginResponseSchema = z.object({
  userid: z.number(),
  passwordhash: z.string(),
  pwresetkey: z.string().optional(),
});

export type WhmcsValidateLoginResponse = z.infer<typeof whmcsValidateLoginResponseSchema>;

// ============================================================================
// WHMCS SSO Response
// ============================================================================

/**
 * WHMCS CreateSsoToken API response schema
 */
export const whmcsSsoResponseSchema = z.object({
  redirect_url: z.string(),
});

export type WhmcsSsoResponse = z.infer<typeof whmcsSsoResponseSchema>;
export type WhmcsClientStats = z.infer<typeof whmcsClientStatsSchema>;

// ============================================================================
// WHMCS Get Users Response
// ============================================================================

/**
 * WHMCS GetUsers API response schema
 * Used to look up users by email during account discovery
 *
 * @see https://developers.whmcs.com/api-reference/getusers/
 */
export const whmcsUserClientAssociationSchema = z.object({
  id: whmcsRequiredNumber,
  isOwner: z.boolean().optional(),
});

export const whmcsGetUsersUserSchema = z.object({
  id: whmcsRequiredNumber,
  firstname: z.string().optional(),
  lastname: z.string().optional(),
  email: z.string(),
  datecreated: z.string().optional(),
  validationdata: z.string().optional(),
  clients: z.array(whmcsUserClientAssociationSchema).optional().default([]),
});

export const whmcsGetUsersResponseSchema = z.object({
  totalresults: whmcsRequiredNumber,
  startnumber: whmcsOptionalNumber,
  numreturned: whmcsOptionalNumber,
  users: z.array(whmcsGetUsersUserSchema).optional().default([]),
});

export type WhmcsGetUsersUser = z.infer<typeof whmcsGetUsersUserSchema>;
export type WhmcsGetUsersResponse = z.infer<typeof whmcsGetUsersResponseSchema>;
