import { z } from "zod";

export const envSchema = z.object({
  NODE_ENV: z.enum(["development", "test", "production"]).default("development"),
  BFF_PORT: z.coerce.number().int().positive().max(65535).default(4000),
  LOG_LEVEL: z.enum(["error", "warn", "info", "debug", "trace"]).default("info"),
  APP_NAME: z.string().default("customer-portal-bff"),

  JWT_SECRET: z.string().min(32, "JWT secret must be at least 32 characters"),
  JWT_EXPIRES_IN: z.string().default("7d"),
  BCRYPT_ROUNDS: z.coerce.number().int().min(12).max(16).default(14),
  APP_BASE_URL: z.string().url().default("http://localhost:3000"),

  CSRF_TOKEN_EXPIRY: z.coerce.number().int().positive().default(3600000),
  CSRF_SECRET_KEY: z.string().min(32, "CSRF secret key must be at least 32 characters").optional(),
  CSRF_COOKIE_NAME: z.string().default("csrf-secret"),
  CSRF_HEADER_NAME: z.string().default("X-CSRF-Token"),

  CORS_ORIGIN: z.string().url().optional(),
  TRUST_PROXY: z.enum(["true", "false"]).default("false"),

  RATE_LIMIT_TTL: z.coerce.number().int().positive().default(60),
  RATE_LIMIT_LIMIT: z.coerce.number().int().positive().default(100),
  AUTH_RATE_LIMIT_TTL: z.coerce.number().int().positive().default(900),
  AUTH_RATE_LIMIT_LIMIT: z.coerce.number().int().positive().default(3),
  AUTH_REFRESH_RATE_LIMIT_TTL: z.coerce.number().int().positive().default(300),
  AUTH_REFRESH_RATE_LIMIT_LIMIT: z.coerce.number().int().positive().default(10),
  AUTH_CAPTCHA_PROVIDER: z.enum(["none", "turnstile", "hcaptcha"]).default("none"),
  AUTH_CAPTCHA_SECRET: z.string().optional(),
  AUTH_CAPTCHA_THRESHOLD: z.coerce.number().min(0).default(0),
  AUTH_CAPTCHA_ALWAYS_ON: z.enum(["true", "false"]).default("false"),

  LOGIN_RATE_LIMIT_TTL: z.coerce.number().int().positive().default(900),
  LOGIN_RATE_LIMIT_LIMIT: z.coerce.number().int().positive().default(5),
  LOGIN_CAPTCHA_AFTER_ATTEMPTS: z.coerce.number().int().nonnegative().default(3),
  SIGNUP_RATE_LIMIT_TTL: z.coerce.number().int().positive().default(900),
  SIGNUP_RATE_LIMIT_LIMIT: z.coerce.number().int().positive().default(5),
  PASSWORD_RESET_RATE_LIMIT_TTL: z.coerce.number().int().positive().default(900),
  PASSWORD_RESET_RATE_LIMIT_LIMIT: z.coerce.number().int().positive().default(5),

  REDIS_URL: z.string().url().default("redis://localhost:6379"),
  AUTH_ALLOW_REDIS_TOKEN_FAILOPEN: z.enum(["true", "false"]).default("false"),
  AUTH_REQUIRE_REDIS_FOR_TOKENS: z.enum(["true", "false"]).default("false"),
  AUTH_MAINTENANCE_MODE: z.enum(["true", "false"]).default("false"),
  AUTH_MAINTENANCE_MESSAGE: z
    .string()
    .default(
      "Authentication service is temporarily unavailable for maintenance. Please try again later."
    ),

  DATABASE_URL: z.string().url(),

  WHMCS_BASE_URL: z.string().url().optional(),
  WHMCS_API_IDENTIFIER: z.string().optional(),
  WHMCS_API_SECRET: z.string().optional(),
  WHMCS_WEBHOOK_SECRET: z.string().optional(),
  WHMCS_DEV_BASE_URL: z.string().url().optional(),
  WHMCS_DEV_API_IDENTIFIER: z.string().optional(),
  WHMCS_DEV_API_SECRET: z.string().optional(),
  WHMCS_DEV_WEBHOOK_SECRET: z.string().optional(),

  SF_LOGIN_URL: z.string().url().optional(),
  SF_USERNAME: z.string().optional(),
  SF_CLIENT_ID: z.string().optional(),
  SF_PRIVATE_KEY_PATH: z.string().optional(),
  SF_WEBHOOK_SECRET: z.string().optional(),
  SF_AUTH_TIMEOUT_MS: z.coerce.number().int().positive().default(30000),
  SF_TOKEN_TTL_MS: z.coerce.number().int().positive().default(720000),
  SF_TOKEN_REFRESH_BUFFER_MS: z.coerce.number().int().positive().default(60000),

  // Queue Throttling Configuration
  WHMCS_QUEUE_CONCURRENCY: z.coerce.number().int().positive().default(15),
  WHMCS_QUEUE_INTERVAL_CAP: z.coerce.number().int().positive().default(300),
  WHMCS_QUEUE_TIMEOUT_MS: z.coerce.number().int().positive().default(30000),
  SF_QUEUE_CONCURRENCY: z.coerce.number().int().positive().default(15),
  SF_QUEUE_LONG_RUNNING_CONCURRENCY: z.coerce.number().int().positive().default(22),
  SF_QUEUE_INTERVAL_CAP: z.coerce.number().int().positive().default(600),
  SF_QUEUE_TIMEOUT_MS: z.coerce.number().int().positive().default(30000),
  SF_QUEUE_LONG_RUNNING_TIMEOUT_MS: z.coerce.number().int().positive().default(600000),

  SF_EVENTS_ENABLED: z.enum(["true", "false"]).default("false"),
  SF_CATALOG_EVENT_CHANNEL: z.string().default("/event/Product_and_Pricebook_Change__e"),
  SF_ACCOUNT_EVENT_CHANNEL: z.string().default("/event/Account_Internet_Eligibility_Update__e"),
  SF_EVENTS_REPLAY: z.enum(["LATEST", "ALL"]).default("LATEST"),
  SF_PUBSUB_NUM_REQUESTED: z.string().default("25"),
  SF_PUBSUB_QUEUE_MAX: z.string().default("100"),
  SF_PUBSUB_ENDPOINT: z.string().default("api.pubsub.salesforce.com:7443"),

  // CDC-specific channels (using /data/ prefix for Change Data Capture)
  SF_CATALOG_PRODUCT_CDC_CHANNEL: z.string().default("/data/Product2ChangeEvent"),
  SF_CATALOG_PRICEBOOKENTRY_CDC_CHANNEL: z.string().default("/data/PricebookEntryChangeEvent"),
  SF_ACCOUNT_ELIGIBILITY_CHANNEL: z.string().optional(),
  SF_ORDER_CDC_CHANNEL: z.string().default("/data/OrderChangeEvent"),
  SF_ORDER_ITEM_CDC_CHANNEL: z.string().default("/data/OrderItemChangeEvent"),

  SENDGRID_API_KEY: z.string().optional(),
  EMAIL_FROM: z.string().email().default("no-reply@example.com"),
  EMAIL_FROM_NAME: z.string().default("Assist Solutions"),
  EMAIL_ENABLED: z.enum(["true", "false"]).default("true"),
  EMAIL_USE_QUEUE: z.enum(["true", "false"]).default("true"),
  SENDGRID_SANDBOX: z.enum(["true", "false"]).default("false"),
  EMAIL_TEMPLATE_RESET: z.string().optional(),
  EMAIL_TEMPLATE_WELCOME: z.string().optional(),

  FREEBIT_BASE_URL: z.string().url().default("https://i1-q.mvno.net/emptool/api/"),
  FREEBIT_OEM_ID: z.string().default("PASI"),
  FREEBIT_OEM_KEY: z.string().optional(),
  FREEBIT_TIMEOUT: z.coerce.number().int().positive().default(30000),
  FREEBIT_RETRY_ATTEMPTS: z.coerce.number().int().positive().default(3),
  FREEBIT_DETAILS_ENDPOINT: z.string().default("/master/getAcnt/"),

  // Portal Configuration
  PORTAL_PRICEBOOK_ID: z.string().default("01sTL000008eLVlYAM"),
  PORTAL_PRICEBOOK_NAME: z.string().default("Portal"),

  // Salesforce Field Mappings - Account
  ACCOUNT_INTERNET_ELIGIBILITY_FIELD: z.string().default("Internet_Eligibility__c"),
  ACCOUNT_CUSTOMER_NUMBER_FIELD: z.string().default("SF_Account_No__c"),

  // Salesforce Field Mappings - Product
  PRODUCT_SKU_FIELD: z.string().default("StockKeepingUnit"),
  PRODUCT_PORTAL_CATEGORY_FIELD: z.string().default("Product2Categories1__c"),
  PRODUCT_PORTAL_CATALOG_FIELD: z.string().default("Portal_Catalog__c"),
  PRODUCT_PORTAL_ACCESSIBLE_FIELD: z.string().default("Portal_Accessible__c"),
  ACCOUNT_PORTAL_STATUS_FIELD: z.string().default("Portal_Status__c"),
  ACCOUNT_PORTAL_STATUS_SOURCE_FIELD: z.string().default("Portal_Registration_Source__c"),
  ACCOUNT_PORTAL_LAST_SIGNED_IN_FIELD: z.string().default("Portal_Last_SignIn__c"),
  PRODUCT_ITEM_CLASS_FIELD: z.string().default("Item_Class__c"),
  PRODUCT_BILLING_CYCLE_FIELD: z.string().default("Billing_Cycle__c"),
  PRODUCT_WHMCS_PRODUCT_ID_FIELD: z.string().default("WH_Product_ID__c"),
  PRODUCT_WHMCS_PRODUCT_NAME_FIELD: z.string().default("WH_Product_Name__c"),
  PRODUCT_INTERNET_PLAN_TIER_FIELD: z.string().default("Internet_Plan_Tier__c"),
  PRODUCT_INTERNET_OFFERING_TYPE_FIELD: z.string().default("Internet_Offering_Type__c"),
  PRODUCT_DISPLAY_ORDER_FIELD: z.string().default("Catalog_Order__c"),
  PRODUCT_BUNDLED_ADDON_FIELD: z.string().default("Bundled_Addon__c"),
  PRODUCT_IS_BUNDLED_ADDON_FIELD: z.string().default("Is_Bundled_Addon__c"),
  PRODUCT_SIM_DATA_SIZE_FIELD: z.string().default("SIM_Data_Size__c"),
  PRODUCT_SIM_PLAN_TYPE_FIELD: z.string().default("SIM_Plan_Type__c"),
  PRODUCT_SIM_HAS_FAMILY_DISCOUNT_FIELD: z.string().default("SIM_Has_Family_Discount__c"),
  PRODUCT_VPN_REGION_FIELD: z.string().default("VPN_Region__c"),

  // Salesforce Field Mappings - Order
  ORDER_TYPE_FIELD: z.string().default("Type"),
  ORDER_ACTIVATION_TYPE_FIELD: z.string().default("Activation_Type__c"),
  ORDER_ACTIVATION_SCHEDULED_AT_FIELD: z.string().default("Activation_Scheduled_At__c"),
  ORDER_ACTIVATION_STATUS_FIELD: z.string().default("Activation_Status__c"),
  ORDER_INTERNET_PLAN_TIER_FIELD: z.string().default("Internet_Plan_Tier__c"),
  ORDER_INSTALLATION_TYPE_FIELD: z.string().default("Installment_Plan__c"),
  ORDER_WEEKEND_INSTALL_FIELD: z.string().default("Weekend_Install__c"),
  ORDER_ACCESS_MODE_FIELD: z.string().default("Access_Mode__c"),
  ORDER_HIKARI_DENWA_FIELD: z.string().default("Hikari_Denwa__c"),
  ORDER_VPN_REGION_FIELD: z.string().default("VPN_Region__c"),
  ORDER_SIM_TYPE_FIELD: z.string().default("SIM_Type__c"),
  ORDER_EID_FIELD: z.string().default("EID__c"),
  ORDER_SIM_VOICE_MAIL_FIELD: z.string().default("SIM_Voice_Mail__c"),
  ORDER_SIM_CALL_WAITING_FIELD: z.string().default("SIM_Call_Waiting__c"),
  ORDER_MNP_APPLICATION_FIELD: z.string().default("MNP_Application__c"),
  ORDER_MNP_RESERVATION_FIELD: z.string().default("MNP_Reservation_Number__c"),
  ORDER_MNP_EXPIRY_FIELD: z.string().default("MNP_Expiry_Date__c"),
  ORDER_MNP_PHONE_FIELD: z.string().default("MNP_Phone_Number__c"),
  ORDER_MVNO_ACCOUNT_NUMBER_FIELD: z.string().default("MVNO_Account_Number__c"),
  ORDER_PORTING_DOB_FIELD: z.string().default("Porting_DateOfBirth__c"),
  ORDER_PORTING_FIRST_NAME_FIELD: z.string().default("Porting_FirstName__c"),
  ORDER_PORTING_LAST_NAME_FIELD: z.string().default("Porting_LastName__c"),
  ORDER_PORTING_FIRST_NAME_KATAKANA_FIELD: z.string().default("Porting_FirstName_Katakana__c"),
  ORDER_PORTING_LAST_NAME_KATAKANA_FIELD: z.string().default("Porting_LastName_Katakana__c"),
  ORDER_PORTING_GENDER_FIELD: z.string().default("Porting_Gender__c"),
  ORDER_WHMCS_ORDER_ID_FIELD: z.string().default("WHMCS_Order_ID__c"),
  ORDER_ACTIVATION_ERROR_CODE_FIELD: z.string().default("Activation_Error_Code__c"),
  ORDER_ACTIVATION_ERROR_MESSAGE_FIELD: z.string().default("Activation_Error_Message__c"),
  ORDER_ACTIVATION_LAST_ATTEMPT_AT_FIELD: z.string().default("ActivatedDate"),
  ORDER_ADDRESS_CHANGED_FIELD: z.string().default("Address_Changed__c"),
  ORDER_BILLING_STREET_FIELD: z.string().default("BillingStreet"),
  ORDER_BILLING_CITY_FIELD: z.string().default("BillingCity"),
  ORDER_BILLING_STATE_FIELD: z.string().default("BillingState"),
  ORDER_BILLING_POSTAL_CODE_FIELD: z.string().default("BillingPostalCode"),
  ORDER_BILLING_COUNTRY_FIELD: z.string().default("BillingCountry"),

  // Salesforce Field Mappings - Order Item
  ORDER_ITEM_BILLING_CYCLE_FIELD: z.string().default("Billing_Cycle__c"),
  ORDER_ITEM_WHMCS_SERVICE_ID_FIELD: z.string().default("WHMCS_Service_ID__c"),
});

export function validate(config: Record<string, unknown>): Record<string, unknown> {
  const result = envSchema.safeParse(config);
  if (!result.success) {
    const flattened = result.error.flatten();
    const messages = [
      ...Object.entries(flattened.fieldErrors).flatMap(([key, errs]) =>
        (errs || []).map(e => `${key}: ${e}`)
      ),
      ...(flattened.formErrors || []),
    ];
    throw new Error(`Invalid environment configuration: ${messages.join("; ")}`);
  }
  return result.data;
}
