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

export interface FXRate {
  pair: string; // e.g., 'USD/CNY'
  rate: number;
  volatility: number; // 波动率
  lastUpdated: Date;
}

export interface HedgingOrder {
  id: string;
  tenantId: string;
  pair: string;
  amount: number;
  strikeRate: number;
  expiryDate: Date;
  status: 'PENDING' | 'EXECUTED' | 'EXPIRED' | 'CANCELLED';
}

/**
 * [BIZ_FIN_03] 汇率自动对冲执行 (Auto FX Hedging Execution)
 * [BIZ_FIN_12] 多币种汇率避险与结算中枢 (FX Engine)
 * @description 基于波动率自动计算安全边际，并模拟生成对冲头寸
 */
export class FXHedgingService {
  private static readonly RATES_TABLE = 'cf_fx_rates';
  private static readonly HEDGING_TABLE = 'cf_fx_hedging_orders';

  /**
   * 初始化数据库表
   */
  static async initTable() {
    const hasRatesTable = await db.schema.hasTable(this.RATES_TABLE);
    if (!hasRatesTable) {
      console.log(`📦 Creating ${this.RATES_TABLE} table...`);
      await db.schema.createTable(this.RATES_TABLE, (table) => {
        table.string('pair', 16).primary();
        table.decimal('rate', 10, 4);
        table.float('volatility').defaultTo(0.01);
        table.timestamp('last_updated').defaultTo(db.fn.now());
      });
    }

    const hasHedgingTable = await db.schema.hasTable(this.HEDGING_TABLE);
    if (!hasHedgingTable) {
      console.log(`📦 Creating ${this.HEDGING_TABLE} table...`);
      await db.schema.createTable(this.HEDGING_TABLE, (table) => {
        table.string('id', 64).primary();
        table.string('tenant_id', 64).index();
        table.string('pair', 16);
        table.decimal('amount', 15, 2);
        table.decimal('strike_rate', 10, 4);
        table.timestamp('expiry_date');
        table.string('status', 16).defaultTo('PENDING');
        table.string('trace_id', 64);
        table.timestamps(true, true);
      });
    }
  }

  /**
   * 获取当前动态安全边际 (BIZ_FIN_03)
   */
  static async getDynamicSafetyMargin(pair: string = 'USD/CNY'): Promise<number> {
    try {
      const rateInfo = await db(this.RATES_TABLE).where({ pair }).first();
      if (!rateInfo) return 0.03;
      const baseMargin = 0.02;
      const volatilityFactor = rateInfo.volatility * 0.5;
      return baseMargin + volatilityFactor;
    } catch (err: any) {
      return 0.03;
    }
  }

  /**
   * 自动生成对冲头寸 (BIZ_FIN_03)
   */
  static async autoHedge(params: {
    tenantId: string;
    pair: string;
    amount: number;
    traceId: string;
  }): Promise<string | null> {
    const { tenantId, pair, amount, traceId } = params;
    if (amount < 1000) return null;

    const rateInfo = await db(this.RATES_TABLE).where({ pair }).first();
    const strikeRate = rateInfo ? rateInfo.rate : 7.25;

    const hedgingId = `HEDGE-${Date.now()}`;
    await db(this.HEDGING_TABLE).insert({
      id: hedgingId,
      tenant_id: tenantId,
      pair,
      amount,
      strike_rate: strikeRate,
      expiry_date: new Date(Date.now() + 30 * 24 * 60 * 60 * 1000),
      status: 'PENDING',
      trace_id: traceId,
      created_at: new Date(),
      updated_at: new Date()
    });

    return hedgingId;
  }

  /**
   * 更新汇率快照
   */
  static async updateRates(pair: string, rate: number, volatility: number): Promise<void> {
    const existing = await db(this.RATES_TABLE).where({ pair }).first();
    if (existing) {
      await db(this.RATES_TABLE).where({ pair }).update({ rate, volatility, last_updated: new Date() });
    } else {
      await db(this.RATES_TABLE).insert({ pair, rate, volatility, last_updated: new Date() });
    }
  }

  /**
   * [BIZ_FIN_12] 锁汇申请
   */
  static async lockRate(tenantId: string, pair: string, amount: number, durationDays: number = 7): Promise<string> {
    const rateInfo = await db(this.RATES_TABLE).where({ pair }).first();
    if (!rateInfo) throw new Error(`Rate info not found for ${pair}`);

    const lockId = `LOCK-${Date.now()}`;
    await db(this.HEDGING_TABLE).insert({
      id: lockId,
      tenant_id: tenantId,
      pair,
      amount,
      strike_rate: rateInfo.rate,
      expiry_date: new Date(Date.now() + durationDays * 24 * 60 * 60 * 1000),
      status: 'PENDING',
      trace_id: `lock-${Date.now()}`,
      created_at: new Date(),
      updated_at: new Date()
    });

    return lockId;
  }

  /**
   * [BIZ_FIN_12] 计算汇率损益
   */
  static async calculateGainLoss(tenantId: string): Promise<{ totalGainLoss: number; details: any[] }> {
    const executedOrders = await db(this.HEDGING_TABLE).where({ tenant_id: tenantId, status: 'EXECUTED' });
    let totalGainLoss = 0;
    const details = [];

    for (const order of executedOrders) {
      const currentRateInfo = await db(this.RATES_TABLE).where({ pair: order.pair }).first();
      if (currentRateInfo) {
        const gainLoss = (order.strike_rate - currentRateInfo.rate) * order.amount;
        totalGainLoss += gainLoss;
        details.push({
          orderId: order.id,
          pair: order.pair,
          strikeRate: order.strike_rate,
          currentRate: currentRateInfo.rate,
          gainLoss: Number(gainLoss.toFixed(2))
        });
      }
    }
    return { totalGainLoss: Number(totalGainLoss.toFixed(2)), details };
  }

  /**
   * [BIZ_FIN_12] 自动执行到期的锁汇订单
   */
  static async executeMaturedOrders(tenantId: string) {
    logger.info(`[FX] Checking matured orders for Tenant: ${tenantId}`);
    const matured = await db(this.HEDGING_TABLE)
      .where({ tenant_id: tenantId, status: 'PENDING' })
      .andWhere('expiry_date', '<', new Date());

    for (const order of matured) {
      await db(this.HEDGING_TABLE).where({ id: order.id }).update({
        status: 'EXECUTED',
        updated_at: new Date()
      });
      logger.info(`[FX] Executed matured order ${order.id}`);
    }
  }

  /**
   * [BIZ_FIN_12] 实时汇率同步 (模拟多源获取)
   */
  static async syncRates() {
    const pairs = ['USD/CNY', 'EUR/USD', 'GBP/USD'];
    for (const pair of pairs) {
      const baseRate = pair === 'USD/CNY' ? 7.2 : 1.1;
      const rate = baseRate + (Math.random() - 0.5) * 0.1;
      const volatility = 0.01 + Math.random() * 0.05;
      await this.updateRates(pair, rate, volatility);
    }
    logger.info('[FX] Market rates synchronized.');
  }
}
