import { Router, Request, Response, NextFunction } from 'express';
import { authorize } from '../../core/guards/trace-context.guard';
import ArbitrageService from '../../services/ArbitrageService';
import { logger } from '../../utils/logger';

// 扩展Request类型
declare global {
  namespace Express {
    interface User {
      id: string;
      tenantId: string;
      role: string;
      email: string;
      [key: string]: any;
    }

    interface Request {
      user?: User;
    }
  }
}

const router = Router();

router.get('/opportunities', authorize(['arbitrage:read']), async (req, res) => {
  try {
    const tenantId = req.user?.tenantId;
    if (!tenantId) {
      return res.status(400).json({ success: false, message: 'Tenant ID required' });
    }

    const { status, platform, minScore, limit, offset } = req.query;

    const result = await ArbitrageService.getOpportunitiesByTenant(tenantId, {
      status: status as string,
      platform: platform as string,
      minScore: minScore ? parseInt(minScore as string) : undefined,
      limit: limit ? parseInt(limit as string) : 50,
      offset: offset ? parseInt(offset as string) : 0
    });

    res.json({ success: true, data: result });
  } catch (error) {
    logger.error('[ArbitrageRoute] Get opportunities error:', error);
    res.status(500).json({ success: false, message: 'Failed to get opportunities' });
  }
});

router.get('/opportunities/:id', authorize(['arbitrage:read']), async (req, res) => {
  try {
    const id = req.params.id as string;
    const opportunity = await ArbitrageService.getOpportunityById(id);

    if (!opportunity) {
      return res.status(404).json({ success: false, message: 'Opportunity not found' });
    }

    if (opportunity.tenant_id !== req.user?.tenantId) {
      return res.status(403).json({ success: false, message: 'Access denied' });
    }

    res.json({ success: true, data: opportunity });
  } catch (error) {
    logger.error('[ArbitrageRoute] Get opportunity error:', error);
    res.status(500).json({ success: false, message: 'Failed to get opportunity' });
  }
});

router.post('/opportunities', authorize(['arbitrage:create']), async (req, res) => {
  try {
    const tenantId = req.user?.tenantId;
    if (!tenantId) {
      return res.status(400).json({ success: false, message: 'Tenant ID required' });
    }

    const {
      productId,
      productName,
      sourcePlatform,
      sourceUrl,
      sourcePrice,
      sourceCurrency,
      targetPlatform,
      targetPrice,
      targetCurrency,
      logisticsCost,
      adBudget,
      isB2B,
      executionMode
    } = req.body;

    const opportunity = await ArbitrageService.createOpportunity(
      tenantId,
      productId,
      productName,
      sourcePlatform,
      sourceUrl,
      sourcePrice,
      sourceCurrency,
      targetPlatform,
      targetPrice,
      targetCurrency,
      {
        logisticsCost,
        adBudget,
        isB2B,
        executionMode
      }
    );

    res.json({ success: true, data: opportunity });
  } catch (error) {
    logger.error('[ArbitrageRoute] Create opportunity error:', error);
    res.status(500).json({ success: false, message: 'Failed to create opportunity' });
  }
});

router.post('/opportunities/:id/approve', authorize(['arbitrage:approve']), async (req, res) => {
  try {
    const id = req.params.id as string;
    const opportunity = await ArbitrageService.getOpportunityById(id);

    if (!opportunity) {
      return res.status(404).json({ success: false, message: 'Opportunity not found' });
    }

    if (opportunity.tenant_id !== req.user?.tenantId) {
      return res.status(403).json({ success: false, message: 'Access denied' });
    }

    const updated = await ArbitrageService.approveOpportunity(id);
    res.json({ success: true, data: updated });
  } catch (error) {
    logger.error('[ArbitrageRoute] Approve opportunity error:', error);
    res.status(500).json({ success: false, message: error instanceof Error ? error.message : 'Failed to approve opportunity' });
  }
});

router.post('/opportunities/:id/reject', authorize(['arbitrage:approve']), async (req, res) => {
  try {
    const id = req.params.id as string;
    const { reason } = req.body;

    const opportunity = await ArbitrageService.getOpportunityById(id);

    if (!opportunity) {
      return res.status(404).json({ success: false, message: 'Opportunity not found' });
    }

    if (opportunity.tenant_id !== req.user?.tenantId) {
      return res.status(403).json({ success: false, message: 'Access denied' });
    }

    await ArbitrageService.rejectOpportunity(id, reason);
    res.json({ success: true, message: 'Opportunity rejected' });
  } catch (error) {
    logger.error('[ArbitrageRoute] Reject opportunity error:', error);
    res.status(500).json({ success: false, message: 'Failed to reject opportunity' });
  }
});

router.post('/opportunities/:id/execute', authorize(['arbitrage:execute']), async (req, res) => {
  try {
    const id = req.params.id as string;
    const opportunity = await ArbitrageService.getOpportunityById(id);

    if (!opportunity) {
      return res.status(404).json({ success: false, message: 'Opportunity not found' });
    }

    if (opportunity.tenant_id !== req.user?.tenantId) {
      return res.status(403).json({ success: false, message: 'Access denied' });
    }

    const execution = await ArbitrageService.executeOpportunity(id);
    res.json({ success: true, data: execution });
  } catch (error) {
    logger.error('[ArbitrageRoute] Execute opportunity error:', error);
    res.status(500).json({ success: false, message: error instanceof Error ? error.message : 'Failed to execute opportunity' });
  }
});

router.get('/opportunities/:id/executions', authorize(['arbitrage:read']), async (req, res) => {
  try {
    const id = req.params.id as string;
    const executions = await ArbitrageService.getExecutionsByOpportunity(id);
    res.json({ success: true, data: executions });
  } catch (error) {
    logger.error('[ArbitrageRoute] Get executions error:', error);
    res.status(500).json({ success: false, message: 'Failed to get executions' });
  }
});

router.post('/scan', authorize(['arbitrage:create']), async (req, res) => {
  try {
    const tenantId = req.user?.tenantId;
    if (!tenantId) {
      return res.status(400).json({ success: false, message: 'Tenant ID required' });
    }

    const { productIds, sourcePlatform } = req.body;

    if (!productIds || !Array.isArray(productIds) || productIds.length === 0) {
      return res.status(400).json({ success: false, message: 'Product IDs required' });
    }

    const opportunities = await ArbitrageService.scanForOpportunities(
      tenantId,
      productIds,
      sourcePlatform || '1688'
    );

    res.json({ success: true, data: opportunities });
  } catch (error) {
    logger.error('[ArbitrageRoute] Scan error:', error);
    res.status(500).json({ success: false, message: 'Failed to scan for opportunities' });
  }
});

router.get('/stats', authorize(['arbitrage:read']), async (req, res) => {
  try {
    const tenantId = req.user?.tenantId;
    if (!tenantId) {
      return res.status(400).json({ success: false, message: 'Tenant ID required' });
    }

    const stats = await ArbitrageService.getArbitrageStats(tenantId);
    res.json({ success: true, data: stats });
  } catch (error) {
    logger.error('[ArbitrageRoute] Get stats error:', error);
    res.status(500).json({ success: false, message: 'Failed to get stats' });
  }
});

router.put('/executions/:id', authorize(['arbitrage:execute']), async (req, res) => {
  try {
    const id = req.params.id as string;
    const { status, purchaseOrderId, listingId, saleOrderId, actualPurchasePrice, actualSalePrice, actualProfit, notes } = req.body;

    const execution = await ArbitrageService.getExecutionById(id);
    if (!execution) {
      return res.status(404).json({ success: false, message: 'Execution not found' });
    }

    if (execution.tenant_id !== req.user?.tenantId) {
      return res.status(403).json({ success: false, message: 'Access denied' });
    }

    const updated = await ArbitrageService.updateExecutionStatus(id, status, {
      purchaseOrderId,
      listingId,
      saleOrderId,
      actualPurchasePrice,
      actualSalePrice,
      actualProfit,
      notes
    });

    res.json({ success: true, data: updated });
  } catch (error) {
    logger.error('[ArbitrageRoute] Update execution error:', error);
    res.status(500).json({ success: false, message: 'Failed to update execution' });
  }
});

export default router;
