import { Injectable } from "@nestjs/common";
import { ConfigService } from "@nestjs/config";
import type { WhmcsApiConfig } from "../types/connection.types";

/**
 * Service for managing WHMCS API configuration
 * Handles environment-based configuration loading with dev/prod separation
 */
@Injectable()
export class WhmcsConfigService {
  private readonly config: WhmcsApiConfig;

  constructor(private readonly configService: ConfigService) {
    this.config = this.loadConfiguration();
  }

  /**
   * Get the complete WHMCS API configuration
   */
  getConfig(): WhmcsApiConfig {
    return { ...this.config };
  }

  /**
   * Get the base URL for WHMCS API
   */
  getBaseUrl(): string {
    return this.config.baseUrl;
  }

  /**
   * Validate that required configuration is present
   */
  validateConfig(): void {
    const required = ["baseUrl", "identifier", "secret"];
    const missing = required.filter(key => !this.config[key as keyof WhmcsApiConfig]);

    if (missing.length > 0) {
      throw new Error(`Missing required WHMCS configuration: ${missing.join(", ")}`);
    }

    if (!this.config.baseUrl.startsWith("http")) {
      throw new Error("WHMCS baseUrl must start with http:// or https://");
    }
  }

  /**
   * Load configuration from environment variables
   */
  private loadConfiguration(): WhmcsApiConfig {
    const nodeEnv = this.configService.get<string>("NODE_ENV", "development");
    const isDev = nodeEnv !== "production";

    // Resolve and normalize base URL (trim trailing slashes)
    const rawBaseUrl =
      this.getFirst([isDev ? "WHMCS_DEV_BASE_URL" : undefined, "WHMCS_BASE_URL"]) || "";
    const baseUrl = rawBaseUrl.replace(/\/+$/, "");

    const identifier =
      this.getFirst([isDev ? "WHMCS_DEV_API_IDENTIFIER" : undefined, "WHMCS_API_IDENTIFIER"]) || "";

    const secret =
      this.getFirst([isDev ? "WHMCS_DEV_API_SECRET" : undefined, "WHMCS_API_SECRET"]) || "";

    return {
      baseUrl,
      identifier,
      secret,
      timeout: this.getNumberConfig("WHMCS_API_TIMEOUT", 30000),
      retryAttempts: this.getNumberConfig("WHMCS_API_RETRY_ATTEMPTS", 3),
      retryDelay: this.getNumberConfig("WHMCS_API_RETRY_DELAY", 1000),
    };
  }

  /**
   * Helper: read the first defined value across a list of keys
   */
  private getFirst(keys: Array<string | undefined>): string | undefined {
    for (const key of keys) {
      if (!key) continue;
      const v = this.configService.get<string | undefined>(key);
      if (v && `${v}`.length > 0) return v;
      const raw = process.env[key];
      if (raw && `${raw}`.length > 0) return raw;
    }
    return undefined;
  }

  /**
   * Get numeric configuration value with fallback
   */
  private getNumberConfig(key: string, defaultValue: number): number {
    const value = this.configService.get<string>(key);
    if (!value) return defaultValue;

    const parsed = parseInt(value, 10);
    return isNaN(parsed) ? defaultValue : parsed;
  }
}
