/**
 * [MOCK] 动态定价数据源
 * AI注意: 这是Mock实现，不是真实业务逻辑
 * 仅在USE_MOCK=true时启用
 */

export type PricingStrategy = 'GAME_THEORY' | 'COMPETITION' | 'DEMAND_BASED' | 'COST_PLUS' | 'DYNAMIC';
export type PriceAdjustmentDirection = 'INCREASE' | 'DECREASE' | 'MAINTAIN';
export type PricingDecisionStatus = 'PENDING' | 'EXECUTED' | 'REJECTED' | 'EXPIRED';

export interface PricingConfig {
  id: string;
  tenant_id: string;
  shop_id: string;
  product_id: string;
  base_price: number;
  min_price: number;
  max_price: number;
  cost_price: number;
  strategy: PricingStrategy;
  strategy_params: {
    game_theory?: {
      competitor_weight: number;
      market_share_target: number;
      profit_priority: number;
    };
    competition?: {
      price_position: 'LOWEST' | 'BELOW_AVG' | 'AVG' | 'ABOVE_AVG' | 'HIGHEST';
      max_diff_percent: number;
      follow_leader: boolean;
    };
    demand_based?: {
      elasticity_threshold: number;
      demand_sensitivity: number;
      seasonal_factor: number;
    };
  };
  auto_adjust: boolean;
  adjust_frequency: 'HOURLY' | 'DAILY' | 'WEEKLY';
  max_adjust_percent: number;
  cooldown_hours: number;
  min_profit_margin: number;
  min_profit_amount: number;
  enabled: boolean;
  created_at: string;
  updated_at: string;
}

export interface PricingDecision {
  id: string;
  tenant_id: string;
  shop_id: string;
  product_id: string;
  product_name?: string;
  current_price: number;
  suggested_price: number;
  price_change: number;
  change_percent: number;
  adjustment_direction: PriceAdjustmentDirection;
  strategy_used: PricingStrategy;
  decision_factors: {
    competitor_prices: number[];
    market_avg_price: number;
    demand_level: 'LOW' | 'MEDIUM' | 'HIGH';
    inventory_level: number;
    sales_velocity: number;
    profit_margin: number;
  };
  predicted_impact: {
    revenue_change: number;
    profit_change: number;
    sales_change: number;
    confidence: number;
  };
  status: PricingDecisionStatus;
  reviewed_by?: string;
  reviewed_at?: string;
  review_notes?: string;
  executed_at?: string;
  execution_result?: {
    success: boolean;
    actual_price?: number;
    error?: string;
  };
  created_at: string;
  expires_at: string;
}

export interface CompetitorPriceRecord {
  id: string;
  product_id: string;
  competitor_shop_id: string;
  competitor_name: string;
  competitor_platform: string;
  price: number;
  shipping_cost: number;
  total_price: number;
  stock_status: 'IN_STOCK' | 'LOW_STOCK' | 'OUT_OF_STOCK';
  rating: number;
  review_count: number;
  collected_at: string;
}

export interface CompetitorAnalysis {
  product_id: string;
  analysis_date: string;
  price_stats: {
    min_price: number;
    max_price: number;
    avg_price: number;
    median_price: number;
    our_price: number;
    our_rank: number;
    total_competitors: number;
  };
  competitor_rankings: Array<{
    shop_id: string;
    shop_name: string;
    price: number;
    rank: number;
    price_diff: number;
    rating: number;
    review_count: number;
  }>;
  market_trend: {
    price_trend: 'RISING' | 'FALLING' | 'STABLE';
    competition_level: 'HIGH' | 'MEDIUM' | 'LOW';
    recommended_action: 'INCREASE' | 'DECREASE' | 'MAINTAIN';
  };
  alerts: Array<{
    type: 'PRICE_DROP' | 'OUT_OF_STOCK' | 'NEW_COMPETITOR' | 'PROMOTION';
    severity: 'HIGH' | 'MEDIUM' | 'LOW';
    message: string;
    competitor_shop_id?: string;
  }>;
}

export interface PricingABTest {
  id: string;
  tenant_id: string;
  product_id: string;
  test_name: string;
  control_price: number;
  variant_price: number;
  traffic_split: number;
  start_date: string;
  end_date: string;
  results?: {
    control: { impressions: number; clicks: number; conversions: number; revenue: number };
    variant: { impressions: number; clicks: number; conversions: number; revenue: number };
    winner?: 'CONTROL' | 'VARIANT' | 'INCONCLUSIVE';
    confidence?: number;
  };
  status: 'RUNNING' | 'COMPLETED' | 'PAUSED';
  created_at: string;
}

export interface IDynamicPricingDataSource {
  generatePricingDecision(productId: string, strategy?: PricingStrategy): Promise<PricingDecision>;
  fetchPendingDecisions(limit?: number): Promise<PricingDecision[]>;
  executePricingDecision(decisionId: string): Promise<{ success: boolean; message: string }>;
  rejectPricingDecision(decisionId: string, reason: string): Promise<{ success: boolean }>;
  fetchPricingConfig(productId: string): Promise<PricingConfig | null>;
  updatePricingConfig(productId: string, config: Partial<PricingConfig>): Promise<PricingConfig>;
  fetchCompetitorPrices(productId: string): Promise<CompetitorPriceRecord[]>;
  analyzeCompetitorPrices(productId: string, ourPrice: number): Promise<CompetitorAnalysis>;
  createABTest(params: {
    productId: string;
    testName: string;
    controlPrice: number;
    variantPrice: number;
    trafficSplit: number;
    durationDays: number;
  }): Promise<PricingABTest>;
  fetchABTests(productId?: string): Promise<PricingABTest[]>;
}

const STRATEGY_NAMES: Record<PricingStrategy, string> = {
  GAME_THEORY: '博弈定价',
  COMPETITION: '竞争定价',
  DEMAND_BASED: '需求定价',
  COST_PLUS: '成本加成',
  DYNAMIC: '动态定价',
};

const PLATFORM_NAMES: Record<string, string> = {
  AMAZON: '亚马逊',
  EBAY: 'eBay',
  SHOPEE: 'Shopee',
  TIKTOK: 'TikTok',
  TEMU: 'Temu',
};

class MockDynamicPricingDataSource implements IDynamicPricingDataSource {
  private decisions: PricingDecision[] = [];
  private configs: Map<string, PricingConfig> = new Map();
  private abTests: PricingABTest[] = [];

  constructor() {
    this.initMockData();
  }

  private initMockData() {
    const products = [
      { id: 'prod-001', name: '无线蓝牙耳机' },
      { id: 'prod-002', name: '智能手表' },
      { id: 'prod-003', name: '便携充电宝' },
      { id: 'prod-004', name: '手机壳' },
      { id: 'prod-005', name: '数据线' },
    ];

    const strategies: PricingStrategy[] = ['GAME_THEORY', 'COMPETITION', 'DEMAND_BASED', 'DYNAMIC'];

    for (let i = 0; i < 10; i++) {
      const product = products[i % products.length];
      const strategy = strategies[i % strategies.length];
      const currentPrice = 50 + Math.random() * 100;
      const changePercent = (Math.random() - 0.5) * 20;
      const suggestedPrice = currentPrice * (1 + changePercent / 100);

      this.decisions.push({
        id: `PD-${i + 1}`,
        tenant_id: 'tenant-001',
        shop_id: 'shop-001',
        product_id: product.id,
        product_name: product.name,
        current_price: currentPrice,
        suggested_price: suggestedPrice,
        price_change: suggestedPrice - currentPrice,
        change_percent: changePercent,
        adjustment_direction: changePercent > 1 ? 'INCREASE' : changePercent < -1 ? 'DECREASE' : 'MAINTAIN',
        strategy_used: strategy,
        decision_factors: {
          competitor_prices: Array.from({ length: 5 }, () => currentPrice * (0.8 + Math.random() * 0.4)),
          market_avg_price: currentPrice * (0.95 + Math.random() * 0.1),
          demand_level: Math.random() > 0.6 ? 'HIGH' : Math.random() > 0.3 ? 'MEDIUM' : 'LOW',
          inventory_level: Math.floor(Math.random() * 200),
          sales_velocity: Math.random() * 10,
          profit_margin: 15 + Math.random() * 20,
        },
        predicted_impact: {
          revenue_change: (Math.random() - 0.3) * 500,
          profit_change: (Math.random() - 0.3) * 100,
          sales_change: (Math.random() - 0.5) * 20,
          confidence: 0.6 + Math.random() * 0.35,
        },
        status: i < 3 ? 'PENDING' : i < 6 ? 'EXECUTED' : 'REJECTED',
        created_at: new Date(Date.now() - i * 3600000).toISOString(),
        expires_at: new Date(Date.now() + (24 - i) * 3600000).toISOString(),
      });
    }
  }

  async generatePricingDecision(productId: string, strategy?: PricingStrategy): Promise<PricingDecision> {
    await this.delay(1000);
    const currentPrice = 50 + Math.random() * 100;
    const changePercent = (Math.random() - 0.5) * 15;
    const suggestedPrice = currentPrice * (1 + changePercent / 100);

    const decision: PricingDecision = {
      id: `PD-${Date.now()}`,
      tenant_id: 'tenant-001',
      shop_id: 'shop-001',
      product_id: productId,
      product_name: '商品-' + productId,
      current_price: currentPrice,
      suggested_price: suggestedPrice,
      price_change: suggestedPrice - currentPrice,
      change_percent: changePercent,
      adjustment_direction: changePercent > 1 ? 'INCREASE' : changePercent < -1 ? 'DECREASE' : 'MAINTAIN',
      strategy_used: strategy || 'DYNAMIC',
      decision_factors: {
        competitor_prices: Array.from({ length: 5 }, () => currentPrice * (0.8 + Math.random() * 0.4)),
        market_avg_price: currentPrice * (0.95 + Math.random() * 0.1),
        demand_level: Math.random() > 0.5 ? 'HIGH' : 'MEDIUM',
        inventory_level: Math.floor(Math.random() * 200),
        sales_velocity: Math.random() * 10,
        profit_margin: 15 + Math.random() * 20,
      },
      predicted_impact: {
        revenue_change: (Math.random() - 0.3) * 500,
        profit_change: (Math.random() - 0.3) * 100,
        sales_change: (Math.random() - 0.5) * 20,
        confidence: 0.7 + Math.random() * 0.25,
      },
      status: 'PENDING',
      created_at: new Date().toISOString(),
      expires_at: new Date(Date.now() + 24 * 3600000).toISOString(),
    };

    this.decisions.unshift(decision);
    return decision;
  }

  async fetchPendingDecisions(limit: number = 20): Promise<PricingDecision[]> {
    await this.delay(300);
    return this.decisions.filter(d => d.status === 'PENDING').slice(0, limit);
  }

  async executePricingDecision(decisionId: string): Promise<{ success: boolean; message: string }> {
    await this.delay(500);
    const decision = this.decisions.find(d => d.id === decisionId);
    if (!decision) {
      throw new Error('决策不存在');
    }
    decision.status = 'EXECUTED';
    decision.executed_at = new Date().toISOString();
    decision.execution_result = { success: true, actual_price: decision.suggested_price };
    return { success: true, message: '价格调整成功' };
  }

  async rejectPricingDecision(decisionId: string, reason: string): Promise<{ success: boolean }> {
    await this.delay(300);
    const decision = this.decisions.find(d => d.id === decisionId);
    if (!decision) {
      throw new Error('决策不存在');
    }
    decision.status = 'REJECTED';
    decision.review_notes = reason;
    decision.reviewed_at = new Date().toISOString();
    return { success: true };
  }

  async fetchPricingConfig(productId: string): Promise<PricingConfig | null> {
    await this.delay(200);
    if (this.configs.has(productId)) {
      return this.configs.get(productId) || null;
    }
    const config: PricingConfig = {
      id: `PC-${productId}`,
      tenant_id: 'tenant-001',
      shop_id: 'shop-001',
      product_id: productId,
      base_price: 100,
      min_price: 70,
      max_price: 150,
      cost_price: 50,
      strategy: 'DYNAMIC',
      strategy_params: {
        game_theory: { competitor_weight: 0.3, market_share_target: 0.2, profit_priority: 0.7 },
        competition: { price_position: 'AVG', max_diff_percent: 10, follow_leader: false },
        demand_based: { elasticity_threshold: 1.5, demand_sensitivity: 0.5, seasonal_factor: 1 },
      },
      auto_adjust: false,
      adjust_frequency: 'DAILY',
      max_adjust_percent: 10,
      cooldown_hours: 24,
      min_profit_margin: 15,
      min_profit_amount: 0,
      enabled: true,
      created_at: new Date().toISOString(),
      updated_at: new Date().toISOString(),
    };
    this.configs.set(productId, config);
    return config;
  }

  async updatePricingConfig(productId: string, updates: Partial<PricingConfig>): Promise<PricingConfig> {
    await this.delay(300);
    const config = await this.fetchPricingConfig(productId);
    const updated = { ...config!, ...updates, updated_at: new Date().toISOString() };
    this.configs.set(productId, updated);
    return updated;
  }

  async fetchCompetitorPrices(productId: string): Promise<CompetitorPriceRecord[]> {
    await this.delay(400);
    const platforms = ['AMAZON', 'EBAY', 'SHOPEE', 'TIKTOK', 'TEMU'];
    return platforms.map((platform, index) => ({
      id: `CP-${productId}-${index}`,
      product_id: productId,
      competitor_shop_id: `COMP-${platform}-${index}`,
      competitor_name: `${PLATFORM_NAMES[platform]}店铺${index + 1}`,
      competitor_platform: platform,
      price: 80 + Math.random() * 40,
      shipping_cost: Math.random() * 10,
      total_price: 85 + Math.random() * 45,
      stock_status: Math.random() > 0.2 ? 'IN_STOCK' : Math.random() > 0.5 ? 'LOW_STOCK' : 'OUT_OF_STOCK',
      rating: 3.5 + Math.random() * 1.5,
      review_count: Math.floor(Math.random() * 500),
      collected_at: new Date(Date.now() - Math.random() * 3600000).toISOString(),
    }));
  }

  async analyzeCompetitorPrices(productId: string, ourPrice: number): Promise<CompetitorAnalysis> {
    await this.delay(500);
    const prices = await this.fetchCompetitorPrices(productId);
    const allPrices = prices.map(p => p.total_price);
    const minPrice = Math.min(...allPrices);
    const maxPrice = Math.max(...allPrices);
    const avgPrice = allPrices.reduce((a, b) => a + b, 0) / allPrices.length;

    return {
      product_id: productId,
      analysis_date: new Date().toISOString(),
      price_stats: {
        min_price: minPrice,
        max_price: maxPrice,
        avg_price: avgPrice,
        median_price: allPrices.sort((a, b) => a - b)[Math.floor(allPrices.length / 2)],
        our_price: ourPrice,
        our_rank: [...allPrices, ourPrice].sort((a, b) => a - b).indexOf(ourPrice) + 1,
        total_competitors: prices.length,
      },
      competitor_rankings: prices.map((p, i) => ({
        shop_id: p.competitor_shop_id,
        shop_name: p.competitor_name,
        price: p.total_price,
        rank: i + 1,
        price_diff: p.total_price - ourPrice,
        rating: p.rating,
        review_count: p.review_count,
      })),
      market_trend: {
        price_trend: Math.random() > 0.6 ? 'RISING' : Math.random() > 0.3 ? 'STABLE' : 'FALLING',
        competition_level: prices.length > 4 ? 'HIGH' : prices.length > 2 ? 'MEDIUM' : 'LOW',
        recommended_action: ourPrice > avgPrice * 1.1 ? 'DECREASE' : ourPrice < avgPrice * 0.9 ? 'INCREASE' : 'MAINTAIN',
      },
      alerts: [
        { type: 'PRICE_DROP', severity: 'HIGH', message: '发现竞争对手价格低于我们15%', competitor_shop_id: prices[0].competitor_shop_id },
        { type: 'PROMOTION', severity: 'MEDIUM', message: '2个竞争对手正在进行促销活动' },
      ],
    };
  }

  async createABTest(params: {
    productId: string;
    testName: string;
    controlPrice: number;
    variantPrice: number;
    trafficSplit: number;
    durationDays: number;
  }): Promise<PricingABTest> {
    await this.delay(500);
    const test: PricingABTest = {
      id: `ABT-${Date.now()}`,
      tenant_id: 'tenant-001',
      product_id: params.productId,
      test_name: params.testName,
      control_price: params.controlPrice,
      variant_price: params.variantPrice,
      traffic_split: params.trafficSplit,
      start_date: new Date().toISOString(),
      end_date: new Date(Date.now() + params.durationDays * 86400000).toISOString(),
      status: 'RUNNING',
      created_at: new Date().toISOString(),
    };
    this.abTests.push(test);
    return test;
  }

  async fetchABTests(productId?: string): Promise<PricingABTest[]> {
    await this.delay(300);
    let tests = this.abTests;
    if (productId) {
      tests = tests.filter(t => t.product_id === productId);
    }
    return tests;
  }

  private delay(ms: number): Promise<void> {
    return new Promise(resolve => setTimeout(resolve, ms));
  }
}

class ApiDynamicPricingDataSource implements IDynamicPricingDataSource {
  private baseUrl = '/api/pricing';

  async generatePricingDecision(productId: string, strategy?: PricingStrategy): Promise<PricingDecision> {
    const response = await fetch(`${this.baseUrl}/decisions/generate`, {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ product_id: productId, strategy }),
    });
    if (!response.ok) throw new Error('Failed to generate pricing decision');
    const data = await response.json();
    return data.data;
  }

  async fetchPendingDecisions(limit?: number): Promise<PricingDecision[]> {
    const params = new URLSearchParams({ limit: (limit || 20).toString() });
    const response = await fetch(`${this.baseUrl}/decisions/pending?${params}`);
    if (!response.ok) throw new Error('Failed to fetch pending decisions');
    const data = await response.json();
    return data.data;
  }

  async executePricingDecision(decisionId: string): Promise<{ success: boolean; message: string }> {
    const response = await fetch(`${this.baseUrl}/decisions/${decisionId}/execute`, {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
    });
    if (!response.ok) throw new Error('Failed to execute pricing decision');
    const data = await response.json();
    return data;
  }

  async rejectPricingDecision(decisionId: string, reason: string): Promise<{ success: boolean }> {
    const response = await fetch(`${this.baseUrl}/decisions/${decisionId}/reject`, {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ reason }),
    });
    if (!response.ok) throw new Error('Failed to reject pricing decision');
    const data = await response.json();
    return data;
  }

  async fetchPricingConfig(productId: string): Promise<PricingConfig | null> {
    const response = await fetch(`${this.baseUrl}/config/${productId}`);
    if (!response.ok) return null;
    const data = await response.json();
    return data.data;
  }

  async updatePricingConfig(productId: string, config: Partial<PricingConfig>): Promise<PricingConfig> {
    const response = await fetch(`${this.baseUrl}/config/${productId}`, {
      method: 'PUT',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify(config),
    });
    if (!response.ok) throw new Error('Failed to update pricing config');
    const data = await response.json();
    return data.data;
  }

  async fetchCompetitorPrices(productId: string): Promise<CompetitorPriceRecord[]> {
    const response = await fetch(`${this.baseUrl}/competitors/${productId}`);
    if (!response.ok) throw new Error('Failed to fetch competitor prices');
    const data = await response.json();
    return data.data;
  }

  async analyzeCompetitorPrices(productId: string, ourPrice: number): Promise<CompetitorAnalysis> {
    const response = await fetch(`${this.baseUrl}/competitors/${productId}/analyze?our_price=${ourPrice}`);
    if (!response.ok) throw new Error('Failed to analyze competitor prices');
    const data = await response.json();
    return data.data;
  }

  async createABTest(params: {
    productId: string;
    testName: string;
    controlPrice: number;
    variantPrice: number;
    trafficSplit: number;
    durationDays: number;
  }): Promise<PricingABTest> {
    const response = await fetch(`${this.baseUrl}/ab-tests`, {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify(params),
    });
    if (!response.ok) throw new Error('Failed to create A/B test');
    const data = await response.json();
    return data.data;
  }

  async fetchABTests(productId?: string): Promise<PricingABTest[]> {
    const params = productId ? `?product_id=${productId}` : '';
    const response = await fetch(`${this.baseUrl}/ab-tests${params}`);
    if (!response.ok) throw new Error('Failed to fetch A/B tests');
    const data = await response.json();
    return data.data;
  }
}

const useMock = process.env.REACT_APP_USE_MOCK === 'true';
export const dynamicPricingDataSource: IDynamicPricingDataSource = useMock
  ? new MockDynamicPricingDataSource()
  : new ApiDynamicPricingDataSource();

export { STRATEGY_NAMES, PLATFORM_NAMES };
