package com.xisc.pm.infra.client;

import com.alibaba.fastjson.JSONObject;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.type.CollectionType;
import com.xisc.pm.api.dto.ObtainWitnessPointDTO;
import com.xisc.pm.api.dto.ObtainWitnessPointReturnDTO;
import com.xisc.pm.api.dto.PreOptimalChargingDTO;
import com.xisc.pm.api.dto.QdMatchParamDTO;
import com.xisc.pm.api.dto.QdSurplusLowMagnificationDTO;
import com.xisc.pm.domain.vo.QdOrderTechVO;
import com.xisc.pm.domain.vo.QdOrderVO;
import com.xisc.pm.infra.feign.QdOrderApiFeign;
import com.xisc.pm.infra.util.Utils;
import io.choerodon.core.exception.CommonException;
import io.choerodon.core.exception.ExceptionResponse;
import lombok.extern.slf4j.Slf4j;
import org.hzero.core.util.ResponseUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Component;

import javax.validation.ConstraintViolation;
import javax.validation.Validation;
import javax.validation.Validator;
import javax.validation.ValidatorFactory;
import java.util.List;
import java.util.Set;
import java.util.function.Function;

/**
 * 质量模块接口Client
 * @author jun.zeng
 *
 */
@Slf4j
@Component
public class QdOrderClient {

    @Autowired
    private QdOrderApiFeign qdOrderApiFeign;
    
    @Autowired
    private ObjectMapper objectMapper;

    @Autowired
    private QeApiClient qeApiClient;
    
    /**
     * 通过合同号查找合同主数据
     * @param tenantId
     * @param orderNoList
     * @return
     */
    public List<QdOrderVO> selectQdOrderByOrderNoList(Long tenantId , List<String> orderNoList){
        long start = System.currentTimeMillis();
        ResponseEntity<String> res = qdOrderApiFeign.orderApi(tenantId, orderNoList);
        log.debug("通过合同号查找合同主数据接口耗时：" +(System.currentTimeMillis() - start));
        return dealResponse(res, QdOrderVO.class , QdOrderVO::getOrderNo);
    }
    
    /**
     * 通过合同号，查询合同工艺参数信息
     * @param tenantId
     * @param orderNoList
     * @return
     */
    public List<QdOrderTechVO> selectQdOrderTechByOrderNoList(Long tenantId , List<String> orderNoList){
        long start = System.currentTimeMillis();
        ResponseEntity<String> res = qdOrderApiFeign.orderTechApi(tenantId, orderNoList);
        log.debug("通过合同号查询合同工艺参数信息接口耗时：" +(System.currentTimeMillis() - start));
        return dealResponse(res, QdOrderTechVO.class , item -> item.getOrderNo() + "-" + item.getMscLineNo());
    }
    
    /**
     * 处理响应结果
     * @param res
     * @param clazz
     * @return
     */
    public <T , R> List<T> dealResponse(ResponseEntity<String> res , Class<T> clazz , Function<T , R> fun){
        log.debug("调用QdOrderClient返回：" + res.getBody());
        if (ResponseUtils.isFailed(res)) {
            ExceptionResponse response = Utils.getExceptionResponse(res);
            throw new CommonException("pm.pm_call_qd_order_info_001",response.getMessage());
        }
        List<T> resultList = null ;
        try {
            
            ValidatorFactory factory = Validation.buildDefaultValidatorFactory();
            Validator validator = factory.getValidator();
            // 尝试将JSON字符串转换为实体列表
            CollectionType collectionType = objectMapper.getTypeFactory().constructCollectionType(List.class, clazz);
            resultList = objectMapper.readValue(res.getBody(), collectionType);
            for (T t : resultList) {
                Set<ConstraintViolation<T>> violations = validator.validate(t);
                if(!violations.isEmpty()) {
                    StringBuffer sb = new StringBuffer();
                    for (ConstraintViolation<T> violation : violations) {
                        sb.append(violation.getMessage()).append(";");
                    }
                    throw new CommonException("pm.pm_call_qd_order_info_003" ,fun.apply(t), sb.toString());
                }
            }
        } catch (CommonException e) {
            throw e ;
        } catch (Exception e) {
            log.error(String.format("解析返回参数失败：%s ", e.getMessage()));
            throw new CommonException("pm.pm_call_qd_order_info_002" , e.getMessage());
        }
        return resultList;
    }

    public List<PreOptimalChargingDTO> preOptimalChargingApi(Long organizationId, List<PreOptimalChargingDTO> dtoList) {
        log.debug("调用质量接口【preOptimalChargingApi】入参 tenantId：{}, dtoList = {}", organizationId, JSONObject.toJSON(dtoList));
        ResponseEntity<String> result = qdOrderApiFeign.preOptimalChargingApi(organizationId, dtoList);
        log.debug("调用质量接口【preOptimalChargingApi】返回：" + result.getBody());
        return qeApiClient.dealResponse(result, PreOptimalChargingDTO.class);
    }
    
    public List<QdMatchParamDTO> phyFurnaceChemicalMatchApi(Long organizationId, List<QdMatchParamDTO> dtoList) {
        log.debug("调用质量接口【phyFurnaceChemicalMatchApi】入参 tenantId：{}, dtoList = {}", organizationId, JSONObject.toJSON(dtoList));
        ResponseEntity<String> result = qdOrderApiFeign.phyFurnaceChemicalMatchApi(organizationId, dtoList);
        log.debug("调用质量接口【phyFurnaceChemicalMatchApi】返回：" + result.getBody());
        return qeApiClient.dealResponse(result, QdMatchParamDTO.class);
    }
    
    public List<QdSurplusLowMagnificationDTO> surplusLowMagnificationMatchApi(Long organizationId, List<QdSurplusLowMagnificationDTO> dtoList) {
        log.debug("调用质量接口【surplusLowMagnificationMatchApi】入参 tenantId：{}, dtoList = {}", organizationId, JSONObject.toJSON(dtoList));
        ResponseEntity<String> result = qdOrderApiFeign.surplusLowMagnificationMatchApi(organizationId, dtoList);
        log.debug("调用质量接口【surplusLowMagnificationMatchApi】返回：" + result.getBody());
        return qeApiClient.dealResponse(result, QdSurplusLowMagnificationDTO.class);
    }

    public List<ObtainWitnessPointReturnDTO> obtainWitnessPointApi(Long organizationId, List<ObtainWitnessPointDTO> dtoList) {
        log.debug("调用质量接口【obtainWitnessPointApi】入参 tenantId：{}, dtoList = {}", organizationId, JSONObject.toJSON(dtoList));
        ResponseEntity<String> result = qdOrderApiFeign.obtainWitnessPointApi(organizationId, dtoList);
        log.debug("调用质量接口【obtainWitnessPointApi】返回：" + result.getBody());
        return qeApiClient.dealResponse(result, ObtainWitnessPointReturnDTO.class);
    }
    
}
