import db from '../../config/database';
import { v4 as uuidv4 } from 'uuid';
import { logger } from '../../utils/logger';
import { AuditService } from '../core/AuditService';
import {
  AdPlan,
  AdCampaign,
  CreateAdPlanParams,
  ExecuteCampaignOptions,
  CampaignResult,
  DateRange,
  ROIData,
  AdPerformanceMetrics,
  AdPlanStatus,
  CampaignStatus,
} from '../../models/AdPlan';

const BUDGET_THRESHOLD_FOR_REVIEW = 10000;

export interface Ad {
  id: string;
  tenantId: string;
  shopId: string;
  platform: string;
  adId: string;
  name: string;
  type: string;
  status: string;
  budget: number;
  spent: number;
  clicks: number;
  impressions: number;
  conversions: number;
  createdAt: Date;
  updatedAt: Date;
}

export interface AdCreative {
  id: string;
  tenantId: string;
  shopId: string;
  name: string;
  type: string;
  content: string;
  status: string;
  createdAt: Date;
  updatedAt: Date;
}

export interface AdPrediction {
  id: string;
  tenantId: string;
  shopId: string;
  adId: string;
  predictedClicks: number;
  predictedConversions: number;
  predictedROI: number;
  confidence: number;
  createdAt: Date;
}

export class AdService {
  private static readonly TABLE_AD = 'cf_ads';
  private static readonly TABLE_AD_PLAN = 'cf_ad_plan';
  private static readonly TABLE_AD_CAMPAIGN = 'cf_ad_campaign';
  private static readonly TABLE_AD_CREATIVE = 'cf_ad_creatives';
  private static readonly TABLE_AD_PREDICTION = 'cf_ad_predictions';

  // ==================== 基础广告管理 ====================

  static async createAd(adData: Partial<Ad>): Promise<Ad> {
    const id = uuidv4();
    await db(this.TABLE_AD).insert({
      id,
      ...adData,
      created_at: new Date(),
      updated_at: new Date()
    });
    return (await this.getAdById(id))!;
  }

  static async getAdById(id: string): Promise<Ad | null> {
    return await db(this.TABLE_AD).where({ id }).first();
  }

  static async updateAd(id: string, adData: Partial<Ad>): Promise<Ad | null> {
    await db(this.TABLE_AD).where({ id }).update({
      ...adData,
      updated_at: new Date()
    });
    return await this.getAdById(id);
  }

  static async deleteAd(id: string): Promise<boolean> {
    const result = await db(this.TABLE_AD).where({ id }).delete();
    return result > 0;
  }

  static async listAds(tenantId: string, shopId: string, filters?: any): Promise<Ad[]> {
    let query = db(this.TABLE_AD).where({ tenantId, shopId });
    
    if (filters) {
      if (filters.platform) query = query.where({ platform: filters.platform });
      if (filters.status) query = query.where({ status: filters.status });
      if (filters.startDate) query = query.where('created_at', '>=', filters.startDate);
      if (filters.endDate) query = query.where('created_at', '<=', filters.endDate);
    }
    
    return await query.orderBy('created_at', 'desc');
  }

  // ==================== 广告计划管理 ====================

  static async createAdPlan(params: CreateAdPlanParams): Promise<AdPlan> {
    const {
      tenantId,
      shopId,
      name,
      platform,
      budget,
      dailyBudget,
      startDate,
      endDate,
      targetAudience,
      keywords,
      taskId,
      traceId,
      businessType,
    } = params;

    logger.info('[AdService] Creating ad plan', {
      tenantId,
      shopId,
      name,
      platform,
      budget,
      traceId,
      businessType,
    });

    try {
      const id = uuidv4();
      const status = budget > BUDGET_THRESHOLD_FOR_REVIEW ? 'PENDING_REVIEW' : 'APPROVED';

      await db(this.TABLE_AD_PLAN).insert({
        id,
        tenant_id: tenantId,
        shop_id: shopId,
        name,
        platform,
        budget,
        daily_budget: dailyBudget,
        start_date: startDate,
        end_date: endDate,
        target_audience: JSON.stringify(targetAudience),
        keywords: JSON.stringify(keywords),
        status,
        created_at: new Date(),
        updated_at: new Date(),
      });

      // 记录审计日志
      await AuditService.log({
        tenantId,
        shopId,
        traceId,
        userId: 'system',
        module: 'MARKETING',
        action: 'CREATE_AD_PLAN',
        resourceType: 'AD_PLAN',
        resourceId: id,
        afterSnapshot: {
          name,
          platform,
          budget,
          status,
        },
        result: 'success',
        source: 'node',
        businessType,
        taskId
      });

      return (await this.getAdPlanById(id))!;
    } catch (error) {
      logger.error('[AdService] Error creating ad plan', { error, traceId });
      throw error;
    }
  }

  static async getAdPlanById(id: string): Promise<AdPlan | null> {
    const plan = await db(this.TABLE_AD_PLAN).where({ id }).first();
    if (!plan) return null;

    return {
      id: plan.id,
      tenant_id: plan.tenant_id,
      shop_id: plan.shop_id,
      name: plan.name,
      platform: plan.platform,
      budget: plan.budget,
      daily_budget: plan.daily_budget,
      start_date: plan.start_date,
      end_date: plan.end_date,
      target_audience: plan.target_audience,
      keywords: JSON.parse(plan.keywords),
      status: plan.status,
      created_at: plan.created_at,
      updated_at: plan.updated_at,
    };
  }

  static async updateAdPlanStatus(id: string, status: AdPlanStatus): Promise<AdPlan | null> {
    await db(this.TABLE_AD_PLAN).where({ id }).update({
      status,
      updated_at: new Date(),
    });
    return await this.getAdPlanById(id);
  }

  // ==================== 广告创意管理 ====================

  static async createAdCreative(creativeData: Partial<AdCreative>): Promise<AdCreative> {
    const id = uuidv4();
    await db(this.TABLE_AD_CREATIVE).insert({
      id,
      ...creativeData,
      created_at: new Date(),
      updated_at: new Date()
    });
    return (await this.getAdCreativeById(id))!;
  }

  static async getAdCreativeById(id: string): Promise<AdCreative | null> {
    return await db(this.TABLE_AD_CREATIVE).where({ id }).first();
  }

  static async listAdCreatives(tenantId: string, shopId: string): Promise<AdCreative[]> {
    return await db(this.TABLE_AD_CREATIVE)
      .where({ tenantId, shopId })
      .orderBy('created_at', 'desc');
  }

  // ==================== 广告效果预测 ====================

  static async createAdPrediction(predictionData: Partial<AdPrediction>): Promise<AdPrediction> {
    const id = uuidv4();
    await db(this.TABLE_AD_PREDICTION).insert({
      id,
      ...predictionData,
      created_at: new Date()
    });
    return (await this.getAdPredictionById(id))!;
  }

  static async getAdPredictionById(id: string): Promise<AdPrediction | null> {
    return await db(this.TABLE_AD_PREDICTION).where({ id }).first();
  }

  static async getAdPredictionByAdId(adId: string): Promise<AdPrediction | null> {
    return await db(this.TABLE_AD_PREDICTION)
      .where({ adId })
      .orderBy('created_at', 'desc')
      .first();
  }

  // ==================== 广告优化 ====================

  static async optimizeAd(adId: string): Promise<Ad | null> {
    const ad = await this.getAdById(adId);
    if (!ad) return null;

    // 简单的优化逻辑：根据点击率和转化率调整预算
    const ctr = ad.clicks / ad.impressions || 0;
    const cvr = ad.conversions / ad.clicks || 0;

    let newBudget = ad.budget;
    if (ctr > 0.05 && cvr > 0.1) {
      // 表现好，增加预算
      newBudget = ad.budget * 1.2;
    } else if (ctr < 0.01 || cvr < 0.01) {
      // 表现差，减少预算
      newBudget = ad.budget * 0.8;
    }

    return await this.updateAd(adId, { budget: newBudget });
  }

  static async optimizeAdPlan(planId: string): Promise<AdPlan | null> {
    const plan = await this.getAdPlanById(planId);
    if (!plan) return null;

    // 这里可以实现更复杂的计划优化逻辑
    // 例如：根据历史数据调整目标受众、关键词等

    return plan;
  }

  // ==================== 广告自动化 ====================

  static async autoCreateAds(tenantId: string, shopId: string, productIds: string[]): Promise<Ad[]> {
    const createdAds: Ad[] = [];

    for (const productId of productIds) {
      // 这里可以实现自动创建广告的逻辑
      // 例如：根据产品信息生成广告内容
      const ad = await this.createAd({
        tenantId,
        shopId,
        platform: 'Amazon',
        adId: `auto_${uuidv4()}`,
        name: `Auto Ad for Product ${productId}`,
        type: 'SPONSORED_PRODUCT',
        status: 'ACTIVE',
        budget: 100,
        spent: 0,
        clicks: 0,
        impressions: 0,
        conversions: 0,
      });
      createdAds.push(ad);
    }

    return createdAds;
  }

  static async autoOptimizeAds(tenantId: string, shopId: string): Promise<Ad[]> {
    const ads = await this.listAds(tenantId, shopId, { status: 'ACTIVE' });
    const optimizedAds: Ad[] = [];

    for (const ad of ads) {
      const optimizedAd = await this.optimizeAd(ad.id);
      if (optimizedAd) {
        optimizedAds.push(optimizedAd);
      }
    }

    return optimizedAds;
  }

  // ==================== 性能分析 ====================

  static async getAdPerformance(adId: string, dateRange: DateRange): Promise<AdPerformanceMetrics> {
    // 这里可以实现广告性能分析逻辑
    // 例如：获取指定时间范围内的广告数据
    const ad = await this.getAdById(adId);
    if (!ad) {
      throw new Error('Ad not found');
    }

    return {
      impressions: ad.impressions || 0,
      clicks: ad.clicks || 0,
      spend: ad.spent || 0,
      sales: (ad.conversions || 0) * 50, // 假设平均订单价值为50
      conversions: ad.conversions || 0,
    };
  }

  static async getCampaignPerformance(campaignId: string, dateRange: DateRange): Promise<CampaignResult> {
    // 这里可以实现 campaign 性能分析逻辑
    return {
      campaignId,
      status: 'RUNNING',
      message: 'Campaign performance retrieved successfully',
    };
  }
}
