import { logger } from '../../utils/logger';
import { FeatureGovernanceService } from '../governance/FeatureGovernanceService';
import db from '../../config/database';
import RedisService from '../../services/RedisService';

export interface QuotaStatus {
  tenantId: string;
  resourceType: string; // API_CALLS, STORAGE_BYTES, COMPUTE_UNITS
  limit: number;
  currentUsage: number;
  isBreakerOpen: boolean;
  lastTripTime?: Date;
}

/**
 * [BIZ_GOV_07] 租户配额超支自动限流与熔断策略 (Quota Circuit Breaker)
 * @description 核心逻辑：实现多维度的租户配额动态管控与熔断保护。
 * 系统实时监控租户对核心资源（如 AGI 推理额度、存储空间、并发请求数）的消耗，
 * 当消耗接近临界值 (Threshold) 或出现爆发式异常增长时，自动开启熔断器 (Circuit Breaker)，
 * 保护全局基础设施不受单点故障或租户恶意刷量影响。
 */
export class QuotaCircuitBreakerService {
  private static readonly QUOTA_TABLE = 'cf_tenant_quotas';
  private static readonly BREAKER_THRESHOLD = 0.95; // 95% 开启熔断

  /**
   * 初始化表结构
   */
  static async initTable() {
    const hasTable = await db.schema.hasTable(this.QUOTA_TABLE);
    if (!hasTable) {
      console.log(`📦 Creating ${this.QUOTA_TABLE} table...`);
      await db.schema.createTable(this.QUOTA_TABLE, (table) => {
        table.increments('id').primary();
        table.string('tenant_id', 64).notNullable();
        table.string('resource_type', 32).notNullable();
        table.decimal('quota_limit', 15, 4).notNullable(); // 改为 decimal 支持金额
        table.decimal('current_usage', 15, 4).defaultTo(0);
        table.boolean('is_breaker_open').defaultTo(false);
        table.timestamp('last_trip_time');
        table.timestamps(true, true);
        table.unique(['tenant_id', 'resource_type']);
      });
      console.log(`✅ Table ${this.QUOTA_TABLE} created`);
    }
  }

  /**
   * 检查并扣减配额 (带熔断逻辑)
   */
  static async checkAndConsume(tenantId: string, resourceType: string, amount: number = 1): Promise<boolean> {
    const quota = await db(this.QUOTA_TABLE).where({ tenant_id: tenantId, resource_type: resourceType }).first();
    
    // 如果没有配额记录，尝试初始化一个默认值 (例如 $10 AGI 预算)
    if (!quota) {
      await db(this.QUOTA_TABLE).insert({
        tenant_id: tenantId,
        resource_type: resourceType,
        quota_limit: resourceType === 'AGI_COST_USD' ? 10.0 : 1000,
        current_usage: 0
      });
      return true;
    }

    if (quota.is_breaker_open) {
      // 检查是否可以自动恢复 (例如熔断 1 小时后进入 Half-Open)
      const oneHourAgo = new Date(Date.now() - 3600000);
      if (quota.last_trip_time && quota.last_trip_time < oneHourAgo) {
        logger.info(`[QuotaBreaker] Attempting auto-recovery for Tenant ${tenantId} on ${resourceType}`);
        await db(this.QUOTA_TABLE).where({ id: quota.id }).update({ is_breaker_open: false });
      } else {
        logger.warn(`[QuotaBreaker] Rejected request for Tenant ${tenantId} on ${resourceType}: Breaker is OPEN`);
        return false;
      }
    }

    const usageRatio = (Number(quota.current_usage) + amount) / Number(quota.quota_limit);

    if (usageRatio >= 1.0) {
      // 彻底耗尽，开启熔断
      await this.tripBreaker(tenantId, resourceType, 'QUOTA_EXHAUSTED');
      return false;
    }

    if (usageRatio >= this.BREAKER_THRESHOLD) {
      logger.warn(`[QuotaBreaker] Warning: Tenant ${tenantId} reached ${Math.round(usageRatio * 100)}% of ${resourceType} quota`);
    }

    // 更新使用量
    await db(this.QUOTA_TABLE)
      .where({ tenant_id: tenantId, resource_type: resourceType })
      .increment('current_usage', amount);

    return true;
  }

  /**
   * 触发熔断
   */
  private static async tripBreaker(tenantId: string, resourceType: string, reason: string) {
    logger.error(`[QuotaBreaker] TRIPPING BREAKER for Tenant ${tenantId} on ${resourceType}. Reason: ${reason}`);
    
    await db(this.QUOTA_TABLE)
      .where({ tenant_id: tenantId, resource_type: resourceType })
      .update({
        is_breaker_open: true,
        last_trip_time: new Date()
      });
    
    // 逻辑：发送警报通知
  }

  /**
   * 重置配额 (定时任务调用)
   */
  static async resetQuotas(resourceType: string) {
    await db(this.QUOTA_TABLE)
      .where({ resource_type: resourceType })
      .update({
        current_usage: 0,
        is_breaker_open: false,
        last_trip_time: null
      });
    
    logger.info(`[QuotaBreaker] All quotas for ${resourceType} have been reset`);
  }
}
