import type { HybxEnvironment } from './types';

export type HybxConfig = {
  environment: HybxEnvironment;
  baseUrl: string;
  clientId: string;
  clientSecret: string;
  apiKey: string;
  mtlsCertPath?: string;
  mtlsKeyPath?: string;
  webhookSecret: string;
  requestTimeoutMs: number;
  maxRetries: number;
};

const PLACEHOLDER_PATTERNS = /^(placeholder|changeme|example|test|dummy|xxx*)$/i;
const PRODUCTION_URL_PATTERNS = /hybxfinance\.io|hybx\.(prod|production)/i;

function requireEnv(name: string, value: string | undefined): string {
  if (!value || value.trim() === '') {
    throw new Error(`Missing required environment variable: ${name}`);
  }
  return value.trim();
}

function parseEnvironment(raw: string | undefined): HybxEnvironment {
  const v = (raw ?? 'sandbox').toLowerCase();
  if (v === 'sandbox' || v === 'staging' || v === 'production') return v;
  throw new Error(`Invalid HYBX_ENVIRONMENT: ${raw}`);
}

export type LoadHybxConfigOptions = {
  /** When true, reject production-like base URLs (for local/test). */
  testMode?: boolean;
  env?: NodeJS.ProcessEnv;
};

export function loadHybxConfig(options: LoadHybxConfigOptions = {}): HybxConfig {
  const env = options.env ?? process.env;
  const environment = parseEnvironment(env.HYBX_ENVIRONMENT);
  const baseUrl = requireEnv('HYBX_BASE_URL', env.HYBX_BASE_URL);

  if (options.testMode && PRODUCTION_URL_PATTERNS.test(baseUrl)) {
    throw new Error('HYBX_BASE_URL appears production-like; use sandbox URL in test mode');
  }

  if (environment === 'production' && options.testMode) {
    throw new Error('HYBX_ENVIRONMENT=production is not allowed in test mode');
  }

  const clientId = requireEnv('HYBX_CLIENT_ID', env.HYBX_CLIENT_ID);
  const clientSecret = requireEnv('HYBX_CLIENT_SECRET', env.HYBX_CLIENT_SECRET);
  const apiKey = requireEnv('HYBX_API_KEY', env.HYBX_API_KEY);
  const webhookSecret = requireEnv('HYBX_WEBHOOK_SECRET', env.HYBX_WEBHOOK_SECRET);

  for (const [key, val] of [
    ['HYBX_CLIENT_ID', clientId],
    ['HYBX_CLIENT_SECRET', clientSecret],
    ['HYBX_API_KEY', apiKey],
    ['HYBX_WEBHOOK_SECRET', webhookSecret],
  ] as const) {
    if (!PLACEHOLDER_PATTERNS.test(val) && options.testMode && environment === 'sandbox') {
      // Allow non-placeholder values in sandbox test mode but warn via validation helper
      void key;
    }
  }

  return {
    environment,
    baseUrl: baseUrl.replace(/\/$/, ''),
    clientId,
    clientSecret,
    apiKey,
    mtlsCertPath: env.HYBX_MTLS_CERT_PATH?.trim() || undefined,
    mtlsKeyPath: env.HYBX_MTLS_KEY_PATH?.trim() || undefined,
    webhookSecret,
    requestTimeoutMs: Number(env.HYBX_REQUEST_TIMEOUT_MS ?? 30_000),
    maxRetries: Number(env.HYBX_MAX_RETRIES ?? 3),
  };
}

export function validateHybxConfigForLocalTest(config: HybxConfig): string[] {
  const warnings: string[] = [];
  if (config.baseUrl.startsWith('http://')) {
    warnings.push('HYBX_BASE_URL uses plain HTTP');
  }
  if (config.environment === 'production') {
    warnings.push('HYBX_ENVIRONMENT is production');
  }
  return warnings;
}
