package com.xisc.pm.app.service.impl;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.xisc.pm.api.dto.InterfaceReceiveDTO;
import com.xisc.pm.app.service.InterfaceReceiveExecuteService;
import com.xisc.pm.app.service.InterfaceReceiveService;
import com.xisc.pm.infra.annotations.InterfaceCode;
import io.choerodon.core.exception.CommonException;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.ListableBeanFactory;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * fileName: InterfaceReceiveServiceImpl
 * description: 二级接口接收
 * history:
 *
 * @author 张建元 jianyuan.zhang@hand-china.com
 * @version 1.0.0
 * @since 2024-08-27 16:01
 */
@Service
@Slf4j
public class InterfaceReceiveServiceImpl implements InterfaceReceiveService {

    /**
     * 用于存储运行策略模式服务的映射表。
     * 关键字为策略模式名称，对应的值为运行该策略模式的服务实例。
     * 这个映射表是静态的，确保在程序运行期间，策略模式服务的映射关系是持久的。
     */
    private static final Map<String, InterfaceReceiveExecuteService> EXECUTE_SERVICE_MAP = new ConcurrentHashMap<>();

    public InterfaceReceiveServiceImpl(ListableBeanFactory listableBeanFactory) {
        try {
            // 通过bean名称获取所有RunByPolicyModeService Bean
            Map<String, InterfaceReceiveExecuteService> beans =
                    listableBeanFactory.getBeansOfType(InterfaceReceiveExecuteService.class);
            beans.forEach((beanName, service) -> {
                InterfaceCode interfaceCode = AnnotationUtils.findAnnotation(service.getClass(), InterfaceCode.class);
                if (interfaceCode != null) {
                    EXECUTE_SERVICE_MAP.put(interfaceCode.code(), service);
                }
            });
        } catch (Exception e) {
            log.error(e.getMessage(), e);
        }
    }

    /**
     * 二级接口接收
     *
     * @param tenantId 租户ID
     * @param dto      二级接口数据格式
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void receiveInterface(Long tenantId, InterfaceReceiveDTO dto) {
        if (dto == null) {
            throw new CommonException("二级接口接收数据不能为空");
        }
        if (StringUtils.isBlank(dto.getInterfaceCode())) {
            throw new CommonException("二级接口电文号不能为空");
        }
        if (CollectionUtils.isEmpty(dto.getInterfaceData())) {
            throw new CommonException("二级接口电文数据不能为空");
        }
        InterfaceReceiveExecuteService executeService = EXECUTE_SERVICE_MAP.get(dto.getInterfaceCode());
        String interfaceData;
        // 创建 ObjectMapper 实例用于序列化数据
        ObjectMapper mapper = new ObjectMapper();
        try {
            // 将数据序列化为 JSON 字符串
            interfaceData = mapper.writeValueAsString(dto.getInterfaceData());
        } catch (JsonProcessingException e) {
            // 如果序列化过程中发生异常，则抛出通用异常
            throw new CommonException(e);
        }
        executeService.execute(tenantId, dto.getInterfaceCode(), interfaceData);
    }
}
