package com.njcn.gather.err.service.impl;

import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.yulichang.wrapper.MPJLambdaWrapper;
import com.njcn.gather.detection.pojo.enums.DetectionCodeEnum;
import com.njcn.gather.err.mapper.PqErrSysDtlsMapper;
import com.njcn.gather.err.pojo.param.PqErrSysDtlsParam;
import com.njcn.gather.err.pojo.param.PqErrSysParam;
import com.njcn.gather.err.pojo.po.PqErrSysDtls;
import com.njcn.gather.err.pojo.vo.ErrDtlsCheckDataVO;
import com.njcn.gather.err.service.IPqErrSysDtlsService;
import com.njcn.gather.script.mapper.PqScriptMapper;
import com.njcn.gather.script.pojo.param.PqScriptCheckDataParam;
import com.njcn.gather.script.pojo.po.PqScriptCheckData;
import com.njcn.gather.script.service.IPqScriptCheckDataService;
import com.njcn.gather.system.dictionary.pojo.po.DictTree;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author caozehui
 * @date 2024-11-27
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class PqErrSysDtlsServiceImpl extends ServiceImpl<PqErrSysDtlsMapper, PqErrSysDtls> implements IPqErrSysDtlsService {

    private final IPqScriptCheckDataService pqScriptCheckDataService;
    private final PqScriptMapper pqScriptMapper;

    @Override
    public List<PqErrSysDtls> listPqErrSysDtlsByPqErrSysId(String pqErrSysId) {
        return this.lambdaQuery().eq(PqErrSysDtls::getErrorSysId, pqErrSysId).orderBy(true, true, PqErrSysDtls::getSort).list();
    }

    @Override
    @Transactional
    public boolean addPqErrSysDtls(String pqErrSysId, List<PqErrSysDtlsParam> list) {
        List<PqErrSysDtls> data = new ArrayList<>();
        for (PqErrSysDtlsParam param : list) {
            PqErrSysDtls pqErrSysDtls = new PqErrSysDtls();
            BeanUtils.copyProperties(param, pqErrSysDtls);
            pqErrSysDtls.setErrorSysId(pqErrSysId);
            data.add(pqErrSysDtls);
        }
        return this.saveBatch(data);
    }

    @Override
    @Transactional
    public boolean updatePqErrSysDtls(String pqErrSysId, List<PqErrSysDtlsParam> list) {
        //先按照pqErrSysId全部删除
        this.deletePqErrSysDtlsByPqErrSysId(Collections.singletonList(pqErrSysId));
        //再重新插入
        this.addPqErrSysDtls(pqErrSysId, list);
        return true;
    }

    @Override
    @Transactional
    public boolean deletePqErrSysDtlsByPqErrSysId(List<String> pqErrSysIds) {
        QueryWrapper<PqErrSysDtls> queryWrapper = new QueryWrapper<>();
        queryWrapper.in("pq_err_sys_dtls.Error_Sys_Id", pqErrSysIds);
        return this.remove(queryWrapper);
    }

    @Override
    public List<PqErrSysDtls> listPqErrSysDtlsByPqErrSysIdAndTypes(PqErrSysParam.DetectionParam param) {
        PqScriptCheckDataParam script = new PqScriptCheckDataParam();
        script.setScriptId(param.getScriptId());
        script.setIndex(param.getIndex());
        script.setIsValueTypeName(false);
        List<String> valueType = pqScriptCheckDataService.getValueType(script);
        //根据检测脚本id和检测序号，查询出检测子项目
        return this.list(new MPJLambdaWrapper<PqErrSysDtls>().selectAll(PqErrSysDtls.class)
                .selectAll(PqErrSysDtls.class)
                .selectAs(DictTree::getCode, PqErrSysDtls::getScriptCode)
                .leftJoin(DictTree.class, DictTree::getId, PqErrSysDtls::getScriptType)
                .eq(PqErrSysDtls::getErrorSysId, param.getErrorSysId())
                .in(PqErrSysDtls::getScriptType, valueType)
        );

    }

    @Override
    public List<ErrDtlsCheckDataVO> listByPqErrSysIdAndTypes(PqErrSysParam.DetectionParam param) {
        List<ErrDtlsCheckDataVO> info = new ArrayList<>();
        PqScriptCheckDataParam checkDataParam = new PqScriptCheckDataParam();
        checkDataParam.setScriptId(param.getScriptId());
        checkDataParam.setIndex(param.getIndex());
        //获取检测脚本中所有装置下发的测试项
        List<PqScriptCheckData> list = pqScriptCheckDataService.listCheckDataCode(checkDataParam);
        Boolean isValueType = pqScriptMapper.selectScriptIsValueType(param.getScriptId());

        Map<String, Integer> valueType = list.stream().collect(Collectors.toMap(PqScriptCheckData::getValueType, PqScriptCheckData::getErrorFlag,
                (key1, key2) -> key1));

        //获取误差体系
        Map<String, List<PqErrSysDtls>> errMap = new HashMap<>(3); //key为误差详情的ScriptType，value为List<PqErrSysDtls>
        if (CollUtil.isNotEmpty(valueType)) {
            List<PqErrSysDtls> errSysDtls = this.list(new MPJLambdaWrapper<PqErrSysDtls>().selectAll(PqErrSysDtls.class)
                    .selectAll(PqErrSysDtls.class)
                    .selectAs(DictTree::getCode, PqErrSysDtls::getScriptCode)
                    .leftJoin(DictTree.class, DictTree::getId, PqErrSysDtls::getScriptType)
                    .eq(PqErrSysDtls::getErrorSysId, param.getErrorSysId())
                    .in(PqErrSysDtls::getScriptType, valueType.keySet())
            );
            errMap = errSysDtls.stream().collect(Collectors.groupingBy(PqErrSysDtls::getScriptType));
        }
        ErrDtlsCheckDataVO dataVO;
        for (PqScriptCheckData script : list) {
            dataVO = new ErrDtlsCheckDataVO();
            dataVO.setCheckDataId(script.getScriptId());
            dataVO.setValueTypeCode(script.getValueTypeCode());
            dataVO.setValueType(script.getValueType());
            dataVO.setValue(script.getValue());
            dataVO.setPhase(script.getPhase());
            if (isValueType) {
                if (DetectionCodeEnum.VRMS.getCode().equals(script.getValueTypeCode())) {
                    BigDecimal volValue = new BigDecimal(script.getValue());
                    BigDecimal result = volValue.multiply(new BigDecimal(param.getUn().toString()))
                            .divide(new BigDecimal(100), 4, BigDecimal.ROUND_HALF_UP);
                    dataVO.setValue(result.doubleValue());
                }
                if (DetectionCodeEnum.IRMS.getCode().equals(script.getValueTypeCode())) {
                    BigDecimal volValue = new BigDecimal(script.getValue());
                    BigDecimal result = volValue.multiply(new BigDecimal(param.getIn().toString()))
                            .divide(new BigDecimal(100), 4, BigDecimal.ROUND_HALF_UP);
                    dataVO.setValue(result.doubleValue());
                }
            }
            if (valueType.containsKey(script.getValueType())) {
                //默认值4.无法处理 5.不参与误差比较
                Integer i = valueType.get(script.getValueType());
                if (i == 1) { //参与误差比较
                    dataVO.setIsQualified(4);
                    if (errMap.containsKey(script.getValueType())) {
                        dataVO.setErrSysDtls(errMap.get(script.getValueType()));
                    }
                } else { //不参与误差比较
                    dataVO.setIsQualified(5);
                }
            }
            info.add(dataVO);
        }
        return info;
    }

    @Override
    public List<PqErrSysDtls> listPqErrSysDtlsByPqErrSysIdAndScriptType(String errSysId, String scriptType) {
        MPJLambdaWrapper<PqErrSysDtls> wrapper = new MPJLambdaWrapper<>();
        wrapper.selectAll(PqErrSysDtls.class)
                .leftJoin(DictTree.class, DictTree::getId, PqErrSysDtls::getScriptType)
                .eq(PqErrSysDtls::getErrorSysId, errSysId)
                .eq(DictTree::getCode, scriptType);
        return this.list(wrapper);
    }
}
