import { Request, Response } from 'express';
import db from '../../config/database';
import { isValidSyncStatusTransition } from '../../core/guards/state-transition.guard';
import { AuditService } from '../../services/AuditService';

export class SyncController {
  /**
   * [UX_DEV_03] 接收插件端上报的 E2E 异常
   */
  static async reportAudit(req: Request, res: Response) {
    try {
      const { action, targetType, targetId, metadata } = req.body;
      const { tenantId, shopId, taskId, traceId, userId, roleCode } = (req as any).traceContext;

      await AuditService.log({
        tenantId,
        shopId,
        taskId,
        traceId,
        userId,
        roleCode,
        module: 'SYNC',
        action: action || 'AUDIT_REPORT',
        resourceType: targetType || 'sync',
        resourceId: targetId ? String(targetId) : undefined,
        result: 'success',
        source: 'extension',
        metadata,
      });
      res.json({ success: true });
    } catch (error: any) {
      res.status(500).json({ success: false, error: error.message });
    }
  }

  /**
   * 分发产品数据至全平台 (Mock 实现，实际应触发各平台发布 Worker)
   */
  static async distribute(req: Request, res: Response) {
    try {
      const { originalUrl, productData } = req.body;
      const { tenantId, shopId, taskId, traceId, userId, roleCode } = (req as any).traceContext;
      
      const platforms = ['Temu', 'TikTok', 'Shopee'];
      
      for (const platform of platforms) {
        const existing = await db('cf_sync_status')
          .where({ originalUrl, platform })
          .first();

        if (existing) {
          await db('cf_sync_status')
            .where({ id: existing.id })
            .update({
              status: 'pending',
              productData: JSON.stringify(productData || {}),
              updated_at: new Date()
            });
        } else {
          await db('cf_sync_status').insert({
            originalUrl,
            platform,
            status: 'pending',
            productData: JSON.stringify(productData || {}),
            created_at: new Date(),
            updated_at: new Date()
          });
        }
      }

      await AuditService.log({
        tenantId,
        shopId,
        taskId,
        traceId,
        userId,
        roleCode,
        module: 'SYNC',
        action: 'DISTRIBUTE',
        resourceType: 'sync',
        resourceId: String(originalUrl || ''),
        result: 'success',
        source: 'console',
      });
      res.json({ success: true, data: { triggered: true } });
    } catch (error: any) {
      res.status(500).json({ success: false, error: error.message });
    }
  }

  static async recordAction(req: Request, res: Response) {
    try {
      const { platform, action, status } = req.body;
      const { tenantId, shopId, taskId, traceId, userId, roleCode } = (req as any).traceContext;

      await AuditService.log({
        tenantId,
        shopId,
        taskId,
        traceId,
        userId,
        roleCode,
        module: 'SYNC',
        action: 'RECORD_ACTION',
        resourceType: 'sync_log',
        resourceId: platform,
        afterSnapshot: { action, status },
        result: 'success',
        source: 'console',
      });

      res.json({ success: true });
    } catch (error: any) {
      res.status(500).json({ success: false, error: error.message });
    }
  }

  /**
   * [FSM] 状态流转控制
   */
  static async updateStatus(req: Request, res: Response) {
    const { id } = req.params;
    const { status } = req.body;
    const { tenantId, shopId, taskId, traceId, userId } = (req as any).traceContext;

    try {
      const record = await db('cf_sync_status').where({ id }).first();
      if (!record) return res.status(404).json({ success: false, error: 'Sync record not found' });

      const previousStatus = record.status;
      const nextStatus = status;

      if (!isValidSyncStatusTransition(previousStatus, nextStatus)) {
        return res.status(400).json({ success: false, error: `Invalid sync status transition: ${previousStatus} -> ${nextStatus}` });
      }

      await db('cf_sync_status').where({ id }).update({ status: nextStatus, updated_at: new Date() });

      await AuditService.log({
        tenantId,
        shopId,
        taskId,
        traceId,
        userId,
        module: 'SYNC',
        action: 'UPDATE_SYNC_STATUS',
        resourceType: 'sync',
        resourceId: String(record.id),
        beforeSnapshot: { status: previousStatus },
        afterSnapshot: { status: nextStatus },
        result: 'success',
        source: 'node',
      });

      res.json({ success: true });
    } catch (err: any) {
      res.status(500).json({ success: false, error: err.message });
    }
  }
}
