import { v4 as uuid } from 'uuid';
import db from '../core/database';
import { eventBus, emitEvent } from '../runtime/eventBus';
import { addJob } from '../runtime/queue-core';

interface ProductMetrics {
  id: string;
  productId: string;
  clicks: number;
  orders: number;
  cost: number;
  revenue: number;
  roi: number;
  updatedAt: Date;
}

interface AdCampaign {
  id: string;
  merchantId: string;
  productId: string;
  name: string;
  budget: number;
  status: string;
  startDate: Date;
  endDate: Date;
  createdAt: Date;
  updatedAt: Date;
}

interface AdPerformance {
  campaignId: string;
  date: Date;
  impressions: number;
  clicks: number;
  cost: number;
  conversions: number;
  revenue: number;
  roi: number;
}

export class AdAutoService {
  /**
   * 自动创建广告活动
   */
  async createAutoCampaign(merchantId: string, productId: string, budget: number): Promise<AdCampaign | null> {
    try {
      // 分析产品数据
      const productMetrics = await this.getProductMetrics(productId);
      
      // 计算ROI预测
      const predictedROI = this.predictROI(productMetrics);
      
      // 只有ROI大于0.5的产品才创建广告活动
      if (predictedROI < 0.5) {
        console.log(`[AdAutoService] Skipping campaign creation for product ${productId} - predicted ROI too low: ${predictedROI}`);
        return null;
      }
      
      // 创建广告活动
      const campaign: AdCampaign = {
        id: uuid(),
        merchantId,
        productId,
        name: `Auto Campaign for ${productId}`,
        budget,
        status: 'active',
        startDate: new Date(),
        endDate: new Date(Date.now() + 30 * 24 * 60 * 60 * 1000), // 30天后结束
        createdAt: new Date(),
        updatedAt: new Date()
      };
      
      await db('ad_campaigns').insert({
        id: campaign.id,
        merchant_id: campaign.merchantId,
        product_id: campaign.productId,
        name: campaign.name,
        budget: campaign.budget,
        status: campaign.status,
        start_date: campaign.startDate,
        end_date: campaign.endDate,
        created_at: campaign.createdAt,
        updated_at: campaign.updatedAt
      });
      
      // 发送事件
      emitEvent('AD_CAMPAIGN_CREATED', {
        campaign,
        predictedROI
      }, 'AdAutoService', merchantId);
      
      // 添加任务到队列
      await addJob('RUN_ADS', {
        campaignId: campaign.id,
        merchantId,
        productId,
        budget,
        roi: predictedROI
      });
      
      console.log(`[AdAutoService] Created auto campaign ${campaign.id} for product ${productId} with predicted ROI: ${predictedROI}`);
      return campaign;
    } catch (error) {
      console.error('[AdAutoService] Error creating auto campaign:', error);
      throw error;
    }
  }
  
  /**
   * 获取产品指标
   */
  async getProductMetrics(productId: string): Promise<ProductMetrics> {
    try {
      const metrics = await db('product_metrics').where({ product_id: productId }).first();
      
      if (metrics) {
        return {
          id: metrics.id,
          productId: metrics.product_id,
          clicks: metrics.clicks,
          orders: metrics.orders,
          cost: metrics.cost,
          revenue: metrics.revenue,
          roi: metrics.roi,
          updatedAt: metrics.updated_at
        };
      }
      
      // 如果没有指标记录，创建一个新的
      const newMetrics: ProductMetrics = {
        id: uuid(),
        productId,
        clicks: 0,
        orders: 0,
        cost: 0,
        revenue: 0,
        roi: 0,
        updatedAt: new Date()
      };
      
      await db('product_metrics').insert({
        id: newMetrics.id,
        product_id: newMetrics.productId,
        clicks: newMetrics.clicks,
        orders: newMetrics.orders,
        cost: newMetrics.cost,
        revenue: newMetrics.revenue,
        roi: newMetrics.roi,
        updated_at: newMetrics.updatedAt
      });
      
      return newMetrics;
    } catch (error) {
      console.error('[AdAutoService] Error getting product metrics:', error);
      throw error;
    }
  }
  
  /**
   * 更新产品指标
   */
  async updateProductMetrics(productId: string, metrics: Partial<ProductMetrics>): Promise<ProductMetrics> {
    try {
      const updatedMetrics = {
        ...metrics,
        updatedAt: new Date()
      };
      
      // 计算ROI
      if (updatedMetrics.cost > 0) {
        updatedMetrics.roi = (updatedMetrics.revenue - updatedMetrics.cost) / updatedMetrics.cost;
      }
      
      await db('product_metrics')
        .where({ product_id: productId })
        .update({
          clicks: updatedMetrics.clicks,
          orders: updatedMetrics.orders,
          cost: updatedMetrics.cost,
          revenue: updatedMetrics.revenue,
          roi: updatedMetrics.roi,
          updated_at: updatedMetrics.updatedAt
        });
      
      return {
        id: '', // 实际应该从数据库获取
        productId,
        clicks: updatedMetrics.clicks || 0,
        orders: updatedMetrics.orders || 0,
        cost: updatedMetrics.cost || 0,
        revenue: updatedMetrics.revenue || 0,
        roi: updatedMetrics.roi || 0,
        updatedAt: updatedMetrics.updatedAt
      };
    } catch (error) {
      console.error('[AdAutoService] Error updating product metrics:', error);
      throw error;
    }
  }
  
  /**
   * 预测ROI
   */
  predictROI(metrics: ProductMetrics): number {
    // 简单的ROI预测模型
    // 基于历史ROI和趋势
    if (metrics.cost === 0) {
      return 0.5; // 默认值
    }
    
    // 基础ROI
    const baseROI = metrics.roi;
    
    // 考虑点击率和转化率
    const clickRate = metrics.clicks > 0 ? metrics.orders / metrics.clicks : 0;
    const conversionFactor = clickRate > 0.01 ? 1.2 : 0.8;
    
    // 考虑趋势（这里简化处理，实际应该使用时间序列分析）
    const trendFactor = baseROI > 0.5 ? 1.1 : 0.9;
    
    // 计算预测ROI
    const predictedROI = baseROI * conversionFactor * trendFactor;
    
    return Math.max(0, predictedROI);
  }
  
  /**
   * 优化广告预算
   */
  async optimizeAdBudget(campaignId: string): Promise<number> {
    try {
      // 获取广告活动信息
      const campaign = await db('ad_campaigns').where({ id: campaignId }).first();
      if (!campaign) {
        throw new Error(`Campaign ${campaignId} not found`);
      }
      
      // 获取产品指标
      const metrics = await this.getProductMetrics(campaign.product_id);
      
      // 计算最优预算
      // 基于ROI和历史数据
      const optimalBudget = this.calculateOptimalBudget(metrics, campaign.budget);
      
      // 更新广告活动预算
      await db('ad_campaigns')
        .where({ id: campaignId })
        .update({
          budget: optimalBudget,
          updated_at: new Date()
        });
      
      // 发送事件
      emitEvent('AD_BUDGET_UPDATED', {
        campaignId,
        oldBudget: campaign.budget,
        newBudget: optimalBudget,
        roi: metrics.roi
      }, 'AdAutoService', campaign.merchant_id);
      
      console.log(`[AdAutoService] Optimized budget for campaign ${campaignId}: ${optimalBudget}`);
      return optimalBudget;
    } catch (error) {
      console.error('[AdAutoService] Error optimizing ad budget:', error);
      throw error;
    }
  }
  
  /**
   * 计算最优预算
   */
  calculateOptimalBudget(metrics: ProductMetrics, currentBudget: number): number {
    // 简单的预算优化模型
    // 基于ROI和历史花费
    if (metrics.roi > 1.0) {
      // ROI大于1，增加预算
      return currentBudget * 1.2;
    } else if (metrics.roi > 0.5) {
      // ROI大于0.5，保持预算
      return currentBudget;
    } else {
      // ROI小于0.5，减少预算
      return currentBudget * 0.8;
    }
  }
  
  /**
   * 停止表现不佳的广告活动
   */
  async stopUnderperformingCampaigns(merchantId: string): Promise<number> {
    try {
      // 获取商户的所有广告活动
      const campaigns = await db('ad_campaigns').where({ merchant_id: merchantId, status: 'active' });
      
      let stoppedCount = 0;
      
      for (const campaign of campaigns) {
        // 获取产品指标
        const metrics = await this.getProductMetrics(campaign.product_id);
        
        // 如果ROI小于0.3，停止广告活动
        if (metrics.roi < 0.3) {
          await db('ad_campaigns')
            .where({ id: campaign.id })
            .update({
              status: 'stopped',
              updated_at: new Date()
            });
          
          // 发送事件
          emitEvent('AD_CAMPAIGN_STOPPED', {
            campaignId: campaign.id,
            reason: 'Low ROI',
            roi: metrics.roi
          }, 'AdAutoService', merchantId);
          
          // 添加任务到队列
          await addJob('STOP_AD', {
            campaignId: campaign.id,
            merchantId
          });
          
          stoppedCount++;
        }
      }
      
      console.log(`[AdAutoService] Stopped ${stoppedCount} underperforming campaigns for merchant ${merchantId}`);
      return stoppedCount;
    } catch (error) {
      console.error('[AdAutoService] Error stopping underperforming campaigns:', error);
      throw error;
    }
  }
  
  /**
   * 获取广告活动列表
   */
  async getCampaignsByMerchant(merchantId: string): Promise<AdCampaign[]> {
    try {
      const campaigns = await db('ad_campaigns').where({ merchant_id: merchantId });
      
      return campaigns.map(campaign => ({
        id: campaign.id,
        merchantId: campaign.merchant_id,
        productId: campaign.product_id,
        name: campaign.name,
        budget: campaign.budget,
        status: campaign.status,
        startDate: campaign.start_date,
        endDate: campaign.end_date,
        createdAt: campaign.created_at,
        updatedAt: campaign.updated_at
      }));
    } catch (error) {
      console.error('[AdAutoService] Error getting campaigns:', error);
      throw error;
    }
  }
}

export default new AdAutoService();
