import { logger } from '../../utils/logger';
import db from '../../config/database';

export interface PurchaseOrder {
  id: string;
  tenantId: string;
  productId: string;
  supplierId: string;
  quantity: number;
  unitPrice: number;
  totalAmount: number;
  status: 'PENDING_INQUIRY' | 'PURCHASED' | 'IN_TRANSIT' | 'ARRIVED' | 'QA_PASSED' | 'STOCKED';
  traceId: string;
}

export interface SalesOrder {
  id: string;
  tenantId: string;
  shopId: string;
  orderId: string;
  productId: string;
  quantity: number;
  sellingPrice: number;
  totalRevenue: number;
  status: 'PULLING' | 'FULFILLING' | 'SHIPPED' | 'DELIVERED' | 'AFTER_SALES' | 'REFUNDED';
  traceId: string;
}

/**
 * [BIZ_TRADE_01] 买卖全链路履约中枢 (Order-to-Cash & Procure-to-Pay)
 * @description 打通“买货-卖货-履约-回款”闭环
 */
export class TradeService {
  private static readonly PO_TABLE = 'cf_purchase_orders';
  private static readonly INVENTORY_TABLE = 'cf_inventory';

  /**
   * 买链路：供应商询价与采购下单
   */
  static async createPurchaseOrder(params: Omit<PurchaseOrder, 'id' | 'status'>): Promise<string> {
    const poId = `PO-${Date.now()}`;
    logger.info(`[Trade] Creating PO: ${poId} for Product: ${params.productId}, Tenant: ${params.tenantId}`);
    
    // 实际业务中需插入数据库 cf_purchase_orders
    await db(this.PO_TABLE).insert({
      id: poId,
      tenant_id: params.tenantId,
      product_id: params.productId,
      supplier_id: params.supplierId,
      quantity: params.quantity,
      unit_price: params.unitPrice,
      total_amount: params.totalAmount,
      status: 'PURCHASED',
      trace_id: params.traceId,
      created_at: new Date(),
      updated_at: new Date()
    });

    // 自动触发库存预锁定 (BIZ_AUTO_01)
    await this.lockInventory(params.productId, params.quantity, params.tenantId);

    return poId;
  }

  /**
   * [BIZ_AUTO_01] 锁定库存逻辑
   * @description 在采购下单后锁定相应库存，防止超卖或分配错误
   */
  private static async lockInventory(productId: string, quantity: number, tenantId: string): Promise<void> {
    logger.info(`[Trade] Locking inventory for Product: ${productId}, Quantity: ${quantity}, Tenant: ${tenantId}`);
    
    // 检查是否存在库存记录
    const stock = await db(this.INVENTORY_TABLE).where({ product_id: productId, tenant_id: tenantId }).first();
    
    if (stock) {
      await db(this.INVENTORY_TABLE).where({ product_id: productId, tenant_id: tenantId }).update({
        locked_stock: (stock.locked_stock || 0) + quantity,
        updated_at: new Date()
      });
    } else {
      await db(this.INVENTORY_TABLE).insert({
        product_id: productId,
        tenant_id: tenantId,
        available_stock: 0,
        locked_stock: quantity,
        warehouse_id: 'DEFAULT',
        created_at: new Date(),
        updated_at: new Date()
      });
    }
  }

  /**
   * [BIZ_TRADE_02] 创建仓际调拨单
   */
  static async createTransferOrder(params: {
    tenantId: string;
    productId: string;
    skuId: string;
    fromWarehouseId: string;
    toWarehouseId: string;
    quantity: number;
    traceId: string;
  }): Promise<string> {
    const toId = `TO-${Date.now()}`;
    logger.info(`[Trade] Creating Transfer Order: ${toId} for SKU: ${params.skuId}, From: ${params.fromWarehouseId}, To: ${params.toWarehouseId}`);

    // 1. 插入调拨单表 (cf_transfer_orders)
    await db('cf_transfer_orders').insert({
      id: toId,
      tenant_id: params.tenantId,
      product_id: params.productId,
      sku_id: params.skuId,
      from_warehouse_id: params.fromWarehouseId,
      to_warehouse_id: params.toWarehouseId,
      quantity: params.quantity,
      status: 'PENDING_TRANSFER',
      trace_id: params.traceId,
      created_at: new Date(),
      updated_at: new Date()
    });

    // 2. 预锁定来源仓库存
    await db(this.INVENTORY_TABLE)
      .where({ product_id: params.productId, tenant_id: params.tenantId, warehouse_id: params.fromWarehouseId })
      .decrement('available_stock', params.quantity)
      .increment('locked_stock', params.quantity);

    return toId;
  }

  /**
   * [BIZ_TRADE_01-EXT] 质量检测 (QA)
   * @description 到货后执行质量检测，并更新采购单状态
   */
  static async performQualityCheck(poId: string, result: 'PASSED' | 'FAILED', notes?: string): Promise<void> {
    logger.info(`[Trade] QA ${result} for PO: ${poId}. Notes: ${notes}`);

    await db(this.PO_TABLE).where({ id: poId }).update({
      status: result === 'PASSED' ? 'QA_PASSED' : 'QA_FAILED',
      updated_at: new Date()
    });

    if (result === 'PASSED') {
      const po = await db(this.PO_TABLE).where({ id: poId }).first();
      await this.addToStock(po.product_id, po.quantity, po.tenant_id);
    }
  }

  /**
   * [BIZ_TRADE_01-EXT] 入库上架
   * @description 将质检通过的商品正式转入可用库存
   */
  private static async addToStock(productId: string, quantity: number, tenantId: string): Promise<void> {
    logger.info(`[Trade] Stocking ${quantity} units for Product: ${productId}, Tenant: ${tenantId}`);

    const stock = await db(this.INVENTORY_TABLE).where({ product_id: productId, tenant_id: tenantId }).first();

    if (stock) {
      await db(this.INVENTORY_TABLE).where({ product_id: productId, tenant_id: tenantId }).update({
        available_stock: (stock.available_stock || 0) + quantity,
        locked_stock: Math.max(0, (stock.locked_stock || 0) - quantity),
        updated_at: new Date()
      });
    } else {
      await db(this.INVENTORY_TABLE).insert({
        product_id: productId,
        tenant_id: tenantId,
        available_stock: quantity,
        locked_stock: 0,
        warehouse_id: 'DEFAULT',
        created_at: new Date(),
        updated_at: new Date()
      });
    }
  }

  /**
   * [BIZ_TRADE_01-EXT] 退款核销与售后处理
   */
  static async handleRefund(soId: string, refundAmount: number, reason: string): Promise<void> {
    logger.info(`[Trade] Processing refund for SO: ${soId}, Amount: ${refundAmount}, Reason: ${reason}`);

    // 1. 更新订单状态为已退款
    await db('cf_orders').where({ id: soId }).update({
      status: 'REFUNDED',
      updated_at: new Date()
    });

    // 2. 在财务模块记录退款支出 (BIZ_FIN_01)
    // 假设 FinanceService 处理利润扣除逻辑
  }

  /**
   * 卖链路：订单拉取与发货履约
   */
  static async processSalesOrder(params: Omit<SalesOrder, 'id' | 'status'>): Promise<string> {
    const soId = `SO-${Date.now()}`;
    logger.info(`[Trade] Processing SO: ${soId} for Order: ${params.orderId}, Tenant: ${params.tenantId}`);
    // 实际业务中需插入数据库 cf_sales_orders
    return soId;
  }

  /**
   * 售后处理与退款核销
   */
  static async handleAfterSales(soId: string, reason: string): Promise<void> {
    logger.info(`[Trade] Handling after-sales for SO: ${soId}, Reason: ${reason}`);
    // 实际业务中需更新 cf_sales_orders 状态并同步到财务模块
  }

  /**
   * 经营看板口径汇总
   */
  static async getBusinessMetrics(tenantId: string) {
    logger.info(`[Trade] Fetching metrics for Tenant: ${tenantId}`);
    // 实际业务中应从数据库汇总毛利、现金流、回款周期等
    return {
      grossProfit: 0,
      cashFlow: 0,
      paymentCycle: '14 days',
      returnRate: '2.5%'
    };
  }

  /**
   * 初始化数据库表
   */
  static async initTable() {
    const hasPOTable = await db.schema.hasTable(this.PO_TABLE);
    if (!hasPOTable) {
      logger.info(`📦 Creating ${this.PO_TABLE} table...`);
      await db.schema.createTable(this.PO_TABLE, (table) => {
        table.string('id', 64).primary();
        table.string('tenant_id', 64).notNullable();
        table.string('product_id', 64).notNullable();
        table.string('supplier_id', 64);
        table.integer('quantity');
        table.decimal('unit_price', 15, 2);
        table.decimal('total_amount', 15, 2);
        table.string('status', 32);
        table.string('trace_id', 64);
        table.timestamps(true, true);
        table.index(['tenant_id', 'product_id']);
      });
    }

    const hasInventoryTable = await db.schema.hasTable(this.INVENTORY_TABLE);
    if (!hasInventoryTable) {
      logger.info(`📦 Creating ${this.INVENTORY_TABLE} table...`);
      await db.schema.createTable(this.INVENTORY_TABLE, (table) => {
        table.increments('id').primary();
        table.string('product_id', 64).notNullable();
        table.string('tenant_id', 64).notNullable();
        table.string('warehouse_id', 64).notNullable();
        table.integer('available_stock').defaultTo(0);
        table.integer('locked_stock').defaultTo(0);
        table.timestamps(true, true);
        table.unique(['product_id', 'tenant_id', 'warehouse_id']);
      });
    }

    const hasTransferTable = await db.schema.hasTable('cf_transfer_orders');
    if (!hasTransferTable) {
      logger.info('📦 Creating cf_transfer_orders table...');
      await db.schema.createTable('cf_transfer_orders', (table) => {
        table.string('id', 64).primary();
        table.string('tenant_id', 64).notNullable();
        table.string('product_id', 64).notNullable();
        table.string('sku_id', 64);
        table.string('from_warehouse_id', 64);
        table.string('to_warehouse_id', 64);
        table.integer('quantity');
        table.string('status', 32);
        table.string('trace_id', 64);
        table.timestamps(true, true);
      });
    }
  }
}
