import path from 'path';
import { fileURLToPath } from 'url';
import dotenv from 'dotenv';
import { EnvConfig } from '../types.js';

export class BotConfigService {
  private readonly config: EnvConfig;

  constructor(private readonly env: NodeJS.ProcessEnv = process.env) {
    this.loadEnvFile();
    this.config = this.resolveConfig();
  }

  getConfig(): EnvConfig {
    return { ...this.config };
  }

  getPort(): string {
    return this.config.PORT;
  }

  getEnvironment(): string {
    return this.config.ENVIRONMENT;
  }

  getGraphQLEndpoint(): string {
    return this.config.GRAPHQL_ENDPOINT;
  }

  getProviderUrl(): string {
    return this.config.PROVIDER_URL;
  }

  getPrivateKey(): string {
    return this.config.PRIVATE_KEY;
  }

  getLiquidityManagerAddress(): string {
    return this.config.LM_CONTRACT_ADDRESS;
  }

  getStakeContractAddress(): string {
    return this.config.STAKE_CONTRACT_ADDRESS;
  }

  private loadEnvFile(): void {
    const envFile = this.env.TXN_BOT_ENV_FILE;
    const __filename = fileURLToPath(import.meta.url);
    const __dirname = path.dirname(__filename);
    const defaultEnvPath = path.resolve(__dirname, '../..', '.env');
    const dotenvPath = envFile ? path.resolve(envFile) : defaultEnvPath;

    dotenv.config({ path: dotenvPath });
  }

  private resolveConfig(): EnvConfig {
    const requiredKeys: Array<keyof EnvConfig> = [
      'PROVIDER_URL',
      'PRIVATE_KEY',
      'LM_CONTRACT_ADDRESS',
      'STAKE_CONTRACT_ADDRESS',
      'GRAPHQL_ENDPOINT',
    ];

    for (const key of requiredKeys) {
      const value = this.env[key];
      if (!value) {
        throw new Error(`Missing required environment variable: ${key}`);
      }
    }

    return {
      PROVIDER_URL: this.env.PROVIDER_URL as string,
      PRIVATE_KEY: this.env.PRIVATE_KEY as string,
      LM_CONTRACT_ADDRESS: this.env.LM_CONTRACT_ADDRESS as string,
      STAKE_CONTRACT_ADDRESS: this.env.STAKE_CONTRACT_ADDRESS as string,
      GRAPHQL_ENDPOINT: this.env.GRAPHQL_ENDPOINT as string,
      ENVIRONMENT: this.env.ENVIRONMENT ?? 'UNSPECIFIED',
      PORT: this.env.PORT ?? '3000',
    };
  }
}
