package com.cf.imes.module.executor.service.orderImport.handler.xml;

import com.cf.imes.framework.common.exception.ServiceException;
import com.cf.imes.framework.mq.rabbitmq.constant.RabbitMqConstants;
import com.cf.imes.framework.mybatis.core.generator.SnowFlakeGenerator;
import com.cf.imes.module.executor.controller.admin.order.vo.order.OrderImportAsyncReqVO;
import com.cf.imes.module.executor.dal.dataobject.orderImport.OrderImportTaskDO;
import com.cf.imes.module.executor.dal.mysql.orderImport.OrderImportTaskMapper;
import com.cf.imes.module.executor.dal.mysql.orderImport.OrderImportTempDataMapper;
import com.cf.imes.module.executor.dal.mysql.plate.PlateGoodMapper;
import com.cf.imes.module.executor.enums.OrderImportStatusEnum;
import com.cf.imes.module.executor.enums.OrderImportTaskStatusEnum;
import com.cf.imes.module.executor.enums.OrderImportTypeEnum;
import com.cf.imes.module.executor.service.order.OrderService;
import com.cf.imes.module.executor.util.fileConversion.admin.files.xml.DefaultOrderImportXmlParserHandler;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.core.MessageBuilder;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.support.TransactionSynchronization;
import org.springframework.transaction.support.TransactionSynchronizationManager;
import org.springframework.web.multipart.MultipartFile;

import jakarta.annotation.Resource;

import static com.cf.imes.module.executor.enums.ErrorCodeConstants.ORDER_IMPORT_FILE_ANALYZE_ERROR;

/**
 * @author Gqr
 * @since 2025/1/9 9:21
 */
@Service("defaultXmlOrderImportHandler")
@Slf4j
public class DefaultXmlOrderImportHandler implements AbstractXmlOrderImportHandler {
    @Resource
    private OrderImportTempDataMapper orderImportTempDataMapper;

    @Resource
    private OrderService orderService;

    @Resource
    private SnowFlakeGenerator snowFlakeGenerator;

    @Resource
    private OrderImportTaskMapper orderImportTaskMapper;

    @Resource
    private RabbitTemplate rabbitTemplate;

    @Resource
    private PlateGoodMapper plateGoodMapper;

    @Override
    public String getFactoryName() {
        return "default";
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void prepareAndConvert(OrderImportAsyncReqVO importAsyncReqVO, MultipartFile file) {
        // 创建任务
        Long taskId = createImportTask(file.getOriginalFilename());

        try {
            DefaultOrderImportXmlParserHandler defaultOrderImportXmlParserHandler = new DefaultOrderImportXmlParserHandler(orderImportTempDataMapper, orderService, snowFlakeGenerator, plateGoodMapper, importAsyncReqVO.getOrderId(), taskId);
            defaultOrderImportXmlParserHandler.analyzeFile(file);
        } catch (ServiceException sev) {
            throw sev;
        } catch (Exception e) {
            log.error(ORDER_IMPORT_FILE_ANALYZE_ERROR.getMsg(), e);
            throw new ServiceException(ORDER_IMPORT_FILE_ANALYZE_ERROR);
        }

        Message message = MessageBuilder
                .withBody(taskId.toString().getBytes())
                .setExpiration("60000")  // 设置消息级 TTL（60 秒）
                .build();
        //如果处于事务中，待事务提交成功了再执行后续操作，防止事务未提交完成导致消费端查不到数据
        if (TransactionSynchronizationManager.isActualTransactionActive()) {
            TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronization() {
                @Override
                public void afterCommit() {
                    // 数据库操作全部完成发送消息
                    rabbitTemplate.convertAndSend(RabbitMqConstants.ORDER_IMPORT_DEFAULT_XML_EXCHANGE, null, message);
                }
            });
        } else {
            // 数据库操作全部完成发送消息
            rabbitTemplate.convertAndSend(RabbitMqConstants.ORDER_IMPORT_DEFAULT_XML_EXCHANGE, null, message);
        }
    }

    /**
     * 创建导入任务
     *
     * @return taskId
     */
    private Long createImportTask(String fileName) {
        // 创建导入任务
        OrderImportTaskDO orderImportTaskDO = OrderImportTaskDO.builder()
                .id((Long) snowFlakeGenerator.nextId(null))
                .type(OrderImportTypeEnum.XML.getType())
                .importStatus(OrderImportStatusEnum.IMPORT_NOT_YET.getStatus())
                .status(OrderImportTaskStatusEnum.CREATE_NOT_CONSUME.getStatus())
                .fileName(fileName)
                .build();
        orderImportTaskMapper.insert(orderImportTaskDO);
        return orderImportTaskDO.getId();
    }
}
