/**
 * [MOCK-ARBITRAGE] 跨平台套利数据源抽象层
 * 通过环境变量自动切换Mock/真实API
 * AI注意: 这是唯一入口，业务代码必须调用此层
 *
 * @module services/arbitrageDataSource
 * @author AI-Agent-1
 * @created 2026-03-19
 */

export interface ProfitSnapshot {
  netProfit: number;
  profitRate: number;
  roi: number;
  platformFee: number;
  logisticsCost: number;
  taxCost: number;
  exchangeRate: number;
}

export interface ArbitrageOpportunity {
  id: string;
  tenant_id: string;
  product_id: string;
  product_name: string;
  source_platform: string;
  source_url: string;
  source_price: number;
  source_currency: string;
  target_platform: string;
  target_price: number;
  target_currency: string;
  profit_snapshot: ProfitSnapshot;
  risk_level: 'LOW' | 'MEDIUM' | 'HIGH' | 'BLOCK';
  opportunity_score: number;
  status: 'PENDING' | 'APPROVED' | 'REJECTED' | 'EXECUTING' | 'EXECUTED' | 'FAILED';
  execution_mode: 'AUTO' | 'MANUAL';
  created_at: string;
  updated_at: string;
  executed_at?: string;
  error_message?: string;
}

export interface ArbitrageExecution {
  id: string;
  opportunity_id: string;
  tenant_id: string;
  status: 'STARTED' | 'PURCHASED' | 'LISTED' | 'SOLD' | 'COMPLETED' | 'FAILED';
  purchase_order_id?: string;
  listing_id?: string;
  sale_order_id?: string;
  actual_purchase_price?: number;
  actual_sale_price?: number;
  actual_profit?: number;
  notes?: string;
  created_at: string;
  updated_at: string;
}

export interface ArbitrageStats {
  totalOpportunities: number;
  pendingOpportunities: number;
  executedOpportunities: number;
  successRate: number;
  totalProfit: number;
  avgProfitMargin: number;
  avgROI: number;
  byPlatform: Record<string, { count: number; profit: number }>;
  byStatus: Record<string, number>;
}

export interface OpportunityQueryParams {
  status?: string;
  platform?: string;
  minScore?: number;
  limit?: number;
  offset?: number;
}

export interface CreateOpportunityParams {
  productId: string;
  productName: string;
  sourcePlatform: string;
  sourceUrl: string;
  sourcePrice: number;
  sourceCurrency: string;
  targetPlatform: string;
  targetPrice: number;
  targetCurrency: string;
  logisticsCost?: number;
  adBudget?: number;
  isB2B?: boolean;
  executionMode?: 'AUTO' | 'MANUAL';
}

export interface ScanParams {
  productIds: string;
  sourcePlatform: string;
}

export interface IArbitrageDataSource {
  getOpportunities(params?: OpportunityQueryParams): Promise<{ opportunities: ArbitrageOpportunity[]; total: number }>;
  getOpportunityById(id: string): Promise<ArbitrageOpportunity | null>;
  createOpportunity(params: CreateOpportunityParams): Promise<ArbitrageOpportunity>;
  approveOpportunity(id: string): Promise<ArbitrageOpportunity>;
  rejectOpportunity(id: string, reason: string): Promise<ArbitrageOpportunity>;
  executeOpportunity(id: string): Promise<ArbitrageExecution>;
  scanProducts(params: ScanParams): Promise<ArbitrageOpportunity[]>;
  getStats(): Promise<ArbitrageStats>;
  getExecutions(opportunityId: string): Promise<ArbitrageExecution[]>;
}

const USE_MOCK = process.env.REACT_APP_USE_MOCK === 'true';

const mockOpportunities: ArbitrageOpportunity[] = [
  {
    id: 'arb_001',
    tenant_id: 'tenant_001',
    product_id: 'prod_001',
    product_name: 'Wireless Bluetooth Headphones Pro',
    source_platform: '1688',
    source_url: 'https://1688.com/item/12345',
    source_price: 35,
    source_currency: 'CNY',
    target_platform: 'Amazon',
    target_price: 29.99,
    target_currency: 'USD',
    profit_snapshot: {
      netProfit: 12.5,
      profitRate: 0.42,
      roi: 0.85,
      platformFee: 4.5,
      logisticsCost: 3.0,
      taxCost: 1.2,
      exchangeRate: 0.14
    },
    risk_level: 'LOW',
    opportunity_score: 85,
    status: 'PENDING',
    execution_mode: 'MANUAL',
    created_at: '2026-03-19T10:00:00Z',
    updated_at: '2026-03-19T10:00:00Z'
  },
  {
    id: 'arb_002',
    tenant_id: 'tenant_001',
    product_id: 'prod_002',
    product_name: 'USB-C Fast Charging Cable 3-Pack',
    source_platform: 'Taobao',
    source_url: 'https://taobao.com/item/67890',
    source_price: 15,
    source_currency: 'CNY',
    target_platform: 'Temu',
    target_price: 8.99,
    target_currency: 'USD',
    profit_snapshot: {
      netProfit: 4.2,
      profitRate: 0.35,
      roi: 0.65,
      platformFee: 1.5,
      logisticsCost: 1.0,
      taxCost: 0.5,
      exchangeRate: 0.14
    },
    risk_level: 'MEDIUM',
    opportunity_score: 72,
    status: 'APPROVED',
    execution_mode: 'MANUAL',
    created_at: '2026-03-19T09:30:00Z',
    updated_at: '2026-03-19T11:00:00Z'
  },
  {
    id: 'arb_003',
    tenant_id: 'tenant_001',
    product_id: 'prod_003',
    product_name: 'Smart Watch Series X',
    source_platform: 'Alibaba',
    source_url: 'https://alibaba.com/item/11111',
    source_price: 120,
    source_currency: 'CNY',
    target_platform: 'Amazon',
    target_price: 49.99,
    target_currency: 'USD',
    profit_snapshot: {
      netProfit: 18.5,
      profitRate: 0.37,
      roi: 0.58,
      platformFee: 7.5,
      logisticsCost: 5.0,
      taxCost: 2.0,
      exchangeRate: 0.14
    },
    risk_level: 'LOW',
    opportunity_score: 78,
    status: 'EXECUTED',
    execution_mode: 'AUTO',
    created_at: '2026-03-18T14:00:00Z',
    updated_at: '2026-03-18T18:00:00Z',
    executed_at: '2026-03-18T18:00:00Z'
  },
  {
    id: 'arb_004',
    tenant_id: 'tenant_001',
    product_id: 'prod_004',
    product_name: 'LED Desk Lamp with Wireless Charger',
    source_platform: '1688',
    source_url: 'https://1688.com/item/22222',
    source_price: 45,
    source_currency: 'CNY',
    target_platform: 'TikTok',
    target_price: 24.99,
    target_currency: 'USD',
    profit_snapshot: {
      netProfit: 5.8,
      profitRate: 0.23,
      roi: 0.32,
      platformFee: 3.5,
      logisticsCost: 2.5,
      taxCost: 1.0,
      exchangeRate: 0.14
    },
    risk_level: 'HIGH',
    opportunity_score: 55,
    status: 'PENDING',
    execution_mode: 'MANUAL',
    created_at: '2026-03-19T08:00:00Z',
    updated_at: '2026-03-19T08:00:00Z'
  },
  {
    id: 'arb_005',
    tenant_id: 'tenant_001',
    product_id: 'prod_005',
    product_name: 'Portable Bluetooth Speaker Mini',
    source_platform: 'Taobao',
    source_url: 'https://taobao.com/item/33333',
    source_price: 28,
    source_currency: 'CNY',
    target_platform: 'Shopee',
    target_price: 12.99,
    target_currency: 'USD',
    profit_snapshot: {
      netProfit: 3.2,
      profitRate: 0.25,
      roi: 0.38,
      platformFee: 2.0,
      logisticsCost: 1.5,
      taxCost: 0.5,
      exchangeRate: 0.14
    },
    risk_level: 'MEDIUM',
    opportunity_score: 62,
    status: 'REJECTED',
    execution_mode: 'MANUAL',
    created_at: '2026-03-17T16:00:00Z',
    updated_at: '2026-03-18T10:00:00Z',
    error_message: 'Profit margin below threshold'
  }
];

const mockStats: ArbitrageStats = {
  totalOpportunities: 15,
  pendingOpportunities: 5,
  executedOpportunities: 8,
  successRate: 0.67,
  totalProfit: 256.8,
  avgProfitMargin: 0.32,
  avgROI: 0.56,
  byPlatform: {
    Amazon: { count: 6, profit: 120.5 },
    Temu: { count: 4, profit: 45.2 },
    TikTok: { count: 3, profit: 58.3 },
    Shopee: { count: 2, profit: 32.8 }
  },
  byStatus: {
    PENDING: 5,
    APPROVED: 2,
    EXECUTED: 6,
    REJECTED: 2
  }
};

class MockArbitrageDataSource implements IArbitrageDataSource {
  private opportunities = [...mockOpportunities];

  async getOpportunities(params?: OpportunityQueryParams): Promise<{ opportunities: ArbitrageOpportunity[]; total: number }> {
    await this.delay(300);
    let filtered = [...this.opportunities];

    if (params?.status) {
      filtered = filtered.filter(o => o.status === params.status);
    }
    if (params?.platform) {
      filtered = filtered.filter(o => o.target_platform === params.platform);
    }
    if (params?.minScore) {
      filtered = filtered.filter(o => o.opportunity_score >= params.minScore!);
    }

    const total = filtered.length;
    const offset = params?.offset || 0;
    const limit = params?.limit || 50;
    const opportunities = filtered.slice(offset, offset + limit);

    return { opportunities, total };
  }

  async getOpportunityById(id: string): Promise<ArbitrageOpportunity | null> {
    await this.delay(200);
    return this.opportunities.find(o => o.id === id) || null;
  }

  async createOpportunity(params: CreateOpportunityParams): Promise<ArbitrageOpportunity> {
    await this.delay(500);
    const opportunity: ArbitrageOpportunity = {
      id: `arb_${Date.now()}`,
      tenant_id: 'tenant_001',
      product_id: params.productId,
      product_name: params.productName,
      source_platform: params.sourcePlatform,
      source_url: params.sourceUrl,
      source_price: params.sourcePrice,
      source_currency: params.sourceCurrency,
      target_platform: params.targetPlatform,
      target_price: params.targetPrice,
      target_currency: params.targetCurrency,
      profit_snapshot: {
        netProfit: (params.targetPrice - params.sourcePrice * 0.14) * 0.6,
        profitRate: 0.35,
        roi: 0.5,
        platformFee: params.targetPrice * 0.15,
        logisticsCost: params.logisticsCost || 3,
        taxCost: params.targetPrice * 0.05,
        exchangeRate: 0.14
      },
      risk_level: 'MEDIUM',
      opportunity_score: Math.floor(Math.random() * 30) + 60,
      status: 'PENDING',
      execution_mode: params.executionMode || 'MANUAL',
      created_at: new Date().toISOString(),
      updated_at: new Date().toISOString()
    };
    this.opportunities.unshift(opportunity);
    return opportunity;
  }

  async approveOpportunity(id: string): Promise<ArbitrageOpportunity> {
    await this.delay(300);
    const opportunity = this.opportunities.find(o => o.id === id);
    if (!opportunity) throw new Error('Opportunity not found');
    opportunity.status = 'APPROVED';
    opportunity.updated_at = new Date().toISOString();
    return opportunity;
  }

  async rejectOpportunity(id: string, reason: string): Promise<ArbitrageOpportunity> {
    await this.delay(300);
    const opportunity = this.opportunities.find(o => o.id === id);
    if (!opportunity) throw new Error('Opportunity not found');
    opportunity.status = 'REJECTED';
    opportunity.error_message = reason;
    opportunity.updated_at = new Date().toISOString();
    return opportunity;
  }

  async executeOpportunity(id: string): Promise<ArbitrageExecution> {
    await this.delay(500);
    const opportunity = this.opportunities.find(o => o.id === id);
    if (!opportunity) throw new Error('Opportunity not found');
    opportunity.status = 'EXECUTING';
    opportunity.updated_at = new Date().toISOString();

    const execution: ArbitrageExecution = {
      id: `exec_${Date.now()}`,
      opportunity_id: id,
      tenant_id: opportunity.tenant_id,
      status: 'STARTED',
      created_at: new Date().toISOString(),
      updated_at: new Date().toISOString()
    };
    return execution;
  }

  async scanProducts(params: ScanParams): Promise<ArbitrageOpportunity[]> {
    await this.delay(1000);
    const newOpportunities: ArbitrageOpportunity[] = [];
    const productIds = params.productIds.split('\n').filter(id => id.trim());

    for (const productId of productIds) {
      const opportunity: ArbitrageOpportunity = {
        id: `arb_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`,
        tenant_id: 'tenant_001',
        product_id: productId.trim(),
        product_name: `Product ${productId.trim()}`,
        source_platform: params.sourcePlatform,
        source_url: `https://${params.sourcePlatform.toLowerCase()}.com/item/${productId}`,
        source_price: Math.floor(Math.random() * 100) + 10,
        source_currency: 'CNY',
        target_platform: ['Amazon', 'Temu', 'TikTok'][Math.floor(Math.random() * 3)],
        target_price: Math.floor(Math.random() * 50) + 15,
        target_currency: 'USD',
        profit_snapshot: {
          netProfit: Math.random() * 20 + 5,
          profitRate: Math.random() * 0.3 + 0.2,
          roi: Math.random() * 0.5 + 0.3,
          platformFee: Math.random() * 5 + 2,
          logisticsCost: 3,
          taxCost: 1,
          exchangeRate: 0.14
        },
        risk_level: ['LOW', 'MEDIUM', 'HIGH'][Math.floor(Math.random() * 3)] as any,
        opportunity_score: Math.floor(Math.random() * 40) + 50,
        status: 'PENDING',
        execution_mode: 'MANUAL',
        created_at: new Date().toISOString(),
        updated_at: new Date().toISOString()
      };
      newOpportunities.push(opportunity);
      this.opportunities.unshift(opportunity);
    }

    return newOpportunities;
  }

  async getStats(): Promise<ArbitrageStats> {
    await this.delay(200);
    return mockStats;
  }

  async getExecutions(opportunityId: string): Promise<ArbitrageExecution[]> {
    await this.delay(200);
    return [
      {
        id: 'exec_001',
        opportunity_id: opportunityId,
        tenant_id: 'tenant_001',
        status: 'COMPLETED',
        purchase_order_id: 'po_12345',
        listing_id: 'list_67890',
        sale_order_id: 'so_11111',
        actual_purchase_price: 35,
        actual_sale_price: 29.99,
        actual_profit: 12.5,
        notes: 'Successfully completed arbitrage',
        created_at: '2026-03-18T14:00:00Z',
        updated_at: '2026-03-18T18:00:00Z'
      }
    ];
  }

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

class ApiArbitrageDataSource implements IArbitrageDataSource {
  private baseUrl = '/api/v1/arbitrage';

  async getOpportunities(params?: OpportunityQueryParams): Promise<{ opportunities: ArbitrageOpportunity[]; total: number }> {
    const query = new URLSearchParams();
    if (params?.status) query.append('status', params.status);
    if (params?.platform) query.append('platform', params.platform);
    if (params?.minScore) query.append('minScore', params.minScore.toString());
    if (params?.limit) query.append('limit', params.limit.toString());
    if (params?.offset) query.append('offset', params.offset.toString());

    const response = await fetch(`${this.baseUrl}/opportunities?${query.toString()}`);
    if (!response.ok) throw new Error(`API Error: ${response.status}`);
    const result = await response.json();
    return result.data || { opportunities: [], total: 0 };
  }

  async getOpportunityById(id: string): Promise<ArbitrageOpportunity | null> {
    const response = await fetch(`${this.baseUrl}/opportunities/${id}`);
    if (!response.ok) {
      if (response.status === 404) return null;
      throw new Error(`API Error: ${response.status}`);
    }
    const result = await response.json();
    return result.data || null;
  }

  async createOpportunity(params: CreateOpportunityParams): Promise<ArbitrageOpportunity> {
    const response = await fetch(`${this.baseUrl}/opportunities`, {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify(params)
    });
    if (!response.ok) throw new Error(`API Error: ${response.status}`);
    const result = await response.json();
    return result.data;
  }

  async approveOpportunity(id: string): Promise<ArbitrageOpportunity> {
    const response = await fetch(`${this.baseUrl}/opportunities/${id}/approve`, {
      method: 'POST'
    });
    if (!response.ok) throw new Error(`API Error: ${response.status}`);
    const result = await response.json();
    return result.data;
  }

  async rejectOpportunity(id: string, reason: string): Promise<ArbitrageOpportunity> {
    const response = await fetch(`${this.baseUrl}/opportunities/${id}/reject`, {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ reason })
    });
    if (!response.ok) throw new Error(`API Error: ${response.status}`);
    const result = await response.json();
    return result.data;
  }

  async executeOpportunity(id: string): Promise<ArbitrageExecution> {
    const response = await fetch(`${this.baseUrl}/opportunities/${id}/execute`, {
      method: 'POST'
    });
    if (!response.ok) throw new Error(`API Error: ${response.status}`);
    const result = await response.json();
    return result.data;
  }

  async scanProducts(params: ScanParams): Promise<ArbitrageOpportunity[]> {
    const response = await fetch(`${this.baseUrl}/scan`, {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify(params)
    });
    if (!response.ok) throw new Error(`API Error: ${response.status}`);
    const result = await response.json();
    return result.data || [];
  }

  async getStats(): Promise<ArbitrageStats> {
    const response = await fetch(`${this.baseUrl}/stats`);
    if (!response.ok) throw new Error(`API Error: ${response.status}`);
    const result = await response.json();
    return result.data;
  }

  async getExecutions(opportunityId: string): Promise<ArbitrageExecution[]> {
    const response = await fetch(`${this.baseUrl}/opportunities/${opportunityId}/executions`);
    if (!response.ok) throw new Error(`API Error: ${response.status}`);
    const result = await response.json();
    return result.data || [];
  }
}

const arbitrageDataSource: IArbitrageDataSource = USE_MOCK
  ? new MockArbitrageDataSource()
  : new ApiArbitrageDataSource();

export default arbitrageDataSource;
export { arbitrageDataSource };
