import { Injectable, Logger } from '@nestjs/common';
import { db } from '../../config/database';

interface SettlementData {
  id: string;
  merchantId: string;
  periodStart: Date;
  periodEnd: Date;
  totalAmount: number;
  status: string;
  settlementDate: Date;
  createdAt: Date;
  updatedAt: Date;
}

interface OptimizationResult {
  settlementId: string;
  merchantId: string;
  currentAmount: number;
  optimizedAmount: number;
  improvement: number;
  recommendations: string[];
}

interface SettlementMetrics {
  totalSettlements: number;
  totalAmount: number;
  averageAmount: number;
  pendingSettlements: number;
  pendingAmount: number;
  averageProcessingTime: number;
}

/**
 * [BE-SET-001] 结算优化服务
 * 负责结算周期优化、金额计算、流程自动化
 * AI注意: 所有结算优化操作必须通过此服务进行
 */
@Injectable()
export class SettlementOptimizationService {
  private readonly logger = new Logger(SettlementOptimizationService.name);

  constructor() {}

  /**
   * 优化结算
   * @param settlementId 结算ID
   * @param traceId 链路追踪ID
   * @returns 优化结果
   */
  async optimizeSettlement(settlementId: string, traceId: string): Promise<OptimizationResult> {
    this.logger.log(`开始优化结算: ${settlementId}`, { traceId, settlementId });

    try {
      const settlement = await db('cf_settlement')
        .where('id', settlementId)
        .first();

      if (!settlement) {
        throw new Error(`结算不存在: ${settlementId}`);
      }

      const currentAmount = settlement.amount;
      const optimizedAmount = await this.calculateOptimizedAmount(settlement);
      const improvement = currentAmount - optimizedAmount;
      const recommendations = this.generateRecommendations(settlement, optimizedAmount);

      const result: OptimizationResult = {
        settlementId,
        merchantId: settlement.merchant_id,
        currentAmount,
        optimizedAmount,
        improvement,
        recommendations,
      };

      this.logger.log(`结算优化完成: ${settlementId}`, { traceId, result });

      return result;
    } catch (error: unknown) {
      const errorMessage = error instanceof Error ? error.message : String(error);
      this.logger.error(`结算优化失败: ${errorMessage}`, { traceId, settlementId, error });
      throw error;
    }
  }

  /**
   * 批量优化结算
   * @param settlementIds 结算ID列表
   * @param traceId 链路追踪ID
   * @returns 优化结果列表
   */
  async batchOptimizeSettlements(
    settlementIds: string[],
    traceId: string
  ): Promise<OptimizationResult[]> {
    this.logger.log(`开始批量优化结算, 数量: ${settlementIds.length}`, { traceId });

    const results: OptimizationResult[] = [];

    for (const settlementId of settlementIds) {
      try {
        const result = await this.optimizeSettlement(settlementId, traceId);
        results.push(result);
      } catch (error) {
        this.logger.error(`批量优化结算失败: ${settlementId}`, { traceId, settlementId });
      }
    }

    this.logger.log(`批量优化结算完成, 成功: ${results.length}/${settlementIds.length}`, { traceId });

    return results;
  }

  /**
   * 获取结算指标
   * @param tenantId 租户ID
   * @param traceId 链路追踪ID
   * @returns 结算指标
   */
  async getSettlementMetrics(tenantId: string, traceId: string): Promise<SettlementMetrics> {
    this.logger.log(`获取结算指标: ${tenantId}`, { traceId, tenantId });

    try {
      const settlements = await db('cf_settlement')
        .where('tenant_id', tenantId)
        .select('*');

      const totalSettlements = settlements.length;
      const totalAmount = settlements.reduce((sum, s) => sum + (s.amount || 0), 0);
      const averageAmount = totalSettlements > 0 ? totalAmount / totalSettlements : 0;
      const pendingSettlements = settlements.filter(s => s.status === 'pending').length;
      const pendingAmount = settlements
        .filter(s => s.status === 'pending')
        .reduce((sum, s) => sum + (s.amount || 0), 0);

      const processingTimes = settlements
        .filter(s => s.settlement_date && s.created_at)
        .map(s => new Date(s.settlement_date).getTime() - new Date(s.created_at).getTime());

      const averageProcessingTime = processingTimes.length > 0
        ? processingTimes.reduce((sum, t) => sum + t, 0) / processingTimes.length
        : 0;

      const metrics: SettlementMetrics = {
        totalSettlements,
        totalAmount,
        averageAmount,
        pendingSettlements,
        pendingAmount,
        averageProcessingTime,
      };

      this.logger.log(`获取结算指标完成: ${tenantId}`, { traceId, metrics });

      return metrics;
    } catch (error: unknown) {
      const errorMessage = error instanceof Error ? error.message : String(error);
      this.logger.error(`获取结算指标失败: ${errorMessage}`, { traceId, tenantId, error });
      throw error;
    }
  }

  /**
   * 计算优化后的金额
   */
  private async calculateOptimizedAmount(settlement: any): Promise<number> {
    const orders = await db('cf_order')
      .where('merchant_id', settlement.merchant_id)
      .whereBetween('created_at', [settlement.period_start, settlement.period_end])
      .select('*');

    const totalOrderAmount = orders.reduce((sum, o) => sum + (o.total_amount || 0), 0);
    const platformFee = totalOrderAmount * 0.03;
    const optimizedAmount = totalOrderAmount - platformFee;

    return Math.round(optimizedAmount * 100) / 100;
  }

  /**
   * 生成建议
   */
  private generateRecommendations(settlement: any, optimizedAmount: number): string[] {
    const recommendations: string[] = [];

    const improvement = settlement.amount - optimizedAmount;

    if (improvement > 0) {
      recommendations.push(`建议优化结算金额，可节省 ${improvement.toFixed(2)} 元`);
    }

    if (settlement.status === 'pending') {
      recommendations.push('建议加快结算处理速度');
    }

    return recommendations;
  }
}
