import { logger } from '../../utils/logger';
import { SemanticLogService } from '../telemetry/SemanticLogService';
import dotenv from 'dotenv';

/**
 * [BIZ_KER_124] 全局环境变量注入一致性检查 (EnvValidatorService)
 * @description 核心逻辑：在系统启动时，对 .env 环境变量进行全量一致性与有效性校验。
 * 针对核心 KEY（数据库、Redis、AI 密钥等）执行强制存在性校验。
 * 联动语义日志中心输出环境启动报告并预警缺失的 Key。
 */
export class EnvValidatorService {
  private static readonly REQUIRED_KEYS = [
    'DB_HOST', 'DB_PORT', 'DB_USER', 'DB_PASS', 'DB_NAME',
    'REDIS_HOST', 'REDIS_PORT',
    'AI_API_KEY', 'AI_API_URL', 'MASTER_ENCRYPTION_KEY'
  ];

  /**
   * 执行环境变量校验
   */
  static async validate() {
    dotenv.config(); // 重新加载以确保同步

    const missingKeys: string[] = [];
    const configSnapshot: Record<string, string> = {};

    for (const key of this.REQUIRED_KEYS) {
      if (!process.env[key] || process.env[key] === 'sk-xxx') {
        missingKeys.push(key);
      } else {
        // 记录脱敏快照
        configSnapshot[key] = this.maskValue(process.env[key]!);
      }
    }

    const report = await this.generateReport(missingKeys, configSnapshot);
    await SemanticLogService.logSemantic(report, missingKeys.length > 0 ? 'ERROR' : 'INFO', 'ENV_AUDIT');

    if (missingKeys.length > 0) {
      logger.error(`[EnvValidator] FATAL: Missing mandatory environment keys: ${missingKeys.join(', ')}`);
      // 生产环境下建议抛出异常以阻止启动
      // throw new Error(`MISSING_ENV_KEYS: ${missingKeys.join(', ')}`);
    } else {
      logger.info(`[EnvValidator] All mandatory environment keys are present and valid.`);
    }
  }

  /**
   * 生成环境报告
   */
  private static async generateReport(missing: string[], snapshot: Record<string, string>): Promise<string> {
    let report = `### 🌍 Global Environment Consistency Audit (Env Check)\n\n`;
    report += `**System Startup Time:** ${new Date().toISOString()}\n\n`;

    if (missing.length > 0) {
      report += `**🚨 FATAL: Missing Mandatory Environment Keys:**\n`;
      missing.forEach(key => report += `- \`${key}\` (请立即在 .env 文件中补充)\n`);
    } else {
      report += `**✅ All mandatory environment keys are properly injected.**\n`;
    }

    report += `\n**Environment Snapshot (Masked):**\n`;
    for (const [key, val] of Object.entries(snapshot)) {
      report += `- \`${key}\`: \`${val}\`\n`;
    }

    return report;
  }

  /**
   * 对敏感环境变量值进行脱敏
   */
  private static maskValue(val: string): string {
    if (val.length <= 8) return '****';
    return val.substring(0, 4) + '****' + val.substring(val.length - 4);
  }
}
