import axios from 'axios';
import db from '../config/database';
import { CDCPipeline } from '../core/pipeline/CDCPipeline';
import { DomainEventBus } from '../core/runtime/DomainEventBus';
import { MultiTenantCore } from '../domains/Tenant/MultiTenantCore';
import { Product } from '../models/Product';
import { logger } from '../utils/logger';
import { AgingInventoryService } from './AgingInventoryService';
import { InventoryAgingService } from './InventoryAgingService';
import { AIService } from './AIService';
import { ArbitrageService } from './ArbitrageService';
import { CompetitorService } from './CompetitorService';
import { ImageFingerprintService } from './ImageFingerprintService';
import { InventoryService } from './InventoryService';
import { MarketingService } from './MarketingService';
import { SupplyChainService } from './SupplyChainService';
import { TaxService } from './TaxService';
import { VisionFactoryService } from './VisionFactoryService';

export class ProductService {
  private static TABLE_NAME = 'cf_product';

  /**
   * 初始化数据库表
   */
  static async initTable() {
    const hasProductTable = await db.schema.hasTable(this.TABLE_NAME);
    if (!hasProductTable) {
      console.log(`📦 Creating ${this.TABLE_NAME} table...`);
      await db.schema.createTable(this.TABLE_NAME, (table) => {
        table.increments('id').primary();
        table.string('tenant_id', 50).notNullable().index(); // [CORE_SEC_45] 租户隔离
        table.string('platform', 50).notNullable();
        table.string('site', 16).defaultTo('GLOBAL'); // [V30.0] 站点维度
        table.string('productId', 100).notNullable();
        table.text('title');
        table.text('originalTitle');
        table.decimal('price', 15, 2).defaultTo(0);
        table.decimal('originalPrice', 15, 2).defaultTo(0);
        table.string('currency', 10).defaultTo('CNY');
        
        // 物理属性：CM, KG, M3 (符合业务规则)
        table.decimal('length_cm', 10, 2).defaultTo(0);
        table.decimal('width_cm', 10, 2).defaultTo(0);
        table.decimal('height_cm', 10, 2).defaultTo(0);
        table.decimal('weight_kg', 10, 3).defaultTo(0);
        
        table.string('mainImage', 500);
        table.string('detailUrl', 1000);
        table.string('shopName', 200);
        table.string('shopId', 100);
        table.bigInteger('sales').defaultTo(0);
        table.double('rating').defaultTo(0);
        table.text('description'); // 商品详情
        table.json('attributes');
        table.json('images');
        table.json('skus');
        table.string('phash', 64); // [CORE_AI_10] 图像指纹
        table.string('semantic_hash', 64);
        table.text('vector_embedding');
        table.string('status', 32).defaultTo('DRAFTED'); // DRAFTED, PENDING_REVIEW, APPROVED, REJECTED
        table.decimal('ai_confidence', 5, 4).defaultTo(1.0); // AI 信心指数
        table.timestamps(true, true);
        
        // 索引优化
        table.index(['tenant_id', 'platform', 'site'], 'idx_prod_geo');
        table.unique(['tenant_id', 'platform', 'productId'], 'uk_prod_id');
        table.index(['phash'], 'idx_prod_phash');
        table.index(['semantic_hash'], 'idx_prod_semantic');
      });
      console.log(`✅ Table ${this.TABLE_NAME} created`);
    } else {
      // 动态列检查 (CORE_SEC_45)
      const hasTenantId = await db.schema.hasColumn(this.TABLE_NAME, 'tenant_id');
      if (!hasTenantId) {
        await db.schema.alterTable(this.TABLE_NAME, (table) => {
          table.string('tenant_id', 50).after('id').index();
        });
        console.log(`✅ Column tenant_id added to ${this.TABLE_NAME}`);
      }
      
      // 动态列检查 (CORE_AI_10)
      const hasPhash = await db.schema.hasColumn(this.TABLE_NAME, 'phash');
      if (!hasPhash) {
        await db.schema.alterTable(this.TABLE_NAME, (table) => {
          table.string('phash', 64).after('skus').index();
        });
        console.log(`✅ Column phash added to ${this.TABLE_NAME}`);
      }

      const hasDescription = await db.schema.hasColumn(this.TABLE_NAME, 'description');
      if (!hasDescription) {
        await db.schema.alterTable(this.TABLE_NAME, (table) => {
          table.text('description').after('rating');
        });
        console.log(`✅ Column description added to ${this.TABLE_NAME}`);
      }

      const hasSemanticHash = await db.schema.hasColumn(this.TABLE_NAME, 'semantic_hash');
      if (!hasSemanticHash) {
        await db.schema.alterTable(this.TABLE_NAME, (table) => {
          table.string('semantic_hash', 64).after('phash').index();
        });
        console.log(`✅ Column semantic_hash added to ${this.TABLE_NAME}`);
      }

      const hasVectorEmbedding = await db.schema.hasColumn(this.TABLE_NAME, 'vector_embedding');
      if (!hasVectorEmbedding) {
        await db.schema.alterTable(this.TABLE_NAME, (table) => {
          table.text('vector_embedding').after('semantic_hash');
        });
        console.log(`✅ Column vector_embedding added to ${this.TABLE_NAME}`);
      }

      const hasStatus = await db.schema.hasColumn(this.TABLE_NAME, 'status');
      if (!hasStatus) {
        await db.schema.alterTable(this.TABLE_NAME, (table) => {
          table.string('status', 32).after('vector_embedding').defaultTo('DRAFTED');
        });
        console.log(`✅ Column status added to ${this.TABLE_NAME}`);
      }

      const hasAiConfidence = await db.schema.hasColumn(this.TABLE_NAME, 'ai_confidence');
      if (!hasAiConfidence) {
        await db.schema.alterTable(this.TABLE_NAME, (table) => {
          table.decimal('ai_confidence', 5, 4).after('status').defaultTo(1.0);
        });
        console.log(`✅ Column ai_confidence added to ${this.TABLE_NAME}`);
      }
    }
  }

  /**
   * [BIZ_EXT_11] 智能库存预测分析
   */
  static async predictProductDemand(tenantId: string, id: number) {
    const product = await this.getById(tenantId, id);
    if (!product || !product.skus) return null;

    const predictions = [];
    for (const sku of product.skus) {
      const result = await InventoryService.predictSKUDemand(id.toString(), sku.skuId);
      predictions.push(result);
    }
    return predictions;
  }

  /**
   * [BIZ_EXT_12] 执行流失营销挽留任务
   */
  static async runAbandonedRecoveryTask() {
    return await MarketingService.processAbandonedCarts();
  }

  /**
   * [CORE_DEV_04] 抓取并生成图像指纹
   */
  static async collectAndFingerprint(tenantId: string, id: number) {
    const product = await this.getById(tenantId, id);
    if (!product || !product.mainImage) return;

    try {
      const response = await axios.get(product.mainImage, { responseType: 'arraybuffer' });
      const buffer = Buffer.from(response.data, 'binary');
      const hash = await ImageFingerprintService.generatePHash(buffer);
      
      // 更新产品图像指纹 (CORE_DEV_04)
      await this.update(tenantId, id, { phash: hash } as any);
      return hash;
    } catch (err: any) {
      console.error(`[ProductService] Fingerprinting failed: ${err.message}`);
    }
  }

  /**
   * [BIZ_EXT_05] 库存周转分析与清仓建议
   */
  static async analyzeInventoryAging(tenantId: string, id: number) {
    const product = await this.getById(tenantId, id);
    if (!product || !product.skus) return null;

    const agingData = [];
    for (const sku of product.skus) {
      const info = await InventoryAgingService.analyzeAging(tenantId);
      const suggestions = info.filter(item => item.skuId === sku.skuId).map(item => ({
        ...item,
        clearance: item.suggestedAction
      }));
      agingData.push({ skuId: sku.skuId, agingInfo: suggestions });
    }
    return agingData;
  }

  /**
   * [BIZ_EXT_08] 全球税务合规引擎
   */
  static async calculateProductTax(tenantId: string, id: number, countryCode: string, isB2B: boolean = false) {
    const product = await this.getById(tenantId, id);
    if (!product || !product.costPrice) return null;

    return await TaxService.calculateTax({
      countryCode,
      baseAmount: product.costPrice,
      currency: 'USD',
      isB2B,
      iossNumber: isB2B ? 'IOSS-TEST-123' : undefined
    });
  }

  /**
   * [CORE_AI_15] 视觉/语义复合检索
   * @description 通过视觉哈希、语义哈希或向量相似度寻找同款
   */
  static async findByFingerprint(tenantId: string, params: {
    phash?: string;
    semanticHash?: string;
    vectorEmbedding?: number[];
    threshold?: number;
  }) {
    const { phash, semanticHash, vectorEmbedding, threshold = 0.9 } = params;
    const query = MultiTenantCore.from(tenantId, this.TABLE_NAME);

    // 1. 优先尝试精确哈希匹配 (快速路径)
    if (phash) {
      const match = await query.clone().where({ phash }).first();
      if (match) return [this.parseProduct(match)];
    }

    if (semanticHash) {
      const match = await query.clone().where({ semantic_hash: semanticHash }).first();
      if (match) return [this.parseProduct(match)];
    }

    // 2. 向量相似度检索 (全量搜索，在大规模场景下应使用专门的向量库)
    if (vectorEmbedding) {
      const products = await query.clone().whereNotNull('vector_embedding').select('*');
      const results = products
        .map((p: any) => {
          const pEmbedding = JSON.parse(p.vector_embedding);
          const similarity = this.cosineSimilarity(vectorEmbedding, pEmbedding);
          return { ...p, similarity };
        })
        .filter((p: any) => p.similarity >= threshold)
        .sort((a: any, b: any) => b.similarity - a.similarity);
      return results;
    }

    return [];
  }

  private static cosineSimilarity(vecA: number[], vecB: number[]): number {
    let dotProduct = 0;
    let normA = 0;
    let normB = 0;
    for (let i = 0; i < vecA.length; i++) {
      dotProduct += vecA[i] * vecB[i];
      normA += vecA[i] * vecA[i];
      normB += vecB[i] * vecB[i];
    }
    return dotProduct / (Math.sqrt(normA) * Math.sqrt(normB));
  }

  /**
   * [BIZ_EXT_09] 全球同行嗅探器
   */
  static async sniffCompetitors(tenantId: string, id: number) {
    const product = await this.getById(tenantId, id);
    if (!product || !product.images || product.images.length === 0) return null;

    const results = [];
    for (const imageUrl of product.images) {
      // 假设 imageUrl 就是指纹，或者先转为指纹
      const res = await CompetitorService.findCrossPlatformMatches(imageUrl);
      results.push(...res);
    }
    return results;
  }

  /**
   * [BIZ_EXT_10] 供应链全链路溯源
   */
  static async trackSupplyChain(tenantId: string, id: number) {
    const product = await this.getById(tenantId, id);
    if (!product) return null;
    return await SupplyChainService.traceSourceFactory(tenantId, id.toString(), product.mainImage);
  }

  /**
   * [BIZ_EXT_07] 分析选品利差
   */
  static async analyzeProductArbitrage(tenantId: string, id: number) {
    const product = await this.getById(tenantId, id);
    if (!product || !product.costPrice) return null;

    const arbitrageService = ArbitrageService.getInstance();
    // 模拟创建一个套利机会来分析利差
    return await arbitrageService.createOpportunity(
      tenantId,
      id.toString(),
      product.title,
      '1688',
      `https://1688.com/item/${id}`,
      product.costPrice,
      'CNY',
      'Amazon',
      product.costPrice * 3.5, // 假设亚马逊售价是成本的3.5倍
      'USD'
    );
  }

  /**
   * [BIZ_DEV_02] 侵权合规性审计
   */
  static async auditProductIP(tenantId: string, id: number) {
    const product = await this.getById(tenantId, id);
    if (!product) return null;

    const result = await AIService.checkIPRisk({
      title: product.title,
      description: product.description,
      imageUrls: product.images || []
    });

    if (result.isRisky) {
      await this.update(tenantId, id, { status: 'rejected' } as any); // 假设 status 是 cf_product 字段
    }

    return result;
  }

  /**
   * [BIZ_PROD_12] AI 商品全自动“清洗”与本地化 (Washer)
   * @description 过滤非法字符/Logo，重写地道 Listing，并生成目标 market 营销图
   */
  static async washAndLocalize(tenantId: string, id: number, targetMarket: string, targetLang: string = 'en') {
    const product = await this.getById(tenantId, id);
    if (!product) throw new Error('Product not found');

    logger.info(`[ProductService] Starting "Washer" for Product ${id} (${targetMarket})`);

    // 1. 语义清洗与本地化 (AIService)
    const localization = await AIService.localizeForIndependentStation({
      title: product.title || product.originalTitle || '',
      description: product.description || '',
      targetMarket
    });

    // 2. 视觉本地化增强 (VisionFactoryService)
    let marketingImage = product.mainImage;
    if (product.mainImage) {
      marketingImage = await VisionFactoryService.generateMarketingImage({
        originalImageUrl: product.mainImage,
        productTitle: localization.seoTitle,
        targetMarket,
        aestheticStyle: targetMarket === 'Middle East' ? 'Gold & Luxury' : 'Minimalist'
      });
    }

    // 3. 更新产品数据
    const updateData: Partial<Product> = {
      title: localization.seoTitle,
      description: localization.localizedBodyHtml,
      mainImage: marketingImage,
      // 将 SEO 标签作为扩展属性存储 (此处模拟)
      attributes: {
        ...product.attributes,
        seo_tags: JSON.stringify(localization.tags),
        json_ld: localization.jsonLd
      }
    };

    await this.update(tenantId, id, updateData);

    return {
      id,
      originalTitle: product.title,
      newTitle: localization.seoTitle,
      marketingImage,
      tags: localization.tags
    };
  }

  static async getAll(tenantId: string, params?: { platform?: string; status?: string }) {
    const query = MultiTenantCore.from(tenantId, this.TABLE_NAME);
    if (params?.platform) query.where({ platform: params.platform });
    if (params?.status) query.where({ status: params.status });
    const products = await query.select('*');
    return products.map((p: any) => this.parseProduct(p));
  }

  static async getById(tenantId: string, id: number): Promise<Product | null> {
    const product = await MultiTenantCore.from(tenantId, this.TABLE_NAME).where({ id }).first();
    return product ? this.parseProduct(product) : null;
  }

  static async create(tenantId: string, product: Partial<Product>): Promise<number> {
    const data = {
      ...this.formatProduct(product),
      tenant_id: tenantId,
      created_at: new Date(),
      updated_at: new Date(),
    };
    const [id] = await db(this.TABLE_NAME).insert(data);
    return id;
  }

  /**
   * 创建商品
   */
  static async createProduct(params: {
    tenantId: string;
    platform: string;
    title: string;
    description: string;
    price: number;
    images: string;
    status: string;
  }): Promise<string> {
    const { tenantId, platform, title, description, price, images, status } = params;
    
    const productData: Partial<Product> = {
      platform,
      title,
      description,
      price,
      images: JSON.parse(images),
      status
    };
    
    const id = await this.create(tenantId, productData);
    return id.toString();
  }

  /**
   * [CORE_DEV_08] 集成向量化存储 & [CORE_DEV_11] CDC 拦截
   */
  static async update(tenantId: string, id: number, product: Partial<Product>): Promise<void> {
    const owned = await MultiTenantCore.ensureOwnership(tenantId, this.TABLE_NAME, id);
    if (!owned) throw new Error('Unauthorized access to product record');

    const data = {
      ...this.formatProduct(product),
      updated_at: new Date(),
    };
    await MultiTenantCore.from(tenantId, this.TABLE_NAME).where({ id }).update(data);
    
    const updatedProduct = await this.getById(tenantId, id);

    // 1. 触发 CDC 变更拦截 (CORE_DEV_11)
    if (updatedProduct) {
      CDCPipeline.onProductChange(id, 'UPDATE', updatedProduct).catch(err => {
        logger.error(`[ProductService] CDC intercept failed: ${err.message}`);
      });
    }
  }

  static async delete(tenantId: string, id: number): Promise<void> {
    const owned = await MultiTenantCore.ensureOwnership(tenantId, this.TABLE_NAME, id);
    if (!owned) throw new Error('Unauthorized access to product record');

    await MultiTenantCore.from(tenantId, this.TABLE_NAME).where({ id }).delete();
  }

  static async findByPhash(tenantId: string, phash: string): Promise<Product[]> {
    const results = await MultiTenantCore.from(tenantId, this.TABLE_NAME).where({ phash }).select('*');
    return results.map((p: any) => this.parseProduct(p));
  }

  /**
   * [BIZ_EXT_01] 模拟商品同步逻辑
   */
  static async syncProduct(productId: string, tenantId: string) {
    logger.info(`[ProductService] Syncing product ${productId} for tenant ${tenantId}`);
    // 实际业务中应对接第三方平台 API 获取最新状态并更新数据库
    await new Promise(resolve => setTimeout(resolve, 500));
  }

  /**
   * 更新商品库存 (BIZ_INV_05)
   */
  static async updateStock(tenantId: string, productId: string, delta: number) {
    logger.info(`[ProductService] Updating stock for ${productId} by ${delta}`);
    
    const product = await db(this.TABLE_NAME).where({ id: productId, tenant_id: tenantId }).first();
    if (!product) throw new Error('Product not found');

    await db(this.TABLE_NAME).where({ id: productId }).update({
      stock: (product.stock || 0) + delta,
      updated_at: new Date()
    });

    // [BIZ_GOV_20] 发布业务事件到总线，触发自动审计
    DomainEventBus.getInstance().publish('STOCK_UPDATE', {
      tenantId,
      module: 'INVENTORY',
      action: 'STOCK_UPDATE',
      resourceType: 'PRODUCT',
      resourceId: productId,
      data: { delta, newStock: (product.stock || 0) + delta },
      traceId: 'stock-update-' + Date.now()
    });
  }

  private static parseProduct(dbData: any): Product {
    return {
      ...dbData,
      images: typeof dbData.images === 'string' ? JSON.parse(dbData.images) : dbData.images,
      skus: typeof dbData.skus === 'string' ? JSON.parse(dbData.skus) : dbData.skus,
      attributes: typeof dbData.attributes === 'string' ? JSON.parse(dbData.attributes) : dbData.attributes,
    };
  }

  private static formatProduct(product: Partial<Product>): any {
    const formatted: any = { ...product };
    if (product.images) formatted.images = JSON.stringify(product.images);
    if (product.skus) formatted.skus = JSON.stringify(product.skus);
    if (product.attributes) formatted.attributes = JSON.stringify(product.attributes);
    delete formatted.id;
    delete formatted.tenant_id;
    delete formatted.createdAt;
    delete formatted.updatedAt;
    return formatted;
  }
}
