package com.steerinfo.meterwork.meterworkcarnoidentify.service.impl;

import com.steerinfo.baseinfo.meterbaseoperationlog.mapper.MeterBaseOperationLogMapper;
import com.steerinfo.baseinfo.meterbaseoperationlog.model.MeterBaseOperationLog;
import com.steerinfo.baseinfo.meterbasespotinfo.mapper.MeterBaseSpotInfoMapper;
import com.steerinfo.baseinfo.meterbasespotinfo.model.MeterBaseSpotInfo;
import com.steerinfo.framework.mapper.IBaseMapper;
import com.steerinfo.framework.service.impl.BaseServiceImpl;
import com.steerinfo.framework.service.pagehelper.PageHelper;
import com.steerinfo.framework.service.pagehelper.PageList;
import com.steerinfo.meterwork.meterworkcarmetertime.model.PointDetailsBo;
import com.steerinfo.meterwork.meterworkcarnoidentify.model.CarNoIndentifyAndCarFirst;
import com.steerinfo.meterwork.meterworkcarnoidentify.model.GroupByNumVo;
import com.steerinfo.meterwork.meterworkcarnoidentify.model.MeterWorkCarnoIdentify;
import com.steerinfo.meterwork.meterworkcarnoidentify.mapper.MeterWorkCarnoIdentifyMapper;
import com.steerinfo.meterwork.meterworkcarnoidentify.model.PointDetailsVo;
import com.steerinfo.meterwork.meterworkcarnoidentify.service.IMeterWorkCarnoIdentifyService;
import com.steerinfo.util.StringUtils;
import org.apache.shiro.crypto.hash.Hash;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

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

import static java.lang.Math.abs;

/**
 * MeterWorkCarnoIdentify服务实现：
 * @author generator
 * @version 1.0-SNAPSHORT 2022-10-12 04:48
 * 类描述
 * 修订历史：
 * 日期：2022-10-12
 * 作者：generator
 * 参考：
 * 描述：MeterWorkCarnoIdentify服务实现
 * @see null
 * @Copyright 湖南视拓信息技术股份有限公司. All rights reserved.
 */
@Service(value = "meterWorkCarnoIdentifyService")
public class MeterWorkCarnoIdentifyServiceImpl extends BaseServiceImpl<MeterWorkCarnoIdentify, String> implements IMeterWorkCarnoIdentifyService {

    @Resource
    private MeterWorkCarnoIdentifyMapper meterWorkCarnoIdentifyMapper;

    @Resource
    private MeterBaseSpotInfoMapper meterBaseSpotInfoMapper;

    @Resource
    private MeterBaseOperationLogMapper meterBaseOperationLogMapper;

    @Override
    protected IBaseMapper<MeterWorkCarnoIdentify, String> getMapper() {
        return meterWorkCarnoIdentifyMapper;
    }

    @Override
    public List<GroupByNumVo> getGroupByNum(HashMap meterWorkCarnoIdentify) {
        return meterWorkCarnoIdentifyMapper.selectGroupByNum(meterWorkCarnoIdentify);

    }

    @Override
    public List<HashMap> getGroupByCarNoNum(HashMap params) {
        List<HashMap> mapList = new ArrayList<>();
        //汽车衡类型
        params.put("spotTypeNo", "001002001");
        //车号根据实绩ID左连接一次数据表
        List<CarNoIndentifyAndCarFirst> models = meterWorkCarnoIdentifyMapper.selectGroupByCarNoNum(params);
        List<HashMap> logModels = meterBaseOperationLogMapper.countWebResetCar(params);

        List<MeterBaseSpotInfo> spotModels = meterBaseSpotInfoMapper.spotInfoByList(params);
        if(spotModels.size() >= 1) {
            for(MeterBaseSpotInfo spot: spotModels) {
                //一次计量车数
                long countCarFirst = 0L;
                //车号识别率=(一次计量车数-（大厅修正车号数+Web修正车号数）)/一次计量车数
                double countCarIdentifyRate = 0;
                //枪机车号使用数
                long countGunUsedIdentify = 0L;
                //球机车号使用数
                long countBallUsedIdentify = 0L;
                //扫码车号使用数
                long countScanCarIdentify = 0L;
                //扫码车号计量比例=扫码车号使用数/一次计量车数
                double countScanCarIdentifyRate = 0;
                //球机车号识别数
                long countBallIdentify = 0L;
                //球机车号未识别数
                long countBallIdentifyTemp = 0L;
                long countBallIdentifyTemp02 = 0L;
                //枪机车号识别数
                long countGunIdentify = 0L;
                //枪机车号未识别数
                long countGunIdentifyTemp = 0L;
                long countGunIdentifyTemp02 = 0L;
                //视觉识别数
                long countVisualIdentify = 0L;
                //视觉未识别数
                long countVisualIdentifyTemp = 0L;
                //视觉识别率
                double countVisualIdentifyRate = 0;
                //枪机球机识别差异数
                long countBallDifferGun = 0L;
                //Rfid车号未识别数
                long countRfidIdentify = 0L;
                //大厅修正车号数
                long countResetCar = 0L;
                //Web修正车号数
                long countWebResetCar = 0L;
                //枪机修改车号数
                long countGunResetCar = 0L;
                //球机修改车号数
                long countBallResetCar = 0L;
                //枪机车号识别率
                double countGunIndentifyRate = 0;
                //枪机识别准确率
                double countGunIndentifyAccuracyRate = 0;
                //球机车号识别率
                double countBallIndentifyRate = 0;
                //球机识别准确率
                double countBallIndentifyAccuracyRate = 0;
                if(models != null && models.size() >= 1) {
                    //一次计量车数
                    countCarFirst = models.stream().filter(model -> model.getBaseSpotNo().equals(spot.getBaseSpotNo())
                            && model.getBaseSpotName().equals(spot.getBaseSpotName())).count();
                    //Rfid车号识别数
                    countRfidIdentify = models.stream().filter(model -> model.getBaseSpotNo().equals(spot.getBaseSpotNo())
                            && model.getBaseSpotName().equals(spot.getBaseSpotName())
                            && model.getCarNoType().equals("2")
                            && StringUtils.isNotEmpty(model.getRfidCarNo())).count();
                    //枪机车号使用数
                    countGunUsedIdentify = models.stream().filter(model -> model.getBaseSpotNo().equals(spot.getBaseSpotNo())
                            && model.getBaseSpotName().equals(spot.getBaseSpotName())
                            && model.getCarNoType().equals("1")
                            && StringUtils.isNotEmpty(model.getVideoCarNo2())
                            && model.getVideoCarNo2().equals(model.getFirstCarNo())).count();
                    //球机车号使用数 - 枪机和球机同时等于一次车号识别数
                    countBallUsedIdentify = models.stream().filter(model -> model.getBaseSpotNo().equals(spot.getBaseSpotNo())
                            && model.getBaseSpotName().equals(spot.getBaseSpotName())
                            && model.getCarNoType().equals("1")
                            && StringUtils.isNotEmpty(model.getVideoCarNo1())
                            && model.getVideoCarNo1().equals(model.getFirstCarNo())).count()
                            - models.stream().filter(model -> model.getBaseSpotNo().equals(spot.getBaseSpotNo())
                                && model.getBaseSpotName().equals(spot.getBaseSpotName())
                                && model.getCarNoType().equals("1")
                                && StringUtils.isNotEmpty(model.getVideoCarNo1())
                                && StringUtils.isNotEmpty(model.getVideoCarNo2())
                                && model.getVideoCarNo1().equals(model.getFirstCarNo())
                                && model.getVideoCarNo2().equals(model.getFirstCarNo())).count();
                    //扫码车号识别数
                    countScanCarIdentify = models.stream().filter(model -> model.getBaseSpotNo().equals(spot.getBaseSpotNo())
                            && model.getBaseSpotName().equals(spot.getBaseSpotName())
                            && StringUtils.isNotEmpty(model.getScanCarNo())
                            && model.getScanCarNo().equals(model.getCarNo())).count();
                    //扫码车号计量比例=扫码车号使用数/一次计量车数
                    if(countCarFirst != 0) {
                        countScanCarIdentifyRate = Math.round((countScanCarIdentify/(countCarFirst*1.0))*100*100)/100.0;
                    }
                    //球机车号识别数
                    countBallIdentify = models.stream().filter(model -> model.getBaseSpotNo().equals(spot.getBaseSpotNo())
                            && model.getBaseSpotName().equals(spot.getBaseSpotName())
                            && StringUtils.isNotEmpty(model.getVideoCarNo1())).count();
                    //球机车号未识别数
                    countBallIdentifyTemp = models.stream().filter(model -> model.getBaseSpotNo().equals(spot.getBaseSpotNo())
                            && model.getBaseSpotName().equals(spot.getBaseSpotName())
                            && (StringUtils.isEmpty(model.getVideoCarNo1())
                            ||  (model.getCarNoType().equals("2")
                            && StringUtils.isNotEmpty(model.getRfidCarNo())))).count()-countRfidIdentify;
                    countBallIdentifyTemp02 = models.stream().filter(model -> model.getBaseSpotNo().equals(spot.getBaseSpotNo())
                            && model.getBaseSpotName().equals(spot.getBaseSpotName())
                            && (StringUtils.isEmpty(model.getVideoCarNo1()))).count();
                    //枪机车号识别数
                    countGunIdentify = models.stream().filter(model -> model.getBaseSpotNo().equals(spot.getBaseSpotNo())
                            && model.getBaseSpotName().equals(spot.getBaseSpotName())
                            && StringUtils.isNotEmpty(model.getVideoCarNo2())).count();
                    //枪机车号未识别数
                    countGunIdentifyTemp = models.stream().filter(model -> model.getBaseSpotNo().equals(spot.getBaseSpotNo())
                            && model.getBaseSpotName().equals(spot.getBaseSpotName())
                            && (StringUtils.isEmpty(model.getVideoCarNo2())
                            ||  (model.getCarNoType().equals("2")
                            && StringUtils.isNotEmpty(model.getRfidCarNo())))).count()-countRfidIdentify;
                    countGunIdentifyTemp02 = models.stream().filter(model -> model.getBaseSpotNo().equals(spot.getBaseSpotNo())
                            && model.getBaseSpotName().equals(spot.getBaseSpotName())
                            && StringUtils.isEmpty(model.getVideoCarNo2())).count();
                    //视觉识别数
                    countVisualIdentify = models.stream().filter(model -> model.getBaseSpotNo().equals(spot.getBaseSpotNo())
                            && model.getBaseSpotName().equals(spot.getBaseSpotName())
                            && (    (
                                        StringUtils.isNotEmpty(model.getVideoCarNo1())
                                        && StringUtils.isNotEmpty(model.getVideoCarNo2())
                                        && model.getVideoCarNo1().equals(model.getVideoCarNo2()
                                    ) ||
                                    (StringUtils.isNotEmpty(model.getVideoCarNo1()) || StringUtils.isNotEmpty(model.getVideoCarNo2())
                                    )))).count();
                    //视觉未识别数
                    countVisualIdentifyTemp = models.stream().filter(model -> model.getBaseSpotNo().equals(spot.getBaseSpotNo())
                            && model.getBaseSpotName().equals(spot.getBaseSpotName())
                            && !(
                                    (
                                        StringUtils.isNotEmpty(model.getVideoCarNo1())
                                        && StringUtils.isNotEmpty(model.getVideoCarNo2())
                                        && model.getVideoCarNo1().equals(model.getVideoCarNo2())
                                                || (StringUtils.isNotEmpty(model.getVideoCarNo1()) || StringUtils.isNotEmpty(model.getVideoCarNo2()))
                                    ||( model.getCarNoType().equals("2") && StringUtils.isNotEmpty(model.getRfidCarNo()))))).count();
                    //视觉识别率
                    if(countVisualIdentify != 0) {
                        countVisualIdentifyRate = Math.round(((countCarFirst-countRfidIdentify)-countVisualIdentifyTemp)/((countCarFirst-countRfidIdentify)*1.0)*100*100)/100.0; //(Math.round((*100))/100.0;
                    }
                    //枪机球机识别差异数
                    countBallDifferGun = models.stream().filter(model -> model.getBaseSpotNo().equals(spot.getBaseSpotNo())
                            && model.getBaseSpotName().equals(spot.getBaseSpotName())
                            && StringUtils.isNotEmpty(model.getVideoCarNo1())
                            && StringUtils.isNotEmpty(model.getVideoCarNo2())
                            && !model.getVideoCarNo1().equals(model.getVideoCarNo2())).count();

                    //大厅修正车号数
                    countResetCar = models.stream().filter(model -> model.getBaseSpotNo().equals(spot.getBaseSpotNo())
                            && model.getBaseSpotName().equals(spot.getBaseSpotName())
                            && model.getCarNoType().equals("4")).count();
                    //Web修正车号数
                    if(logModels.size() >= 1) {
                        countWebResetCar = logModels.stream().filter(model -> spot.getBaseSpotNo().equals(model.get("BASESPOTNO"))
                            && spot.getBaseSpotName().equals(model.get("BASESPOTNAME"))).count();
                    }
                    //车号识别率=(一次计量车数-（大厅修正车号数+Web修正车号数）)/一次计量车数
                    if(countCarFirst != 0) {
                        countCarIdentifyRate = Math.round(((countCarFirst-(countResetCar+countWebResetCar))/(countCarFirst*1.0))*100*100)/100.0;
                    }
                    //枪机修改车号数
                    countGunResetCar = models.stream().filter(model -> model.getBaseSpotNo().equals(spot.getBaseSpotNo())
                            && model.getBaseSpotName().equals(spot.getBaseSpotName())
                            && StringUtils.isNotEmpty(model.getVideoCarNo2())
                            && !model.getVideoCarNo2().equals(model.getFirstCarNo()) ).count();
                    //球机修改车号数
                    countBallResetCar = models.stream().filter(model -> model.getBaseSpotNo().equals(spot.getBaseSpotNo())
                            && model.getBaseSpotName().equals(spot.getBaseSpotName())
                            && StringUtils.isNotEmpty(model.getVideoCarNo1())
                            && !model.getVideoCarNo1().equals(model.getFirstCarNo()) ).count();
                    //枪机车号识别率------枪机车号识别数/一次计量车数
                    if((countCarFirst-countRfidIdentify)-countGunIdentifyTemp <= (countCarFirst-countRfidIdentify)) {
                        countGunIndentifyRate = Math.round(((countCarFirst-countRfidIdentify)-countGunIdentifyTemp)/((countCarFirst-countRfidIdentify)*1.0)*100*100)/100.0; //(Math.round(*100))/100.0;
                    }else {
                        countGunIndentifyRate = Math.round(((countCarFirst-countRfidIdentify)-countGunIdentifyTemp02)/((countCarFirst-countRfidIdentify)*1.0)*100*100)/100.0; //(Math.round(*100))/100.0;
                    }
                    //枪机识别准确率------（枪机识别车号数-枪机识别错误修正数）/枪机识别车号数c
                    if(countGunIdentify != 0) {
                        countGunIndentifyAccuracyRate = Math.round((countGunIdentify-countGunResetCar)/(countGunIdentify*1.0)*100*100)/100.0; //(Math.round((*100))/100.0;
                    }
                    //球机车号识别率
                    if(((countCarFirst-countRfidIdentify)-countBallIdentifyTemp) <= (countCarFirst-countRfidIdentify)) {
                        countBallIndentifyRate = Math.round(((countCarFirst-countRfidIdentify)-countBallIdentifyTemp)/((countCarFirst-countRfidIdentify)*1.0)*100*100)/100.0; //(Math.round(*100))/100.0;
                    }else {
                        countBallIndentifyRate = Math.round(((countCarFirst-countRfidIdentify)-countBallIdentifyTemp02)/((countCarFirst-countRfidIdentify)*1.0)*100*100)/100.0; //(Math.round(*100))/100.0;
                    }
                    //球机识别准确率
                    if(countBallIdentify != 0) {
                        countBallIndentifyAccuracyRate = Math.round((countBallIdentify-countBallResetCar)/(countBallIdentify*1.0)*100*100)/100.0; //(Math.round((*100))/100.0;
                    }

                    HashMap<String, Object> obj = new HashMap<>();
                    //一次计量车数、球机车号识别数、枪机车号识别数、枪机球机识别差数、Rfid车号识别数、
                    // 修正车号数、枪机修改车号数、球机修改车号数、枪机车号识别率、枪机识别准确率、球机车号识别率、球机识别准确率
                    obj.put("spotNo", spot.getBaseSpotNo());
                    obj.put("spotName", spot.getBaseSpotName());
                    obj.put("countCarFirst", countCarFirst);
                    obj.put("countGunUsedIdentify", countGunUsedIdentify);
                    obj.put("countBallUsedIdentify", countBallUsedIdentify);
                    obj.put("countScanCarIdentify", countScanCarIdentify);
                    obj.put("countScanCarIdentifyRate", countScanCarIdentifyRate);
                    obj.put("countBallIdentify", countBallIdentify);
                    obj.put("countGunIdentify", countGunIdentify);
                    obj.put("countVisualIdentify", countVisualIdentify);
                    obj.put("countVisualIdentifyRate", countVisualIdentifyRate);
                    obj.put("countBallDifferGun", countBallDifferGun);
                    obj.put("countRfidIdentify", countRfidIdentify);
                    obj.put("countResetCar", countResetCar);
                    obj.put("countWebResetCar", countWebResetCar);
                    obj.put("countCarIdentifyRate", countCarIdentifyRate);
                    obj.put("countGunResetCar", countGunResetCar);
                    obj.put("countBallResetCar", countBallResetCar);
                    obj.put("countGunIndentifyRate", countGunIndentifyRate);
                    obj.put("countGunIndentifyAccuracyRate", countGunIndentifyAccuracyRate);
                    obj.put("countBallIndentifyRate", countBallIndentifyRate);
                    obj.put("countBallIndentifyAccuracyRate", countBallIndentifyAccuracyRate);
                    mapList.add(obj);
                }
            }
        }
        return mapList;
    }

    @Override
    public PageList<HashMap> getCarNoDetail(HashMap params) {
        PageHelper.startPage(Integer.parseInt(params.get("pageNum").toString()), Integer.parseInt(params.get("pageSize").toString()));
        List<HashMap> rows = meterWorkCarnoIdentifyMapper.getCarNoDetail(params);
        PageList pageInfo = new PageList(rows);
        return pageInfo;
    }

    @Override
    public List<PointDetailsVo> getPointDetails(PointDetailsBo pointDetailsBo) {
        return meterWorkCarnoIdentifyMapper.selectPointDetails(pointDetailsBo);
    }
}
