import db from '../../config/database';
import { DisputeResolverService } from '../../services/DisputeResolverService';
import { DynamicPricingService } from '../../services/DynamicPricingService';
import { logger } from '../../utils/logger';
import { SupplierService } from '../../services/SupplierService';
import { TradeService } from '../Trade/TradeService';

export interface ActionableInsight {
  id?: number;
  type: 'PRICING' | 'INVENTORY' | 'MARKETING' | 'ARBITRAGE' | 'LOGISTICS' | 'SUPPLIER';
  title: string;
  description: string;
  impact: 'high' | 'medium' | 'low';
  confidence: number;
  suggestedAction: string;
  metadata?: any;
  status?: 'PENDING' | 'APPROVED' | 'EXECUTED' | 'IGNORED';
}

export interface StrategicAdvicePackage {
  tenantId: string;
  shopId: string;
  insights: ActionableInsight[];
  summary: string;
  timestamp: number;
}

/**
 * [BIZ_AI_16] 交互式策略包生成 (Actionable Insights)
 * @description 整合多维数据，生成半 AI 决策建议包，并支持持久化与自动化执行
 */
export class AdviceService {
  private static readonly TABLE_NAME = 'cf_strategic_advice';

  /**
   * 记录新的策略建议 (持久化)
   */
  static async recordAdvice(params: {
    tenantId: string;
    shopId: string;
    insight: ActionableInsight;
    traceId: string;
  }): Promise<number> {
    logger.info(`[Advice] Recording new ${params.insight.type} advice for Tenant: ${params.tenantId}`);

    const [id] = await db(this.TABLE_NAME).insert({
      tenant_id: params.tenantId,
      shop_id: params.shopId,
      type: params.insight.type,
      title: params.insight.title,
      description: params.insight.description,
      impact: params.insight.impact,
      confidence: params.insight.confidence,
      suggested_action: params.insight.suggestedAction,
      metadata: JSON.stringify(params.insight.metadata || {}),
      status: 'PENDING',
      trace_id: params.traceId,
      created_at: new Date(),
      updated_at: new Date()
    });

    return id;
  }

  /**
   * 获取店铺或特定商品的待处理建议
   */
  static async getPendingAdvice(tenantId: string, shopId?: string, productId?: string): Promise<ActionableInsight[]> {
    let query = db(this.TABLE_NAME)
      .where({ tenant_id: tenantId, status: 'PENDING' });

    if (shopId) {
      query = query.andWhere({ shop_id: shopId });
    }

    if (productId) {
      // 模糊匹配 metadata 中的 productId
      query = query.andWhereRaw('JSON_EXTRACT(metadata, "$.productId") = ?', [productId]);
    }

    const records = await query.orderBy('created_at', 'desc');

    return records.map(r => ({
      id: r.id,
      type: r.type,
      title: r.title,
      description: r.description,
      impact: r.impact,
      confidence: r.confidence,
      suggestedAction: r.suggested_action,
      metadata: typeof r.metadata === 'string' ? JSON.parse(r.metadata) : r.metadata,
      status: r.status
    }));
  }

  /**
   * [BIZ_AI_16] 用户审批并应用策略 (BIZ_AI_16-EXT)
   * @description 状态流转：PENDING -> APPROVED -> EXECUTING -> EXECUTED
   */
  static async approveAction(tenantId: string, shopId: string, insight: ActionableInsight): Promise<void> {
    if (!insight.id) throw new Error('Advice ID is required');
    
    // 逻辑：如果是从前端传来的完整对象，直接执行；如果只有 ID，从 DB 查
    await this.approveAndExecute(insight.id, {
      tenantId,
      shopId,
      userId: 'SYSTEM_AGENT', // 默认系统代理，实际应从上下文取
      traceId: `approve-${insight.type}-${Date.now()}`
    });
  }

  /**
   * [BIZ_AI_16] 生成交互式策略包建议
   * @description 触发全域 AGI 诊断并聚合结果
   */
  static async generateAdvice(tenantId: string, shopId: string): Promise<StrategicAdvicePackage> {
    logger.info(`[Advice] Generating strategic advice package for Tenant: ${tenantId}, Shop: ${shopId}`);

    // 1. 获取现有待处理建议
    const pending = await this.getPendingAdvice(tenantId, shopId);

    // 2. 模拟触发实时诊断 (实际应异步触发各 Domain Service)
    // 聚合各模块生成的建议包
    const insights: ActionableInsight[] = [...pending];

    return {
      tenantId,
      shopId,
      insights,
      summary: `Found ${insights.length} actionable insights for your store.`,
      timestamp: Date.now()
    };
  }

  /**
   * 用户审批并应用策略 (内部执行逻辑)
   */
  static async approveAndExecute(adviceId: number, context: {
    tenantId: string;
    shopId: string;
    userId: string;
    traceId: string;
  }): Promise<void> {
    const advice = await db(this.TABLE_NAME).where({ id: adviceId, tenant_id: context.tenantId }).first();
    if (!advice) throw new Error('Advice not found');

    logger.info(`[Advice] Executing approved action: ${advice.type} - ${advice.suggested_action}`);

    // 1. 更新状态为执行中
    await db(this.TABLE_NAME).where({ id: adviceId }).update({ 
      status: 'APPROVED',
      updated_at: new Date() 
    });

    try {
      const metadata = typeof advice.metadata === 'string' ? JSON.parse(advice.metadata) : advice.metadata;

      // 2. 根据类型分发执行逻辑
      switch (advice.type) {
        case 'PRICING':
          if (metadata.productId) {
            // 生成定价决策并执行
            const decision = await DynamicPricingService.generatePricingDecision(context.tenantId, context.shopId, metadata.productId);
            await DynamicPricingService.executePricingDecision(context.tenantId, decision.id);
          }
          break;
        
        case 'INVENTORY':
          if (metadata.productId && metadata.restockQuantity) {
            await TradeService.createPurchaseOrder({
              tenantId: context.tenantId,
              productId: metadata.productId,
              supplierId: metadata.supplierId || 'DEFAULT_SUPPLIER',
              quantity: metadata.restockQuantity,
              unitPrice: metadata.suggestedPrice || 0,
              totalAmount: (metadata.suggestedPrice || 0) * metadata.restockQuantity,
              traceId: context.traceId
            });
          }
          break;

        case 'LOGISTICS':
          if (metadata.orderId) {
            await DisputeResolverService.initiateDispute(
              context.tenantId,
              metadata.orderId,
              advice.description || 'Auto-initiated dispute via AGI advice'
            );
          }
          break;

        case 'SUPPLIER':
          if (metadata.supplierId) {
            await SupplierService.updateSupplierStatus(
              metadata.supplierId,
              advice.suggestedAction.includes('SWITCH') ? 'REVIEW' : 'BLOCK',
              advice.description
            );
          }
          break;

        case 'ARBITRAGE':
          // 处理套利策略调整
          break;
      }

      // 3. 标记为已完成
      await db(this.TABLE_NAME).where({ id: adviceId }).update({ 
        status: 'EXECUTED',
        updated_at: new Date() 
      });

    } catch (err: any) {
      logger.error(`[Advice] Execution failed for Advice ${adviceId}: ${err.message}`);
      await db(this.TABLE_NAME).where({ id: adviceId }).update({ 
        status: 'PENDING', 
        updated_at: new Date() 
      });
      throw err;
    }
  }
}
