package com.mvc.service.copy;

import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.mvc.constant.BaseConstant;
import com.mvc.dao.TChkrptDetailMapper;
import com.mvc.dao.TChkrptMapper;
import com.mvc.entity.TChkrpt;
import com.mvc.entity.TChkrptDetail;
import com.mvc.entity.TChkrptDetailExample;
import com.mvc.entity.TChkrptExample;
import com.mvc.model.*;
import com.mvc.service.dic.DicChkplatCellService;
import com.mvc.service.dic.DicChkplatService;
import com.mvc.service.taizhang.TaskBatchRemoteDetailService;
import com.mvc.utils.DateUtil;
import com.mvc.utils.StringUtil;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

//拷机报告主表服务类
@Service
@Transactional
public class TChkrptService {

    @Autowired(required = false)
    private TChkrptMapper tChkrptMapper;

    @Autowired(required = false)
    private TChkrptDetailMapper tChkrptDetailMapper;

    @Autowired
    private TCheckDetailService tCheckDetailService;

    @Autowired
    private DicChkplatService dicChkplatService;

    @Autowired
    private DicChkplatCellService dicChkplatCellService;

    @Autowired
    private TAireadService tAireadService;

    @Autowired
    private TCheckService tCheckService;

    @Autowired
    private TChkrptDetailService tChkrptDetailService;

    @Resource
    private TaskBatchRemoteDetailService taskBatchRemoteDetailService;

    @Resource
    private TServerReadService serverReadService;

    public Map<String, Object> findAllTChkrpt(TChkrptModel queryModel) {
        Map<String, Object> resMap = new HashMap<>();
        List<TChkrptModel> resList = new ArrayList<>();
        TChkrptExample example = new TChkrptExample();
        TChkrptExample.Criteria criteria = example.createCriteria();
        if (StringUtils.isNotEmpty(queryModel.getCheckMan())) {
            criteria.andCheckManEqualTo(queryModel.getCheckMan());
        }
        if (StringUtils.isNotEmpty(queryModel.getInvalidMan())) {
            criteria.andInvalidManLike("%" + queryModel.getInvalidMan() + "%");
        }
        if (StringUtils.isNotEmpty(queryModel.getCheckName())) {//按拷机计划名称查询(要先去拷机表中查询)
            List<TCheckModel> checkModels = tCheckService.findTCheckListByCheckName(queryModel.getCheckName());
            if (checkModels != null && checkModels.size() > 0) {
                List<String> ids = new ArrayList<>();
                for (TCheckModel checkModel : checkModels) {
                    ids.add(checkModel.getCheckId());
                }
                criteria.andCheckIdIn(ids);
            } else {
                resMap.put("total", 0);
                resMap.put("list", resList);
            }
        }
        if (StringUtils.isNotEmpty(queryModel.getQueryDeviceSn())) {//按设备SN查询(要先去报告明细中查询)
            List<String> ids = tChkrptDetailService.findChkrptIdsByDeviceSn(queryModel.getQueryDeviceSn());
            if (ids.size() > 0) {
                criteria.andChkrptIdIn(ids);
            } else {
                resMap.put("total", 0);
                resMap.put("list", resList);
            }
        }

        example.setOrderByClause(" CREATE_TIME desc");
        Page<Object> pageObject = PageHelper.startPage(queryModel.getPage(), queryModel.getRows());
        List<TChkrpt> TChkrpts = tChkrptMapper.selectByExample(example);

        for (TChkrpt TChkrpt : TChkrpts) {
            TChkrptModel model = new TChkrptModel();
            BeanUtils.copyProperties(TChkrpt, model);
            TCheckModel tcheck = tCheckService.findBycheckByIdWithOutMx(TChkrpt.getCheckId());
            model.setCheckName(tcheck.getCheckName());
            model.setStartTime(tcheck.getStartTime());
            model.setEndTime(tcheck.getEndTime());
            List<TChkrptDetailModel> chkrpdetails = findByChkrptId(model.getChkrptId());
            model.setDetailList(chkrpdetails);
            resList.add(model);
        }
        resMap.put("total", pageObject.getTotal());
        resMap.put("list", resList);
        return resMap;
    }

    public TChkrptModel saveTChkrpt(TChkrptModel model) {
        model.setChkrptId(StringUtil.getUuid());
        model.setCreateTime(new Date());
        TChkrpt TChkrpt = new TChkrpt();
        BeanUtils.copyProperties(model, TChkrpt);
        int insert = tChkrptMapper.insert(TChkrpt);
        model.setId(TChkrpt.getId());
        return model;
    }

    public TChkrptModel updateTChkrpt(TChkrptModel model) {
        TChkrpt tChkrpt = tChkrptMapper.selectByPrimaryKey(model.getId());
        if (StringUtils.isEmpty(tChkrpt.getInvalidMan()) || !model.getInvalidMan().equals(tChkrpt.getInvalidMan())) {
            model.setInvalidTime(new Date());
        }
        BeanUtils.copyProperties(model, tChkrpt);
        int i = tChkrptMapper.updateByPrimaryKey(tChkrpt);
        return model;
    }

    public int deleteTChkrpt(int id) {
        int i = tChkrptMapper.deleteByPrimaryKey(id);
        return i;
    }

    //根据chkrptId 查拷机报告明细
    public List<TChkrptDetailModel> findByChkrptId(String chkrptId) {
        List<TChkrptDetailModel> resList = new ArrayList<>();
        TChkrptDetailExample example = new TChkrptDetailExample();
        TChkrptDetailExample.Criteria criteria = example.createCriteria();
        criteria.andChkrptIdEqualTo(chkrptId);
        List<TChkrptDetail> tChkrptDetails = tChkrptDetailMapper.selectByExample(example);
        for (int i = 0; i < tChkrptDetails.size(); i++) {
            TChkrptDetailModel model = new TChkrptDetailModel();
            BeanUtils.copyProperties(tChkrptDetails.get(i), model);
            resList.add(model);
        }
        return resList;
    }

    //根据checkid查询拷机报告
    public TChkrptModel findTchkrptModelByCheckid(String checkid) {
        TChkrptExample example = new TChkrptExample();
        TChkrptExample.Criteria criteria = example.createCriteria();
        criteria.andCheckIdEqualTo(checkid);
        List<TChkrpt> tChkrpts = tChkrptMapper.selectByExample(example);
        if (tChkrpts.size() > 0) {
            TChkrptModel resModel = new TChkrptModel();
            BeanUtils.copyProperties(tChkrpts.get(0), resModel);
            return resModel;
        } else {
            return null;
        }
    }

    /**
     * 生成拷机报告
     *
     * @param checkId
     * @param username
     * @param isInDb   是否入库(不入库代表未拷机结束,是实时的报告)
     * @return
     */
    public TChkrptModel generateTChkrpt(String checkId, String username, Boolean isInDb) {
        //判断是否已经生成，如果已经生成，直接返回
        TChkrptModel tchkrptModel = findTchkrptModelByCheckid(checkId);
        if (tchkrptModel != null) {
            List<TChkrptDetailModel> chkrpdetails = findByChkrptId(tchkrptModel.getChkrptId());
            tchkrptModel.setDetailList(chkrpdetails);
            return tchkrptModel;//从null改为tchkrptModel(前台展示) 2022-11-07 guozhao
        }
        TCheckModel checkModel = tCheckService.findBycheckByIdWithOutMx(checkId);

        TChkrptModel resModel = new TChkrptModel();
        List<TCheckDetailModel> details = tCheckDetailService.findDetailsByCheckId(checkId);

        int nowyinshou = 0;
        int checkIntverl = checkModel.getCheckIntverl();
        int sencondsbetweenTime = DateUtil.getSencondsbetweenTime(checkModel.getStartTime(), new Date());
        Date queryEndTime = null;

        if (isInDb) {
            queryEndTime = DateUtil.getOtherDateByCurrentDate(checkModel.getStartTime(), checkModel.getCheckDays());
        } else if (checkModel.getEndTime() != null) {//特殊情况,一般调试下可能有,拷机结束了,但未生成报告
            queryEndTime = checkModel.getEndTime();
            sencondsbetweenTime = DateUtil.getSencondsbetweenTime(checkModel.getStartTime(), queryEndTime);
            nowyinshou = sencondsbetweenTime / 60 / checkIntverl;
        } else {
            queryEndTime = new Date();
            nowyinshou = sencondsbetweenTime / 60 / checkIntverl;
        }

        //生成报告主表
        TChkrpt tChkrpt = new TChkrpt();
        tChkrpt.setChkrptId(StringUtil.getUuid());
        tChkrpt.setCheckId(checkId);
        List<TChkrptDetailModel> tChkrptDetailModelList = new ArrayList<>();
        int qualnum = 0;
        int unqualnum = 0;
        for (int i = 0; i < details.size(); i++) {
            TCheckDetailModel detailModel = details.get(i);
            TChkrptDetail tChkrptDetail = new TChkrptDetail();
            tChkrptDetail.setDetailId(StringUtil.getUuid());
            tChkrptDetail.setChkrptId(tChkrpt.getChkrptId());
            tChkrptDetail.setCheckDetailId(detailModel.getDetailId());
            tChkrptDetail.setDeviceSn(detailModel.getDeviceSn());
            //工装名称+工位名称
            if (detailModel.getChkpaltId() != null && detailModel.getCellId() != null) {
                DicChkplatModel plat = dicChkplatService.findDicChkplatByPlatId(detailModel.getChkpaltId());
                DicChkplatCellModel cell = dicChkplatCellService.findCellModelbycellId(detailModel.getCellId());
                if (plat == null || cell == null) {
                    tChkrptDetail.setCheckPos("");
                } else {
                    tChkrptDetail.setCheckPos(plat.getPlatName() + "_" + cell.getCellName());
                }
            } else {
                tChkrptDetail.setCheckPos("");
            }
            queryEndTime = detailModel.getEndTime() == null ? queryEndTime : detailModel.getEndTime();
            List<TAireadModel> tairedList = tAireadService.findAllTaireadBySnAndTime(detailModel.getDeviceSn(), detailModel.getStartTime(), queryEndTime);
            //根据采样时间去重,在燃气表测试时,会有重发机制,但不能参与统计 2024-01-12 guozhao
            tairedList = tairedList.stream().collect(Collectors.collectingAndThen(
                    Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(TAireadModel::getSampleTime))),
                    ArrayList::new
            ));

            int correctnum = 0;
            int originalcorrectnum = 0;
            int xinhaohegenum = 0;
            int voltagenum = 0;
            int revallnum = detailModel.getRevAllNum();
            int neizhixinhaohegenum = 0;//内置信号合格数量

            int waizhishishounum = 0;//外置实收的数量
            int neizhishishounum = 0;//内置实收的数量

            int waizhiyingshounum = 0;//外置应收的数量
            int neizhiyingshounum = 0;//内置应收的数量

            Date switchTime = null;
            if (StringUtils.isNotEmpty(checkModel.getDelaySwitchBatchId())) {//已经切换过天线了
                TaskBatchRemoteDetailModel bModel = taskBatchRemoteDetailService.findTaskBatchRemoteDetailByBatchIdAndDeviceSn(checkModel.getDelaySwitchBatchId(), detailModel.getDeviceSn());
                if (bModel != null) {
                    switchTime = bModel.getFinishedTime();
                    tChkrptDetail.setSwitchAntennaTime(switchTime);
                }
            }

            if (checkModel.getDelaySwitchAntenna() == null) {//没有配置多少小时切换天线,默认外置 2023-03-16 guozhao
                waizhiyingshounum = isInDb ? detailModel.getRevAllNum() : nowyinshou;
            } else if (checkModel.getCheckDays() * 24 <= checkModel.getDelaySwitchAntenna()) {//切换小时超过总拷机时长了,代表不切天线
                if (checkModel.getDelaySwitchAntennaType().equals("0")) {//开始是内置
                    neizhiyingshounum = isInDb ? detailModel.getRevAllNum() : nowyinshou;
                } else {//开始是外置
                    waizhiyingshounum = isInDb ? detailModel.getRevAllNum() : nowyinshou;
                }
            } else {
                if (switchTime == null) {//计划切换,但还未切换成功
                    int jg = DateUtil.getSencondsbetweenTime(checkModel.getStartTime(), queryEndTime);
                    if (checkModel.getDelaySwitchAntennaType().equals("0")) {//开始是内置
                        neizhiyingshounum = jg / 60 / checkIntverl;
                    } else {//开始是外置
                        waizhiyingshounum = jg / 60 / checkIntverl;
                    }

                } else {//已经切换成功了
                    int jg = DateUtil.getSencondsbetweenTime(checkModel.getStartTime(), switchTime);
                    if (checkModel.getDelaySwitchAntennaType().equals("0")) {//开始是内置
                        neizhiyingshounum = jg / 60 / checkIntverl;
                        jg = DateUtil.getSencondsbetweenTime(switchTime, queryEndTime);
                        waizhiyingshounum = jg / 60 / checkIntverl;
                    } else {//开始是外置
                        waizhiyingshounum = jg / 60 / checkIntverl;
                        jg = DateUtil.getSencondsbetweenTime(switchTime, queryEndTime);
                        neizhiyingshounum = jg / 60 / checkIntverl;
                    }
                }
            }

            //由于后续出货MCU侧125版本未配置前不再识别,因此要使用服务器侧识别了
            Map<String, TServerReadModel> serverReadMap = serverReadService.queryTServerReadModelsByDeviceSnAndTime(detailModel.getDeviceSn(), detailModel.getStartTime(), queryEndTime);

            for (int j = 0; j < tairedList.size(); j++) {
                TAireadModel airm = tairedList.get(j);
                //注释:改为使用服务器识别结果判断 2025-07-11 guozhao
                /*if (airm.getRawValue() != null && airm.getRawValue().intValue() == detailModel.getStdValue()) {
                    originalcorrectnum++;
                }*/

                //注释:改为使用服务器识别结果判断 2025-07-11 guozhao
                if (serverReadMap.containsKey(airm.getAireadId()) && serverReadMap.get(airm.getAireadId()).getIdentValue() != null) {
                    TServerReadModel serverReadModel = serverReadMap.get(airm.getAireadId());
                    //说明:此处要判断是否是1278,从而排除服务器使用了前值的情况 2025-07-11 guozhao
                    if (serverReadModel.getIdentValue().intValue() == detailModel.getStdValue()) {
                        if (BaseConstant.IDENT_GOOD_FLAG.contains(serverReadModel.getGoodFlag())) {//符合1278
                            originalcorrectnum++;
                        }
                    }
                }

                if (airm.getIdentValue() != null && airm.getIdentValue().intValue() == detailModel.getStdValue()) {
                    correctnum++;
                }

                /** 根据要切换的天线类型来判断未切换前的状态 */
                //if (StringUtils.isNotEmpty(checkModel.getDelaySwitchAntennaType())) { //和上面判断条件不一样 2024-01-11 guozhao
                if (checkModel.getDelaySwitchAntenna() != null) {
                    if (checkModel.getDelaySwitchAntennaType().equals("0")) {//计划要切换到外置(开始是内置)
                        if (switchTime == null || airm.getSampleTime().compareTo(switchTime) < 1) {
                            if (airm.getCsq() != null && airm.getCsq().intValue() >= BaseConstant.CHECK_CSQ_MIN_QUALIFY) {
                                neizhixinhaohegenum++;
                            }
                            neizhishishounum++;
                        } else {
                            if (airm.getCsq() != null && airm.getCsq().intValue() >= BaseConstant.CHECK_CSQ_MIN_QUALIFY) {
                                xinhaohegenum++;
                            }
                            waizhishishounum++;
                        }
                    } else if (checkModel.getDelaySwitchAntennaType().equals("1")) {//计划要切换到内置(开始是外置)
                        if (switchTime == null || airm.getSampleTime().compareTo(switchTime) < 1) {
                            if (airm.getCsq() != null && airm.getCsq().intValue() >= BaseConstant.CHECK_CSQ_MIN_QUALIFY) {
                                xinhaohegenum++;
                            }
                            waizhishishounum++;
                        } else {
                            if (airm.getCsq() != null && airm.getCsq().intValue() >= BaseConstant.CHECK_CSQ_MIN_QUALIFY) {
                                neizhixinhaohegenum++;
                            }
                            neizhishishounum++;
                        }
                    }
                } else {//中途不切换天线(暂默认外置),此情况不应该有,前台可将切换时间配置成超长,走上面两个条件,此处前台操作时需要理解
                    if (airm.getCsq() != null && airm.getCsq().intValue() >= BaseConstant.CHECK_CSQ_MIN_QUALIFY) {
                        xinhaohegenum++;
                    }
                    waizhishishounum++;
                }

                if (checkModel != null && StringUtils.isNotEmpty(checkModel.getBatFlag()) && checkModel.getBatFlag().equals("1")) {//电池供电(暂以不低于3.5为标准)
                    //因为制定的规则不能用百分比还衡量了,后续要完善
                    if (airm.getVoltage() != null && airm.getVoltage().doubleValue() >= 3.5 && airm.getVoltage().doubleValue() <= 3.8) {        //3.6改为3.8 2022-08-29 guozhao
                        voltagenum++;
                    }
                } else {
                    if (airm.getVoltage() != null && airm.getVoltage().doubleValue() >= 3.3 && airm.getVoltage().doubleValue() <= 3.8) {        //3.6改为3.8 2022-08-29 guozhao
                        voltagenum++;
                    }
                }
            }
            //接收数据完整率
            if (waizhishishounum > 0 && waizhiyingshounum > 0) {//waizhiyingshounum > 0 待查 2024-01-11 guozhao
                tChkrptDetail.setRevIntegRate(new BigDecimal(waizhishishounum).divide(new BigDecimal(waizhiyingshounum), 2, BigDecimal.ROUND_HALF_UP).movePointRight(2));
            }
            if (neizhishishounum > 0 && neizhiyingshounum > 0) {//neizhiyingshounum > 0 待查 2024-01-11 guozhao
                tChkrptDetail.setInsideRevIntegRate(new BigDecimal(neizhishishounum).divide(new BigDecimal(neizhiyingshounum), 2, BigDecimal.ROUND_HALF_UP).movePointRight(2));
            }

            BigDecimal data_accuracy = null;
            BigDecimal originaldataAccuracy = null;
            BigDecimal xinhaohegelv = null;
            BigDecimal dianyahegelv = null;
            BigDecimal neizhixinhaohegelv = null;

            if (tairedList.size() == 0) {
                data_accuracy = new BigDecimal(0);
                originaldataAccuracy = new BigDecimal(0);
                xinhaohegelv = new BigDecimal(0);
                dianyahegelv = new BigDecimal(0);
            } else {
                data_accuracy = new BigDecimal(correctnum).divide(new BigDecimal(tairedList.size()), 2, BigDecimal.ROUND_HALF_UP);
                originaldataAccuracy = new BigDecimal(originalcorrectnum).divide(new BigDecimal(tairedList.size()), 2, BigDecimal.ROUND_HALF_UP);
                //xinhaohegelv = new BigDecimal(xinhaohegenum).divide(new BigDecimal(tairedList.size()), 2, BigDecimal.ROUND_HALF_UP);
                dianyahegelv = new BigDecimal(voltagenum).divide(new BigDecimal(tairedList.size()), 2, BigDecimal.ROUND_HALF_UP);

                if (waizhishishounum > 0) {
                    xinhaohegelv = new BigDecimal(xinhaohegenum).divide(new BigDecimal(waizhishishounum), 2, BigDecimal.ROUND_HALF_UP);
                }

                if (neizhishishounum > 0) {
                    neizhixinhaohegelv = new BigDecimal(neizhixinhaohegenum).divide(new BigDecimal(neizhishishounum), 2, BigDecimal.ROUND_HALF_UP);
                }

            }
            //识别准确率
            tChkrptDetail.setRecogAccuracy(originaldataAccuracy.movePointRight(2));
            //最终准确率
            tChkrptDetail.setFinalAccuracy(data_accuracy.movePointRight(2));
            //信号合格率
            if (xinhaohegelv != null) {
                tChkrptDetail.setRsrpQualRate(xinhaohegelv.movePointRight(2));
            }

            //内置天线-信号合格率
            if (neizhixinhaohegelv != null) {
                tChkrptDetail.setInsideRsrpQualRate(neizhixinhaohegelv.movePointRight(2));
            }

            //电压合格率
            tChkrptDetail.setVtQualRate(dianyahegelv.movePointRight(2));

            //tChkrptDetail.setSystemQualFlag("1");   系统判定都是1？ 2022-11-12 guozhao
            //判断最终是否合格  //tChkrptDetail.getRevIntegRate().intValue() >= 95 && //
            //去掉了最终准确性判断 && tChkrptDetail.getFinalAccuracy().intValue() >= 95 2025-07-17 guozhao
            if (tChkrptDetail.getRecogAccuracy().intValue() >= 95
                    && tChkrptDetail.getRsrpQualRate().intValue() >= 95 && tChkrptDetail.getVtQualRate().intValue() >= 95) {

                //分开判断内外置完整性是否合格 2022-12-27 guozhao
                boolean wzwz = waizhiyingshounum > 0 && tChkrptDetail.getRevIntegRate().intValue() > 95 || waizhiyingshounum == 0;
                boolean nzwz = neizhiyingshounum > 0 && tChkrptDetail.getInsideRevIntegRate().intValue() > 95 || neizhiyingshounum == 0;
                if (wzwz && nzwz) {
                    tChkrptDetail.setSystemQualFlag("1");
                    qualnum++;
                } else {
                    tChkrptDetail.setSystemQualFlag("0");
                    unqualnum++;
                }
                if (tChkrptDetail.getSystemQualFlag().equals("1") && neizhiyingshounum > 0 && tChkrptDetail.getInsideRsrpQualRate().intValue() < 95) {
                    tChkrptDetail.setSystemQualFlag("0");//内置完整性低于95%
                }

            } else {
                tChkrptDetail.setSystemQualFlag("0");
                unqualnum++;
            }
            tChkrptDetailMapper.insert(tChkrptDetail);
            TChkrptDetailModel tChkrptDetailModel = new TChkrptDetailModel();
            BeanUtils.copyProperties(tChkrptDetail, tChkrptDetailModel);
            tChkrptDetailModelList.add(tChkrptDetailModel);
        }
        tChkrpt.setCheckNum(tChkrptDetailModelList.size());
        tChkrpt.setCheckQualNum(qualnum);
        tChkrpt.setCheckUnqualNum(unqualnum);
        tChkrpt.setCreateTime(new Date());
        tChkrpt.setCreateMan(username);
        if (isInDb) {// 2022-11-07 guozhao
            tChkrptMapper.insert(tChkrpt);
        }
        BeanUtils.copyProperties(tChkrpt, resModel);
        resModel.setDetailList(tChkrptDetailModelList);
        return resModel;
    }
}
