import { NextFunction, Request, Response } from 'express';
import { z } from 'zod';
import { PricingService, PricingParams } from '../../services/PricingService';
import { FinanceService } from '../../services/FinanceService';
import { FXHedgingService } from '../../services/FXHedgingService';
import { AuditService } from '../../services/AuditService';
import { ArbitrageService } from '../../domains/Arbitrage/ArbitrageService';

export class PricingController {
  /**
   * [BIZ_FIN_12] 锁汇接口
   */
  static async lockRate(req: Request, res: Response, next: NextFunction) {
    try {
      const { tenantId } = (req as any).traceContext;
      const { pair, amount, durationDays } = req.body;
      const lockId = await FXHedgingService.lockRate(tenantId, pair, amount, durationDays);
      res.json({ success: true, data: { lockId } });
    } catch (err) {
      next(err);
    }
  }

  /**
   * [BIZ_FIN_12] 汇率损益查询接口
   */
  static async getFXGainLoss(req: Request, res: Response, next: NextFunction) {
    try {
      const { tenantId } = (req as any).traceContext;
      const data = await FXHedgingService.calculateGainLoss(tenantId);
      res.json({ success: true, data });
    } catch (err) {
      next(err);
    }
  }

  /**
   * [BIZ_ARB_01] 统一净利测算接口
   */
  static async calculate(req: Request, res: Response, next: NextFunction) {
    try {
      const bodySchema = z.object({
        sellingPrice: z.number(),
        purchasePrice: z.number(),
        platform: z.string(),
        countryCode: z.string().optional().default('US'),
        logisticsCost: z.number().optional().default(5.0),
        adBudget: z.number().optional().default(0),
        isB2B: z.boolean().optional().default(false),
        sourceUrl: z.string().optional(),
      });

      const params = bodySchema.parse(req.body);
      const { tenantId, shopId, taskId, traceId, userId } = (req as any).traceContext;

      // 1. 调用 ArbitrageService 进行深度分析
      const opportunity = await ArbitrageService.analyzeOpportunity(params as PricingParams, params.sourceUrl || 'direct');

      // 2. 记录套利发现
      if (params.sourceUrl) {
        await ArbitrageService.recordOpportunity(tenantId, opportunity);
      }

      // 3. 记录审计日志
      await AuditService.log({
        tenantId,
        shopId,
        taskId,
        traceId,
        userId,
        module: 'FINANCE',
        action: 'CALCULATE_PROFIT',
        resourceType: 'pricing',
        resourceId: params.platform,
        afterSnapshot: { params, opportunity },
        result: opportunity.riskLevel === 'BLOCK' ? 'failed' : 'success',
        source: 'console'
      });

      if (opportunity.riskLevel === 'BLOCK') {
        return res.status(400).json({
          success: false,
          error: 'Profit margin too low, arbitrage blocked.',
          data: opportunity
        });
      }

      res.json({
        success: true,
        data: opportunity
      });
    } catch (err: any) {
      if (err instanceof z.ZodError) {
        return res.status(400).json({ success: false, error: err.issues[0].message });
      }
      next(err);
    }
  }

  /**
   * [BIZ_FIN_01] 订单财务对账接口
   */
  static async reconcile(req: Request, res: Response, next: NextFunction) {
    try {
      const orderId = String(req.params.orderId);
      const { tenantId, shopId, taskId, traceId, userId } = (req as any).traceContext;

      const result = await FinanceService.reconcileOrder(orderId);
      
      await AuditService.log({
        tenantId,
        shopId,
        taskId,
        traceId,
        userId,
        module: 'FINANCE',
        action: 'RECONCILE_ORDER',
        resourceType: 'order',
        resourceId: orderId,
        afterSnapshot: result,
        result: 'success',
        source: 'console'
      });

      res.json({
        success: true,
        data: result
      });
    } catch (err: any) {
      next(err);
    }
  }

  /**
   * [BIZ_FIN_01] 账单回放接口
   */
  static async getPlayback(req: Request, res: Response, next: NextFunction) {
    try {
      const { orderId } = req.query;
      const { tenantId, shopId, taskId, traceId, userId } = (req as any).traceContext;

      if (!orderId) {
        return res.status(400).json({ success: false, error: 'Missing orderId' });
      }

      const result = await FinanceService.getBillPlayback(
        tenantId,
        shopId || '',
        orderId as string
      );

      await AuditService.log({
        tenantId,
        shopId,
        taskId,
        traceId,
        userId,
        module: 'FINANCE',
        action: 'GET_BILL_PLAYBACK',
        resourceType: 'order',
        resourceId: orderId as string,
        result: 'success',
        source: 'console'
      });

      res.json({
        success: true,
        data: result
      });
    } catch (err: any) {
      next(err);
    }
  }
}
