package com.cf.imes.module.plan.service.orderImport.consumer;

import cn.hutool.core.util.ObjectUtil;
import com.baomidou.dynamic.datasource.annotation.DS;
import com.baomidou.dynamic.datasource.toolkit.DynamicDataSourceContextHolder;
import com.cf.imes.framework.common.exception.ServiceException;
import com.cf.imes.framework.id.core.util.SnowflakeIdWorker3rd;
import com.cf.imes.framework.mybatis.core.generator.SnowFlakeGenerator;
import com.cf.imes.framework.organ.core.context.OrganContextHolder;
import com.cf.imes.framework.redis.config.ChenfengCacheProperties;
import com.cf.imes.framework.redis.constants.RedisKeyConstants;
import com.cf.imes.framework.redis.util.RedisLockUtil;
import com.cf.imes.module.plan.dal.dataobject.orderImport.OrderImportTaskDO;
import com.cf.imes.module.plan.dal.mysql.goods.GoodsMapper;
import com.cf.imes.module.plan.dal.mysql.order.OrderMapper;
import com.cf.imes.module.plan.dal.mysql.orderBody.OrderBodyMapper;
import com.cf.imes.module.plan.dal.mysql.orderImport.OrderImportTaskMapper;
import com.cf.imes.module.plan.dal.mysql.plate.PlateMapper;
import com.cf.imes.module.plan.service.customplateno.CustomPlateNoGenerateService;
import com.cf.imes.module.plan.service.orderImport.OrderImportTaskService;
import com.cf.imes.module.plan.service.orderImport.factory.WebCadOrderImportAsyncFactory;
import com.cf.imes.module.plan.service.orderImport.property.WebCadImportProperties;
import com.cf.imes.module.system.api.assemblyconfig.AssemblyConfigApi;
import com.cf.imes.module.system.api.systemconfig.SystemConfigApi;
import com.rabbitmq.client.Channel;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.amqp.support.AmqpHeaders;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.messaging.handler.annotation.Header;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import org.thymeleaf.util.StringUtils;

import jakarta.annotation.Resource;


import static com.cf.imes.module.executor.enums.ErrorCodeConstants.ORDER_IMPORT_ORGAN_LOCK_ERROR;
import static com.cf.imes.module.plan.enums.ErrorCodeConstants.ORDER_IMPORT_FAIL;
import static com.cf.imes.module.plan.enums.ErrorCodeConstants.ORDER_IMPORT_ORGANID_NOT_EXISTS;
import static com.cf.imes.module.plan.enums.ErrorCodeConstants.WEBCAD_ORDER_IMPORT_PEEK_NOT_EXIST_ERROR;

/**
 * webcad拆单消费者
 *
 * @author Gqr
 * @since 2025/4/21 13:46
 */
@Component
@Slf4j
public class WebCadOrderImportConsumer {
    @Resource
    private OrderMapper orderMapper;

    @Resource
    private SnowFlakeGenerator snowFlakeGenerator;

    @Resource
    private OrderBodyMapper orderBodyMapper;

    @Resource
    private PlateMapper plateMapper;

    @Resource
    private SnowflakeIdWorker3rd idWorker;

    @Resource
    private CustomPlateNoGenerateService customPlateNoGenerateService;

    @Resource
    private RedisLockUtil redisLockUtil;

    @Resource
    private GoodsMapper goodsMapper;

    @Resource
    private SystemConfigApi systemConfigApi;

    @Resource
    private AssemblyConfigApi assemblyConfigApi;

    @Value("${chenfeng.plan.webcad.import.cadImportPlateNumThreshold:10000}")
    private int cadImportPlateNumThreshold;

    @Resource
    private JdbcTemplate jdbcTemplate;

    @Resource
    private OrderImportTaskMapper orderImportTaskMapper;

    @Resource
    private OrderImportTaskService orderImportTaskService;

    @Resource
    private WebCadImportProperties webCadImportProperties;

    @Resource
    private ChenfengCacheProperties chenfengCacheProperties;

    @RabbitListener(queues = "#{@orderImportWebCadQueueName}")
    @DS("imes_prod")
    @Transactional(rollbackFor = Exception.class)
    public void orderImport(String message,
                            Channel channel,
                            @Header(value = "peek", required = false) String peek,
                            @Header(AmqpHeaders.DELIVERY_TAG) long deliveryTag) throws Exception {
        log.info("====================【webcad异步拆单收到消息：{}】====================", message);

        Long organId = null;
        Long taskId = Long.parseLong(message);
        boolean lockResult = true;
        OrderImportTaskDO orderImportTaskDO = null;
        try {
            // 手动确认消息接收
            channel.basicAck(deliveryTag, false);

            organId = OrganContextHolder.getOrganId();
            if (ObjectUtil.isNull(organId)) {
                throw new ServiceException(ORDER_IMPORT_ORGANID_NOT_EXISTS);
            }

            if (StringUtils.isEmpty(peek)) {
                throw new ServiceException(WEBCAD_ORDER_IMPORT_PEEK_NOT_EXIST_ERROR);
            } else {
                DynamicDataSourceContextHolder.push(peek);
            }

            // 检查机构导入锁
            String importLockKey = String.format(RedisKeyConstants.ORDER_IMPORT_LOCK_KEY, organId);
            lockResult = redisLockUtil.acquireLock(importLockKey, String.valueOf(taskId), chenfengCacheProperties.getLockTimeout());
            if (!lockResult) {
                throw new ServiceException(ORDER_IMPORT_ORGAN_LOCK_ERROR);
            }

            // 确认任务，更新状态为消费成功，没有找到任务中断后续消费
            orderImportTaskDO = orderImportTaskService.confirmOrderImport(taskId);
            if (ObjectUtil.isNull(orderImportTaskDO)) {
                return;
            }

            log.info("====================【webcad异步拆单处理临时数据开始】====================");
            WebCadOrderImportAsyncFactory webCadOrderImportAsyncFactory =
                    new WebCadOrderImportAsyncFactory(organId, orderMapper, snowFlakeGenerator, orderBodyMapper, plateMapper, idWorker,
                            orderImportTaskMapper, goodsMapper, customPlateNoGenerateService, systemConfigApi, assemblyConfigApi, orderImportTaskDO.getCreator(),
                            cadImportPlateNumThreshold, jdbcTemplate);
            webCadOrderImportAsyncFactory.analyzeTempData(taskId, webCadImportProperties.getTempFilePath());
            log.info("====================【webcad异步拆单处理临时数据结束】====================");

        } catch (Exception e) {
            log.error(ORDER_IMPORT_FAIL.getMsg(), e);
            orderImportTaskService.updateImportTaskFail(orderImportTaskDO, e);
            throw e;
        } finally {
            if (lockResult) {
                // 导入锁解锁
                redisLockUtil.releaseLock(String.format(RedisKeyConstants.ORDER_IMPORT_LOCK_KEY, organId), message);
            }
        }
    }



}
