package com.mvc.service.ysfx;

import com.mvc.dao.TAireadMapper;
import com.mvc.entity.TAiread;
import com.mvc.model.StationAccModel;
import com.mvc.model.TAireadModel;
import com.mvc.model.ysfx.*;
import com.mvc.service.copy.TAireadService;
import com.mvc.service.taizhang.StationAccService;
import com.mvc.utils.DateUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

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

/**
 * 用水分析主服务
 */
@Service
@Transactional
public class YsfxService {

    @Autowired
    private StationAccService stationAccService;

    @Autowired
    private TAireadService tAireadService;

    @Autowired
    private TStationStructureService tStationStructureService;

    @Autowired
    private DicWaterTypeService dicWaterTypeService;

    @Autowired(required = false)
    private TAireadMapper tAireadMapper;

    public WaterConsModel findWaterConsumptionByUnitCode(String unitCode) {
        WaterConsModel consModel = new WaterConsModel();
        List<StationAccModel> accList = stationAccService.findStationAccByUnitCode(unitCode);
        if (accList == null || accList.size() == 0) return consModel;

        //获取水表等级的信息
        //List<TStationStructureModel> stationStruViewModels = tStationStructureService.findTStationStructureModelsByUnitCode(unitCode);

        //时间范围为一周(结束时间是昨天,结束时间从当天算计算畅通率比较复杂)
        //Date dtEnd = DateUtil.getOtherDateByCurrentDate(new Date(), -1);
        //String startTime = DateUtil.formateDate(DateUtil.getOtherDateByCurrentDate(dtEnd, -7), "yyyyMMdd235959");
        //String endTime = DateUtil.formateDate(dtEnd, "yyyyMMdd000000");

        SameTimeDataModel sameTimeDataModel = getSameTimeData(unitCode);
        if(sameTimeDataModel==null||sameTimeDataModel.getStationStruViewModels()==null||sameTimeDataModel.getStartDate()==null){
            return consModel;       //没有找到同时有数据的
        }

        List<TStationStructureModel> stationStruViewModels=sameTimeDataModel.getStationStruViewModels();

        String startTime=DateUtil.formateDate(sameTimeDataModel.getStartDate(), "yyyyMMdd000000");
        String endTime=DateUtil.formateDate(sameTimeDataModel.getEndDate(),"yyyyMMdd000000");
        long days=(sameTimeDataModel.getEndDate().getTime() - sameTimeDataModel.getStartDate().getTime()) / (24 * 60 * 60 * 1000);//间隔天数
        if((sameTimeDataModel.getEndDate().getTime() - sameTimeDataModel.getStartDate().getTime()) % (24 * 60 * 60 * 1000)!=0){
            days=days+1;
        }
        //int ysCount = 21 * accList.size();                 //7天应收总条数
        int ssCount = 0;
        int idenTrue = 0;     //识别正确的数
        int idenFalse = 0;    //识别错误的数

        long ysDay=(days+1)*accList.size();//按天计算应收数量(间隔+1是因为包含最后一天)
        int ssDay=0;//按天计算实收数量

        BigDecimal level1 = new BigDecimal(0);       //1级用水量
        BigDecimal level2 = new BigDecimal(0);
        BigDecimal level3 = new BigDecimal(0);
        BigDecimal level4 = new BigDecimal(0);

        List<WaterConsDetailModel> details = new ArrayList<>();
        for (StationAccModel acc : accList) {
            Map<String, Object> map = tAireadService.findAllTAireadByStationCode(acc.getStationCode(), startTime, endTime, 1, 100);
            WaterConsDetailModel consDetailModel = new WaterConsDetailModel();

            consDetailModel.setStationCode(acc.getStationCode());
            consDetailModel.setStationName(acc.getStationName());

            List<TAireadModel> tAireadModels = (List<TAireadModel>) map.get("list");
            if (tAireadModels != null) {
                ssCount += tAireadModels.size();

                //先按数据正常处理(后续考虑换表和中间丢数的问题)
                TAireadModel last = tAireadModels.get(0);
                TAireadModel first = tAireadModels.get(tAireadModels.size() - 1);
                BigDecimal sl = last.getResultValue().subtract(first.getResultValue()).setScale(1);
                consDetailModel.setWaterCons(sl);

                //累加级别用水量
                List<TStationStructureModel> struList = stationStruViewModels.stream().filter(s -> s.getStationCode().equals(acc.getStationCode())).collect(Collectors.toList());
                if (struList != null && struList.size() > 0) {
                    TStationStructureModel structure = struList.get(0);
                    if (structure.getWaterMeterLevel() == 1) {
                        level1 = level1.add(sl);
                    } else if (structure.getWaterMeterLevel() == 2) {
                        level2 = level2.add(sl);
                    } else if (structure.getWaterMeterLevel() == 3) {
                        level3 = level3.add(sl);
                    } else if (structure.getWaterMeterLevel() == 4) {
                        level4 = level4.add(sl);
                    }
                }

                //下面暂时通过比较result和iden的差值来判断准确性(因为result是经过审核的)(两个差值不超过1就代表正确)
                for (TAireadModel aireadModel : tAireadModels) {
                    if((aireadModel.getIdentValue().subtract(aireadModel.getResultValue()).abs().compareTo(new BigDecimal(1))<1)){
                        idenTrue++;
                    } else {
                        idenFalse++;
                    }
                }

                Map<String,List<TAireadModel>> dayMap = tAireadModels.stream().collect(Collectors.groupingBy(t -> DateUtil.formateDate(t.getSampleTime(),"yyyyMMdd")));

                ssDay+=dayMap.size();//每天只累加一条
//                if(dayMap.size()!=days){
//                    System.out.println("Code:"+acc.getStationCode());
//                    for(String key:dayMap.keySet()){
//                        System.out.println("Date:"+key);
//                    }
//                }
            }
            details.add(consDetailModel);
        }

        //计算畅通率
        //int stl = (int) (((double) ssCount / ysCount) * 100);
        int stl=(int) (((double) ssDay / ysDay) * 100);
        int zql = (int) (((double) idenTrue / ssCount) * 100);

        consModel.setLevel1Cons(level1.setScale(0));
        consModel.setLevel2Cons(level2.setScale(0));
        consModel.setLevel3Cons(level3.setScale(0));
        consModel.setLevel4Cons(level4.setScale(0));
        consModel.setUnblockedRate(stl);
        consModel.setPrecision(zql);
        consModel.setDetails(details);

        return consModel;
    }

    /**
     * 根据站代码获取用水结构数据
     *
     * @param unitCode
     * @return
     */
    public List<DicWaterTypeModel> findTypeWaterConsByUnitCode(String unitCode) {
        List<DicWaterTypeModel> resList = new ArrayList<>();
        List<TStationStructureModel> stationStruViewModels = tStationStructureService.findTStationStructureModelsByUnitCode(unitCode);
        if (stationStruViewModels != null && stationStruViewModels.size() > 0) {
            List<DicWaterTypeModel> typeModels = dicWaterTypeService.findDicWaterTypeModelsByUnitCode(unitCode);

            Date dtEnd = new Date();
            Date dtStart = DateUtil.getOtherDateByCurrentDate(dtEnd, -7);
            Date temp = dtStart;
            List<String> days = new ArrayList<>();
            while (temp.compareTo(dtEnd) == -1) {
                days.add(DateUtil.formateDate(temp, "MM/dd"));
                temp = DateUtil.getOtherDateByCurrentDate(temp, 1);
            }

            String startTime = DateUtil.formateDate(dtStart, "yyyyMMdd000000");
            String endTime = DateUtil.formateDate(dtEnd, "yyyyMMdd000000");
            BigDecimal totalDays = new BigDecimal(7);
            for (TStationStructureModel model : stationStruViewModels) {
                Map<String, Object> map = tAireadService.findAllTAireadByStationCode(model.getStationCode(), startTime, endTime, 1, 100);
                List<TAireadModel> tAireadModels = (List<TAireadModel>) map.get("list");
                if (tAireadModels == null) continue;

                TAireadModel last = tAireadModels.get(0);
                TAireadModel first = tAireadModels.get(tAireadModels.size() - 1);
                BigDecimal sl = last.getResultValue().subtract(first.getResultValue()).setScale(1);

                var types = typeModels.stream().filter(s -> s.getWaterType().equals(model.getWaterType())).collect(Collectors.toList());
                if (types != null && types.size() > 0) {
                    BigDecimal ysl = types.get(0).getWaterCons() == null ? new BigDecimal(0) : types.get(0).getWaterCons();
                    types.get(0).setWaterCons(ysl.add(sl));

                    types.get(0).setDayCategory(days);
                    BigDecimal aver = types.get(0).getWaterCons().divide(totalDays, RoundingMode.HALF_UP).divide(new BigDecimal(types.get(0).getPeopleNum()), RoundingMode.HALF_UP);
                    types.get(0).setAverageWater(aver);
                }
            }
            resList = typeModels;
        }
        return resList;
    }

    /**
     * 获取1级表的近20天用水量
     *
     * @param unitCode
     * @param num 几天的
     * @return
     */
    public MonthlyWaterConsModel getMonthlyWaterCons(String unitCode,int num) {
        TStationStructureModel structureModel = tStationStructureService.findStationStruViewModelsByUnitCodeAndLevel(unitCode, 1);
        if (structureModel == null) {
            return null;
        }

        List<String> days = new ArrayList<>();//日期的天
        List<Integer> values = new ArrayList<>();//水量
        List<String> tips = new ArrayList<>();//统计时间范围(可能存在不是0点到0点的)

        String strNow = DateUtil.formateDate(new Date(), "yyyy-MM-dd 00:00:00");
        Date now = DateUtil.parseTimeStr(strNow, "yyyy-MM-dd HH:mm:ss");
        Date yesterday = DateUtil.getOtherDateByCurrentDate(now, -1);

        String startTime = DateUtil.formateDate(DateUtil.getOtherDateByCurrentDate(yesterday, -30), "yyyyMMddHHmmss");
        String endTime = DateUtil.formateDate(yesterday, "yyyyMMddHHmmss");

        Map<String, Object> map = tAireadService.findAllTAireadByStationCode(structureModel.getStationCode(), startTime, endTime, 1, 1000);
        List<TAireadModel> aireadModels = (List<TAireadModel>) map.get("list");
        for (int i = num-1; i > -1; i--) {
            Date temp0 = DateUtil.getOtherDateByCurrentDate(yesterday, -1 * i - 1);
            Date temp1 = DateUtil.getOtherDateByCurrentDate(yesterday, -1 * i);

            String day = DateUtil.formateDate(temp0, "dd");
            days.add(day);//记哪一天

            String tip0 = DateUtil.formateDate(temp0, "yyyy-MM-dd HH:mm:ss");
            String tip1 = DateUtil.formateDate(temp1, "yyyy-MM-dd HH:mm:ss");
            tips.add(tip0 + " 至 " + tip1);//记统计的时间点

            List<TAireadModel> list0 = aireadModels.stream().filter(s -> s.getSampleTime().compareTo(temp0) == 0).collect(Collectors.toList());
            List<TAireadModel> list1 = aireadModels.stream().filter(s -> s.getSampleTime().compareTo(temp1) == 0).collect(Collectors.toList());
            if (list0 != null && list1 != null && list0.size() > 0 && list1.size() > 0) {
                TAireadModel tAireadModel0 = list0.get(0);
                TAireadModel tAireadModel1 = list1.get(0);

                BigDecimal value = tAireadModel1.getResultValue().subtract(tAireadModel0.getResultValue());
                values.add(value.intValue());
            } else {
                values.add(0);
            }
        }

        MonthlyWaterConsModel monthly = new MonthlyWaterConsModel();
        monthly.setDays(days);
        monthly.setValues(values);
        monthly.setTips(tips);

        return monthly;
    }

    /**
     * 获取一周的人均用水量(用水结构分类)
     *
     * @param unitCode
     * @return
     */
    public List<DicWaterTypeModel> getWaterStandard(String unitCode) {
        List<DicWaterTypeModel> resList = new ArrayList<>();
        List<TStationStructureModel> stationStruViewModels = tStationStructureService.findTStationStructureModelsByUnitCode(unitCode);
        if (stationStruViewModels != null && stationStruViewModels.size() > 0) {
            List<DicWaterTypeModel> typeModels = dicWaterTypeService.findDicWaterTypeModelsByUnitCode(unitCode);
            List<String> days = new ArrayList<>();
            List<BigDecimal> values = new ArrayList<>();
            Date dtEnd = new Date();
            Date dtStart = DateUtil.getOtherDateByCurrentDate(dtEnd, -7);

            String startTime = DateUtil.formateDate(dtStart, "yyyyMMdd000000");
            String endTime = DateUtil.formateDate(dtEnd, "yyyyMMdd000000");

            Date dtKs = DateUtil.parseTimeStr(startTime, "yyyyMMddHHmmss");
            Date dtJs = DateUtil.parseTimeStr(endTime, "yyyyMMddHHmmss");

            Date temp = dtKs;
            //循环日期
            while (temp.compareTo(dtJs) == -1) {
                days.add(DateUtil.formateDate(temp, "MM/dd"));
                String kssj = DateUtil.formateDate(temp, "yyyyMMdd000000");
                temp = DateUtil.getOtherDateByCurrentDate(temp, 1);
                String jssj = DateUtil.formateDate(temp, "yyyyMMdd000000");

                //循环下辖站点

                for (TStationStructureModel structureModel : stationStruViewModels) {
                    Map<String, Object> map = tAireadService.findAllTAireadByStationCode(structureModel.getStationCode(), kssj, jssj, 1, 100);
                    List<TAireadModel> tAireadModels = (List<TAireadModel>) map.get("list");


                    if (tAireadModels == null || tAireadModels.size() < 2) continue;
                    //假设数据完整,都有0点的情况
                    BigDecimal value = tAireadModels.get(0).getResultValue().subtract(tAireadModels.get(tAireadModels.size() - 1).getResultValue());
                    List<DicWaterTypeModel> types = typeModels.stream().filter(s -> s.getWaterType().equals(structureModel.getWaterType())).collect(Collectors.toList());
                    if (types != null && types.size() > 0) {
                        value = types.get(0).getWaterCons() == null ? value : types.get(0).getWaterCons().add(value);
                        types.get(0).setWaterCons(value);
                    }
                }

                //计算当日分类的人均用水量
                for (DicWaterTypeModel typeModel : typeModels) {
                    if (typeModel.getWaterCons() == null) {
                        typeModel.setWaterCons(new BigDecimal(0));
                    }
                    BigDecimal aver = typeModel.getWaterCons().divide(new BigDecimal(typeModel.getPeopleNum()), RoundingMode.HALF_UP);
                    values.add(aver);
                    if (typeModel.getDayValues() == null) {
                        typeModel.setDayValues(new ArrayList<>());
                        typeModel.setDayCategory(days);
                    }
                    typeModel.getDayValues().add(aver);
                    typeModel.setWaterCons(new BigDecimal(0));
                }

            }
            resList = typeModels;
        }
        return resList;
    }

    /**
     * 获取漏溢、漏损数据
     * @param unitCode
     * @return
     */
    public LeakageModel getLeakageData(String unitCode) {
        LeakageModel res = new LeakageModel();
        SameTimeDataModel stdModel = getSameTimeData(unitCode);
        if (stdModel.getStationStruViewModels() == null || stdModel.getStartDate() == null) return res;
        String timeFrame = "[" + DateUtil.formateDate(stdModel.getStartDate(),
                "MM-dd HH时") + "至" + DateUtil.formateDate(stdModel.getEndDate(), "MM-dd HH时]");
        res.setTimeFrame(timeFrame);
        Map<Integer, BigDecimal> consMap = new HashMap<>();        //存储等级和水量

        List<TStationStructureModel> stationStruViewModels = stdModel.getStationStruViewModels();
        //汇总出一共几级表,然后加各级水量
        Map<Integer, List<TStationStructureModel>> levelMap = stationStruViewModels.stream().collect(Collectors.groupingBy(t -> t.getWaterMeterLevel()));
        for (Integer level : levelMap.keySet()) {
            BigDecimal cons = new BigDecimal(0);
            List<TStationStructureModel> temps = levelMap.get(level);
            for (TStationStructureModel tssModel : temps) {
                List<TAiread> ksdsList = stdModel.getStartAireadList().stream()
                        .filter(s -> s.getStationCode().equals(tssModel.getStationCode())).collect(Collectors.toList());
                List<TAiread> jsdsList = stdModel.getEndAireadList().stream()
                        .filter(s -> s.getStationCode().equals(tssModel.getStationCode())).collect(Collectors.toList());
                TAiread read0 = ksdsList.get(0);
                TAiread read1 = jsdsList.get(0);
                cons = cons.add(read1.getResultValue().subtract(read0.getResultValue()));
            }
            //System.out.println(level + "级水量:" + cons);
            consMap.put(level, cons);
        }

        List<String> levelCategory = new ArrayList<>();
        List<BigDecimal> leakageLy = new ArrayList<>();
        List<BigDecimal> leakageLs = new ArrayList<>();
        //开始计算漏
        for (Integer level : consMap.keySet()) {
            Integer nextLv = level + 1;
            if (consMap.containsKey(nextLv)) {
                BigDecimal valueCur = consMap.get(level);       //当前等级的水量
                BigDecimal valueNext = consMap.get(nextLv);     //下一等级的水量
                //漏溢率=(一级表总水量 - 二级表总水量)/一级表总水量
                BigDecimal ly = (valueCur.subtract(valueNext)).divide(valueCur, RoundingMode.HALF_UP);

                //漏损率=漏溢率-水表计量误差率(此处水表计量误差固定5%)
                BigDecimal ls =ly.subtract(new BigDecimal(0.05));
                String category=level+"-"+nextLv+"级";

                levelCategory.add(category);
                leakageLy.add(ly.multiply(new BigDecimal(100)).setScale(2,RoundingMode.HALF_UP));
                leakageLs.add(ls.multiply(new BigDecimal(100)).setScale(2,RoundingMode.HALF_UP));
            }
        }

        res.setLevelCategory(levelCategory);
        res.setLeakageLy(leakageLy);
        res.setLeakageLs(leakageLs);
        res.setStandardValue(new BigDecimal(2));

        return res;
    }

    //找某一时刻都有数据的
    public SameTimeDataModel getSameTimeData(String unitCode) {
        SameTimeDataModel sameTimeDataModel = new SameTimeDataModel();
        sameTimeDataModel.setUnitCode(unitCode);
        //获取水表等级的信息
        List<TStationStructureModel> stationStruViewModels = tStationStructureService.findTStationStructureModelsByUnitCode(unitCode);
        sameTimeDataModel.setStationStruViewModels(stationStruViewModels);
        //昨天的最后一个审核时刻(当天数据可能未审核)
        String strNow = DateUtil.formateDate(DateUtil.getOtherDateByCurrentDate(new Date(),-1), "yyyy-MM-dd 00:00:00");
        Date now = DateUtil.parseTimeStr(strNow, "yyyy-MM-dd HH:mm:ss");
        int num = stationStruViewModels.size();//站点数量(设备数)
        Date minDate = DateUtil.getOtherDateByCurrentDate(now, -30);//最长寻找30天

        Date temp = now;//循环变更
        Date dtEnd = null;//结束日期
        Date dtStart = null;//开始日期
        long days = 0;//间隔天数
        Calendar calendar = Calendar.getInstance();
        while (temp.compareTo(minDate) > 0) {
            List<TAiread> list = tAireadMapper.findSameTimeDataByUnitAndDate(unitCode, temp);
            if (list.size() == num) {
                if (dtEnd == null) {
                    dtEnd = temp;
                    sameTimeDataModel.setEndDate(temp);
                    sameTimeDataModel.setEndAireadList(list);
                    //System.out.println("找到结束时间" + DateUtil.formateDate(temp, "yyyy-MM-dd HH:mm:ss"));
                } else if (dtStart == null) {
                    //System.out.println(DateUtil.formateDate(dtEnd, "MM-dd HH:mm:ss")+DateUtil.formateDate(temp, "MM-dd HH:mm:ss"));
                    if(!DateUtil.formateDate(dtEnd, "HH:mm:ss").equals(DateUtil.formateDate(temp,"HH:mm:ss"))){
                        calendar.setTime(temp);
                        calendar.add(Calendar.DAY_OF_MONTH, -1);
                        temp = calendar.getTime();
                        continue;//时刻相同
                    }

                    days = (dtEnd.getTime() - temp.getTime()) / (24 * 60 * 60 * 1000);
                    if (days > 7) {//最短7天
                        dtStart = temp;
                        sameTimeDataModel.setStartDate(temp);
                        sameTimeDataModel.setStartAireadList(list);
                        //System.out.println("找到开始时间" + DateUtil.formateDate(temp, "yyyy-MM-dd HH:mm:ss"));
                        sameTimeDataModel.setIntervalDays(days);
                        break;
                    }
                }
            }

            calendar.setTime(temp);
            //calendar.add(Calendar.HOUR_OF_DAY, -8);
            calendar.add(Calendar.DAY_OF_MONTH,-1);
            temp = calendar.getTime();
        }
        if(sameTimeDataModel.getStartDate()!=null){
            String timeFrame = "[" + DateUtil.formateDate(sameTimeDataModel.getStartDate(),
                    "MM-dd HH时") + "至" + DateUtil.formateDate(sameTimeDataModel.getEndDate(), "MM-dd HH时]");
            sameTimeDataModel.setTimeFrame(timeFrame);
        }
        return sameTimeDataModel;
    }

    /** 统一时刻的接口开始 */
    /** ------------------------------------------------------------------------------------------------------*/

    /**
     * 根据SameTimeDataModel获取用水结构数据
     *
     * @param sameTimeDataModel
     * @return
     */
    public List<DicWaterTypeModel> findTypeWaterConsByUnitCode(SameTimeDataModel sameTimeDataModel) {
        List<DicWaterTypeModel> resList = new ArrayList<>();
        List<TStationStructureModel> stationStruViewModels = sameTimeDataModel.getStationStruViewModels();
        if (stationStruViewModels != null && stationStruViewModels.size() > 0) {
            List<DicWaterTypeModel> typeModels = dicWaterTypeService.findDicWaterTypeModelsByUnitCode(sameTimeDataModel.getUnitCode());

            Date temp = sameTimeDataModel.getStartDate();
            List<String> days = new ArrayList<>();
            while (temp.compareTo(sameTimeDataModel.getEndDate()) == -1) {
                days.add(DateUtil.formateDate(temp, "MM/dd"));
                temp = DateUtil.getOtherDateByCurrentDate(temp, 1);
            }

            String startTime = DateUtil.formateDate(sameTimeDataModel.getStartDate(), "yyyyMMddHHmmdd");
            String endTime = DateUtil.formateDate(sameTimeDataModel.getEndDate(), "yyyyMMddHHmmdd");
            long tianShu = (sameTimeDataModel.getEndDate().getTime() - sameTimeDataModel.getStartDate().getTime()) / (24 * 60 * 60 * 1000);
            BigDecimal totalDays = new BigDecimal(tianShu);
            for (TStationStructureModel model : stationStruViewModels) {
                Map<String, Object> map = tAireadService.findAllTAireadByStationCode(model.getStationCode(), startTime, endTime, 1, 100);
                List<TAireadModel> tAireadModels = (List<TAireadModel>) map.get("list");
                if (tAireadModels == null) continue;

                TAireadModel last = tAireadModels.get(0);
                TAireadModel first = tAireadModels.get(tAireadModels.size() - 1);
                BigDecimal sl = last.getResultValue().subtract(first.getResultValue()).setScale(1);

                var types = typeModels.stream().filter(s -> s.getWaterType().equals(model.getWaterType())).collect(Collectors.toList());
                if (types != null && types.size() > 0) {
                    BigDecimal ysl = types.get(0).getWaterCons() == null ? new BigDecimal(0) : types.get(0).getWaterCons();
                    types.get(0).setWaterCons(ysl.add(sl));

                    types.get(0).setDayCategory(days);
                    BigDecimal aver = types.get(0).getWaterCons().divide(totalDays, RoundingMode.HALF_UP).divide(new BigDecimal(types.get(0).getPeopleNum()), RoundingMode.HALF_UP);
                    types.get(0).setAverageWater(aver);
                }
            }
            resList = typeModels;
        }
        return resList;
    }

    /**
     * 获取用水量、等级用水、畅通率、准确率
     * @param sameTimeDataModel
     * @return
     */
    public WaterConsModel findWaterConsumptionByUnitCode(SameTimeDataModel sameTimeDataModel) {
        WaterConsModel consModel = new WaterConsModel();
        List<StationAccModel> accList = stationAccService.findStationAccByUnitCode(sameTimeDataModel.getUnitCode());
        if (accList == null || accList.size() == 0) return consModel;

        String startTime=DateUtil.formateDate(sameTimeDataModel.getStartDate(), "yyyyMMdd000000");
        String endTime=DateUtil.formateDate(sameTimeDataModel.getEndDate(),"yyyyMMdd000000");

        Date dtStart=sameTimeDataModel.getStartDate();
        Date dtEnd=sameTimeDataModel.getEndDate();

        long days=(dtEnd.getTime() - dtStart.getTime()) / (24 * 60 * 60 * 1000);//间隔天数
        if((dtEnd.getTime() - dtStart.getTime()) % (24 * 60 * 60 * 1000)!=0){
            days=days+1;
        }
        int ssCount = 0;
        int idenTrue = 0;     //识别正确的数
        int idenFalse = 0;    //识别错误的数

        long ysDay=(days+1)*accList.size();//按天计算应收数量(间隔+1是因为包含最后一天)
        int ssDay=0;//按天计算实收数量

        BigDecimal level1 = new BigDecimal(0);       //1级用水量
        BigDecimal level2 = new BigDecimal(0);
        BigDecimal level3 = new BigDecimal(0);
        BigDecimal level4 = new BigDecimal(0);

        List<WaterConsDetailModel> details = new ArrayList<>();
        for (StationAccModel acc : accList) {
            Map<String, Object> map = tAireadService.findAllTAireadByStationCode(acc.getStationCode(), startTime, endTime, 1, 100);
            WaterConsDetailModel consDetailModel = new WaterConsDetailModel();
            List<TStationStructureModel> stationStruViewModels = sameTimeDataModel.getStationStruViewModels();
            consDetailModel.setStationCode(acc.getStationCode());
            consDetailModel.setStationName(acc.getStationName());

            List<TAireadModel> tAireadModels = (List<TAireadModel>) map.get("list");
            if (tAireadModels != null) {
                ssCount += tAireadModels.size();

                //先按数据正常处理(后续考虑换表和中间丢数的问题)
                TAireadModel last = tAireadModels.get(0);
                TAireadModel first = tAireadModels.get(tAireadModels.size() - 1);
                BigDecimal sl = last.getResultValue().subtract(first.getResultValue()).setScale(1);
                consDetailModel.setWaterCons(sl);

                //累加级别用水量
                List<TStationStructureModel> struList = stationStruViewModels.stream().filter(s -> s.getStationCode().equals(acc.getStationCode())).collect(Collectors.toList());
                if (struList != null && struList.size() > 0) {
                    TStationStructureModel structure = struList.get(0);
                    if (structure.getWaterMeterLevel() == 1) {
                        level1 = level1.add(sl);
                    } else if (structure.getWaterMeterLevel() == 2) {
                        level2 = level2.add(sl);
                    } else if (structure.getWaterMeterLevel() == 3) {
                        level3 = level3.add(sl);
                    } else if (structure.getWaterMeterLevel() == 4) {
                        level4 = level4.add(sl);
                    }
                }

                //下面暂时通过比较result和iden的差值来判断准确性(因为result是经过审核的)(两个差值不超过1就代表正确)
                for (TAireadModel aireadModel : tAireadModels) {
                    if((aireadModel.getIdentValue().subtract(aireadModel.getResultValue()).abs().compareTo(new BigDecimal(1))<1)){
                        idenTrue++;
                    } else {
                        idenFalse++;
                    }
                }

                Map<String,List<TAireadModel>> dayMap = tAireadModels.stream().collect(Collectors.groupingBy(t -> DateUtil.formateDate(t.getSampleTime(),"yyyyMMdd")));

                ssDay+=dayMap.size();//每天只累加一条
            }
            details.add(consDetailModel);
        }

        //计算畅通率
        //int stl = (int) (((double) ssCount / ysCount) * 100);
        int stl=(int) (((double) ssDay / ysDay) * 100);
        int zql = (int) (((double) idenTrue / ssCount) * 100);

        consModel.setLevel1Cons(level1.setScale(0));
        consModel.setLevel2Cons(level2.setScale(0));
        consModel.setLevel3Cons(level3.setScale(0));
        consModel.setLevel4Cons(level4.setScale(0));
        consModel.setUnblockedRate(stl);
        consModel.setPrecision(zql);
        consModel.setDetails(details);

        return consModel;
    }

    /**
     * 获取一级表用水量
     * @param sameTimeDataModel
     * @return
     */
    public MonthlyWaterConsModel getMonthlyWaterCons(SameTimeDataModel sameTimeDataModel) {
        List<TStationStructureModel> lvList = sameTimeDataModel.getStationStruViewModels().stream().filter(s->s.getWaterMeterLevel()==1).collect(Collectors.toList());
        //TStationStructureModel structureModel = tStationStructureService.findStationStruViewModelsByUnitCodeAndLevel(sameTimeDataModel.getUnitCode(), 1);
        if (lvList == null||lvList.size()==0) {
            return null;
        }
        TStationStructureModel structureModel=lvList.get(0);
        List<String> days = new ArrayList<>();//日期的天
        List<Integer> values = new ArrayList<>();//水量
        List<String> tips = new ArrayList<>();//统计时间范围(可能存在不是0点到0点的)

        String strNow = DateUtil.formateDate(new Date(), "yyyy-MM-dd 00:00:00");
        Date now = DateUtil.parseTimeStr(strNow, "yyyy-MM-dd HH:mm:ss");
        //Date yesterday = DateUtil.getOtherDateByCurrentDate(now, -1);
        Date dtEnd=sameTimeDataModel.getEndDate();

        String startTime = DateUtil.formateDate(sameTimeDataModel.getStartDate(), "yyyyMMddHHmmss");
        String endTime = DateUtil.formateDate(sameTimeDataModel.getEndDate(), "yyyyMMddHHmmss");

        Map<String, Object> map = tAireadService.findAllTAireadByStationCode(structureModel.getStationCode(), startTime, endTime, 1, 1000);
        List<TAireadModel> aireadModels = (List<TAireadModel>) map.get("list");
        int intervalDays=sameTimeDataModel.getIntervalDays().intValue();
        for (int i = intervalDays-1; i > -1; i--) {
            Date temp0 = DateUtil.getOtherDateByCurrentDate(dtEnd, -1 * i - 1);
            Date temp1 = DateUtil.getOtherDateByCurrentDate(dtEnd, -1 * i);

            String day = DateUtil.formateDate(temp0, "dd");
            days.add(day);//记哪一天

            String tip0 = DateUtil.formateDate(temp0, "yyyy-MM-dd HH:mm:ss");
            String tip1 = DateUtil.formateDate(temp1, "yyyy-MM-dd HH:mm:ss");
            tips.add(tip0 + " 至 " + tip1);//记统计的时间点

            List<TAireadModel> list0 = aireadModels.stream().filter(s -> s.getSampleTime().compareTo(temp0) == 0).collect(Collectors.toList());
            List<TAireadModel> list1 = aireadModels.stream().filter(s -> s.getSampleTime().compareTo(temp1) == 0).collect(Collectors.toList());
            if (list0 != null && list1 != null && list0.size() > 0 && list1.size() > 0) {
                TAireadModel tAireadModel0 = list0.get(0);
                TAireadModel tAireadModel1 = list1.get(0);

                BigDecimal value = tAireadModel1.getResultValue().subtract(tAireadModel0.getResultValue());
                values.add(value.intValue());
            } else {
                values.add(0);
            }
        }

        MonthlyWaterConsModel monthly = new MonthlyWaterConsModel();
        monthly.setDays(days);
        monthly.setValues(values);
        monthly.setTips(tips);

        return monthly;
    }

    /**
     * 获取人均用水标准
     * @param sameTimeDataModel
     * @return
     */
    public List<DicWaterTypeModel> getWaterStandard(SameTimeDataModel sameTimeDataModel) {
        List<DicWaterTypeModel> resList = new ArrayList<>();
        List<TStationStructureModel> stationStruViewModels = sameTimeDataModel.getStationStruViewModels();
        if (stationStruViewModels != null && stationStruViewModels.size() > 0) {
            List<DicWaterTypeModel> typeModels = dicWaterTypeService.findDicWaterTypeModelsByUnitCode(sameTimeDataModel.getUnitCode());
            List<String> days = new ArrayList<>();
            List<BigDecimal> values = new ArrayList<>();
            Date dtEnd = sameTimeDataModel.getEndDate();
            Date dtStart = sameTimeDataModel.getStartDate();

            String startTime = DateUtil.formateDate(dtStart, "yyyyMMddHHmmss");
            String endTime = DateUtil.formateDate(dtEnd, "yyyyMMddHHmmss");

            //Date dtKs = DateUtil.parseTimeStr(startTime, "yyyyMMddHHmmss");
            //Date dtJs = DateUtil.parseTimeStr(endTime, "yyyyMMddHHmmss");

            Date temp = dtStart;
            //循环日期
            while (temp.compareTo(dtEnd) == -1) {
                days.add(DateUtil.formateDate(temp, "MM/dd"));
                String kssj = DateUtil.formateDate(temp, "yyyyMMdd000000");
                temp = DateUtil.getOtherDateByCurrentDate(temp, 1);
                String jssj = DateUtil.formateDate(temp, "yyyyMMdd000000");

                //循环下辖站点

                for (TStationStructureModel structureModel : stationStruViewModels) {
                    Map<String, Object> map = tAireadService.findAllTAireadByStationCode(structureModel.getStationCode(), kssj, jssj, 1, 100);
                    List<TAireadModel> tAireadModels = (List<TAireadModel>) map.get("list");

                    if (tAireadModels == null || tAireadModels.size() < 2) continue;
                    //假设数据完整,都有0点的情况
                    BigDecimal value = tAireadModels.get(0).getResultValue().subtract(tAireadModels.get(tAireadModels.size() - 1).getResultValue());
                    List<DicWaterTypeModel> types = typeModels.stream().filter(s -> s.getWaterType().equals(structureModel.getWaterType())).collect(Collectors.toList());
                    if (types != null && types.size() > 0) {
                        value = types.get(0).getWaterCons() == null ? value : types.get(0).getWaterCons().add(value);
                        types.get(0).setWaterCons(value);
                    }
                }

                //计算当日分类的人均用水量
                for (DicWaterTypeModel typeModel : typeModels) {
                    if (typeModel.getWaterCons() == null) {
                        typeModel.setWaterCons(new BigDecimal(0));
                    }
                    BigDecimal aver = typeModel.getWaterCons().divide(new BigDecimal(typeModel.getPeopleNum()), RoundingMode.HALF_UP);
                    values.add(aver);
                    if (typeModel.getDayValues() == null) {
                        typeModel.setDayValues(new ArrayList<>());
                        typeModel.setDayCategory(days);
                    }
                    typeModel.getDayValues().add(aver);
                    typeModel.setWaterCons(new BigDecimal(0));
                }
            }
            resList = typeModels;
        }
        return resList;
    }

    /**
     * 获取漏溢、漏损数据
     * @param stdModel
     * @return
     */
    public LeakageModel getLeakageData(SameTimeDataModel stdModel) {
        LeakageModel res = new LeakageModel();
        if (stdModel.getStationStruViewModels() == null || stdModel.getStartDate() == null) return res;
//        String timeFrame = "[" + DateUtil.formateDate(stdModel.getStartDate(),
//                "MM-dd HH时") + "至" + DateUtil.formateDate(stdModel.getEndDate(), "MM-dd HH时]");
        res.setTimeFrame("");
        Map<Integer, BigDecimal> consMap = new HashMap<>();        //存储等级和水量

        List<TStationStructureModel> stationStruViewModels = stdModel.getStationStruViewModels();
        //汇总出一共几级表,然后加各级水量
        Map<Integer, List<TStationStructureModel>> levelMap = stationStruViewModels.stream().collect(Collectors.groupingBy(t -> t.getWaterMeterLevel()));
        for (Integer level : levelMap.keySet()) {
            BigDecimal cons = new BigDecimal(0);
            List<TStationStructureModel> temps = levelMap.get(level);
            for (TStationStructureModel tssModel : temps) {
                List<TAiread> ksdsList = stdModel.getStartAireadList().stream()
                        .filter(s -> s.getStationCode().equals(tssModel.getStationCode())).collect(Collectors.toList());
                List<TAiread> jsdsList = stdModel.getEndAireadList().stream()
                        .filter(s -> s.getStationCode().equals(tssModel.getStationCode())).collect(Collectors.toList());
                TAiread read0 = ksdsList.get(0);
                TAiread read1 = jsdsList.get(0);
                cons = cons.add(read1.getResultValue().subtract(read0.getResultValue()));
            }
            //System.out.println(level + "级水量:" + cons);
            consMap.put(level, cons);
        }

        List<String> levelCategory = new ArrayList<>();
        List<BigDecimal> leakageLy = new ArrayList<>();
        List<BigDecimal> leakageLs = new ArrayList<>();
        //开始计算漏
        for (Integer level : consMap.keySet()) {
            Integer nextLv = level + 1;
            if (consMap.containsKey(nextLv)) {
                BigDecimal valueCur = consMap.get(level);       //当前等级的水量
                BigDecimal valueNext = consMap.get(nextLv);     //下一等级的水量
                //漏溢率=(一级表总水量 - 二级表总水量)/一级表总水量
                BigDecimal ly = (valueCur.subtract(valueNext)).divide(valueCur, RoundingMode.HALF_UP);

                //漏损率=漏溢率-水表计量误差率(此处水表计量误差固定5%)
                BigDecimal ls =ly.subtract(new BigDecimal(0.05));
                String category=level+"-"+nextLv+"级";

                levelCategory.add(category);
                leakageLy.add(ly.multiply(new BigDecimal(100)).setScale(2,RoundingMode.HALF_UP));
                leakageLs.add(ls.multiply(new BigDecimal(100)).setScale(2,RoundingMode.HALF_UP));
            }
        }

        res.setLevelCategory(levelCategory);
        res.setLeakageLy(leakageLy);
        res.setLeakageLs(leakageLs);
        res.setStandardValue(new BigDecimal(2));

        return res;
    }
    /** 统一时刻的接口结束 */
}
