package com.tofly.watermeter.custom.service.statisticanalysis.impl;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.tofly.common.core.util.DateUtil;
import com.tofly.common.core.util.StringUtil;
import com.tofly.watermeter.config.ComConstans;
import com.tofly.watermeter.custom.bo.MonthReadMeterDataBO;
import com.tofly.watermeter.custom.entity.statisticanalysis.WaterQuantityInfo;
import com.tofly.watermeter.custom.entity.statisticanalysis.WaterQuantityLoadInfo;
import com.tofly.watermeter.custom.mapper.statisticanalysis.WaterStatisticsMapper;
import com.tofly.watermeter.custom.service.statisticanalysis.IWaterStatisticsService;
import com.tofly.watermeter.custom.util.DateTimeUtil;
import com.tofly.watermeter.util.CallAPIUtil;
import lombok.AllArgsConstructor;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import java.text.ParseException;
import java.time.YearMonth;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;

@Slf4j
@Service
@AllArgsConstructor
public class WaterStatisticsServiceImpl implements IWaterStatisticsService {

    private final WaterStatisticsMapper mapper;

    @Override
    @SneakyThrows
    public HashMap getWaterTrend(String cbpq, String startDate, String endDate) {
        if (StringUtils.isBlank(startDate) || StringUtils.isBlank(endDate)) {
            return null;
        }

        // 格式化查询日期
        YearMonth start = YearMonth.parse(startDate, DateTimeFormatter.ofPattern(DateUtil.DATE_MONTH_FORMAT));
        YearMonth end = YearMonth.parse(endDate, DateTimeFormatter.ofPattern(DateUtil.DATE_MONTH_FORMAT));
        if (end.isBefore(start)) {
            return null;
        }

        HashMap<String, Object> res = new HashMap<>();
        List<String> pqs = Arrays.asList(cbpq.split(ComConstans.CSV));
        if (pqs.size() == 1) {

            for (String pqbm : pqs) {
                List<HashMap<String, String>> trend = mapper.getWaterTrendByQyd(pqbm, startDate, endDate);
                res.put("cbpq",pqbm);
                res.put("trend", trend);
                Map<String,Map<String,String>> hjmap = new HashMap<>();

                for (HashMap<String, String> map:trend) {
                    String cbsj = map.get("cbsj");
                    if(hjmap.containsKey(cbsj)){
                        Map<String,String> hj = hjmap.get(cbsj);
                        hj.put("ysl",(Double.parseDouble(String.valueOf(map.get("ysl")))+Double.parseDouble(hj.get("ysl")))+"");
                    }else {
                        Map<String,String> hj = new HashMap<>();
                        hj.put("ysl",String.valueOf(map.get("ysl")));
                        hj.put("cbsj",cbsj);
                        hjmap.put(cbsj,hj);
                    }
                }
                res.put("summary", hjmap.values());
            }
        } else if (pqs.size() > 1) {
            Map<String,Map<String,String>> hjmap = new HashMap<>();
            for (String pqbm : pqs) {
                List<HashMap<String, String>> trend = mapper.getWaterTrend(pqbm, startDate, endDate);
                HashMap<String, List<HashMap<String, String>>> map = new HashMap<>();
                map.put("trend",trend);
                res.put(pqbm,map);
                for (HashMap<String, String> map1:trend) {
                    String cbsj = map1.get("cbsj");
                    if(hjmap.containsKey(cbsj)){
                        Map<String,String> hj = hjmap.get(cbsj);
                        hj.put("ysl",(Double.parseDouble(String.valueOf(map1.get("ysl")))+Double.parseDouble(hj.get("ysl")))+"");
                    }else {
                        Map<String,String> hj = new HashMap<>();
                        hj.put("ysl",String.valueOf(map1.get("ysl")));
                        hj.put("cbsj",cbsj);
                        hjmap.put(cbsj,hj);
                    }
                }
            }
            Map map = new HashMap<>();
            map.put("trend",hjmap.values());
            res.put("summary", map);
        }
        return res;
    }

    @Override
    public List getWaterAnalysis(String cbpq, String queryDate) {
        if(StringUtils.isNotEmpty(queryDate)){
            queryDate = queryDate.replaceAll("-","");
        }
        List res = null;
        if (!StringUtils.isBlank(cbpq) && !StringUtils.isBlank(queryDate)) {
            List<String> pqList = Arrays.asList(cbpq.split(ComConstans.CSV));
            res = new ArrayList<>();
            if (pqList.size() > 0) {
                HashMap<String, String> map = null;
                for (String pq : pqList) {
                    map = mapper.getYWaterAnalysisByPqAndYearMonth(pq, queryDate);
                    if (map != null) {
                        map.put("cbpq", pq);
                        res.add(map);
                    }
                }
                return res;
            }
        }
        return res;
    }



    @Override
    public Page getWaterInquire(Page page,String yhbh, String queryYear) {
        Page<HashMap<String, Object>> res = null;
        if (StringUtils.isBlank(queryYear)) {
            return res;
        } else {
            res = mapper.getFuzzyQueryUsers(page, yhbh);
            List<HashMap<String, Object>> users = res.getRecords();
            if (users.size() > 0) {
                List<HashMap<String,Object>> resList = new ArrayList<>();
                for (HashMap<String,Object> user : users) {
                    HashMap<String, Object> hashMap = new HashMap<>();
                    List<String> years = Arrays.asList(queryYear.split(ComConstans.CSV)).stream().sorted().collect(Collectors.toList());
                    List<HashMap<String,Object>> arrayList = new ArrayList<>();
                    for (String year : years) {
                        String start = year + "-01";
                        String end = year + "-12";
                        List<HashMap<String, String>> list = mapper.getWaterInquire(String.valueOf(user.get("yhbh")), start, end);
                        HashMap<String, Object> map = new HashMap<>();
                        map.put("year",year);
                        if (list != null && list.size() > 0) {
                            map.put("InquireList",list);
                        }
                        arrayList.add(map);
                    }
                    // yhbh,yhxm
                    hashMap.putAll(user);
                    hashMap.put("queryData",arrayList);
                    resList.add(hashMap);
                }
                res.setRecords(resList);
                return res;
            }
        }
        return res;
    }

    @Override
    public boolean synchroWaterQuantityData() {
        return synchroWaterQuantityData(null,null);
    }

    @Override
    public boolean synchroWaterQuantityData(String begDate,String endDate) {
        String startTime = "20190101";

        String meterReadData = "api/Business/MeterReadData";

        log.info("-----------------------------start----------------------------");
        String begTime = null;
        String endTime = null;
        try {
            if(StringUtils.isNotEmpty(begDate)){
                begTime=begDate;
            }else {
                begTime = mapper.getCWRQMaxTime();
                if (StringUtils.isEmpty(begTime)) {
                    begTime = startTime;
                } else {
                    begTime = DateTimeUtil.monthToDayStr(begTime, DateTimeUtil.MONTHS_YEARS_FORMAT, DateTimeUtil.DAY_MONTHS_YEARS_FORMAT);
                    begTime = DateTimeUtil.addMonth(begTime, DateTimeUtil.DAY_MONTHS_YEARS_FORMAT, 1);
                }
            }
            endTime = DateTimeUtil.addMonth(begTime, DateTimeUtil.DAY_MONTHS_YEARS_FORMAT, 1);

        } catch (ParseException e) {
            e.printStackTrace();
            return false;
        }
        int pc = 500;
        //当前时间往后推一个月
        String dateTime = null;
        if(StringUtils.isNotEmpty(endDate)){
            dateTime = endDate;
        }else {
            dateTime = DateTimeUtil.getDayDateStr(DateTimeUtil.DAY_MONTHS_YEARS_FORMAT);
        }
        final long[] finalI = {mapper.getMaxId()==null?0:mapper.getMaxId()};
        while(Integer.parseInt(dateTime)>=Integer.parseInt(endTime)){
            WaterQuantityLoadInfo info = new WaterQuantityLoadInfo();
            info.setAction("query");
            info.setCbrqStart(begTime);
            info.setCbrqEnd(endTime);
            String cwrq = begTime.substring(0, begTime.length() - 2);
            try {
                Map map = CallAPIUtil.callAPIUtil(info,meterReadData);
                if (StringUtil.isNull(map)) {
                    begTime = endTime;
                    endTime = DateTimeUtil.addMonth(endTime, DateTimeUtil.DAY_MONTHS_YEARS_FORMAT, 1);
                    continue;
                }
                log.info(begTime+"   "+endTime);
                String jsonString = JSONObject.toJSONString(map.get("data"));
                List<WaterQuantityInfo> wqs = JSONObject.parseArray(jsonString, WaterQuantityInfo.class);
                if(wqs!=null&&!wqs.isEmpty()) {
                    int num = wqs.size() / pc;
                    int delcount = mapper.deleteQfcbywlsCwrq(DateTimeUtil.monthToDayStr(begTime, DateTimeUtil.DAY_MONTHS_YEARS_FORMAT, DateTimeUtil.MONTHS_YEARS_FORMAT));
                    log.info("=============delete=============>" + begTime +"   "+delcount);
                    log.info("==========================>" + wqs.size());
                    List<String> months = DateTimeUtil.continuityFrontMonth(begTime, DateTimeUtil.DAY_MONTHS_YEARS_FORMAT, DateTimeUtil.MONTHS_YEARS_FORMAT, -1, 3, 1);
                    List<String> years = DateTimeUtil.continuityFrontMonth(begTime, DateTimeUtil.DAY_MONTHS_YEARS_FORMAT, DateTimeUtil.MONTHS_YEARS_FORMAT, -1, 3, 2);
                    int yearmonth = Integer.parseInt(begTime);
                    for (int j = 0; j < num + 1; j++) {
                        List<WaterQuantityInfo> cp = null;
                        if (j < num) {
                            cp = wqs.subList(j * pc, (j + 1) * pc);
                        } else {
                            cp = wqs.subList(j * pc, wqs.size());
                        }
                        log.info("---------------------->" + cp.size());
                        cp.forEach(r -> {
                            try {
                                finalI[0]++;
                                r.setId(finalI[0]);
                                r.setMonths(months);
                                r.setYears(years);
                                r.setYearMonth(yearmonth);
                                r.setScwrq(DateTimeUtil.addMonth(r.getCwrq(), DateTimeUtil.MONTHS_YEARS_FORMAT, -1));
                            } catch (ParseException e) {
                                e.printStackTrace();
                            }
                        });
                        long btm = System.currentTimeMillis();
                        int count = mapper.insertWaterQuantity(cp);
                        log.info(count + "==                         "+((System.currentTimeMillis()-btm)/(1000)));
                    }

                }
                begTime = endTime;
                endTime = DateTimeUtil.addMonth(endTime, DateTimeUtil.DAY_MONTHS_YEARS_FORMAT, 1);
            } catch (Exception e) {
                e.printStackTrace();
                return false;
            }
            if(2021<= Integer.parseInt(begTime.substring(0,4))) {
                int row = mapper.insertQfcbycslData(cwrq);
                log.info(cwrq + "生成的异常数据条数：：" + row);
            }

        }

        return true;
    }



    @Override
    public List getWaterFluctuationDetail(String khbh, String queryDate) {
        return mapper.getWaterFluctuationDetail(khbh,queryDate);
    }

    @Override
    public List getWaterTrendDetail(String cbpq, String queryDate) {
        return mapper.getWaterTrendDetail(cbpq,queryDate);
    }

    @Override
    public Page getWaterTrendWaterDetail(Page page,String cbpq, String cbqyd, String queryDate) {
        return mapper.getWaterTrendWaterDetail(page,cbpq,cbqyd,queryDate);
    }

    @Override
    public Page getWaterAnalysisDetail(Page page,String cbpq, String queryDate, String queryType) {
        Page<HashMap<String,String>> res = null;
        if (StringUtils.isBlank(cbpq) || StringUtils.isBlank(queryDate) || StringUtils.isBlank(queryType)) {
            return res;
        } else {
            // isPass 0为合格 1为不合格（异常）
            if ("zc".equals(queryType)) {
                res = mapper.getWaterAnalysisDetail(page,cbpq,queryDate,"0");
                return res;
            } else if ("yc".equals(queryType)){
                res = mapper.getWaterAnalysisDetail(page,cbpq,queryDate,"1");
                return res;
            }
        }
        return res;
    }

    @Override
    public List getWaterAnalysisDetailAndYOM(String khbh, String startDate, String endDate, String queryType) {
        List<HashMap<String,String>> res = null;
        if (StringUtils.isBlank(khbh)  || StringUtils.isBlank(queryType) || StringUtils.isBlank(startDate) || StringUtils.isBlank(endDate) ) {
            return res;
        } else {
            YearMonth start = YearMonth.parse(startDate, DateTimeFormatter.ofPattern(DateUtil.DATE_MONTH_FORMAT));
            YearMonth end = YearMonth.parse(endDate, DateTimeFormatter.ofPattern(DateUtil.DATE_MONTH_FORMAT));
            if (end.isBefore(start)) {
                return res;
            }
            if ("tbcx".equals(queryType)) {
                res = new ArrayList();
                YearMonth query = start;
                YearMonth queryEnd = end.plusYears(1L);
                res = mapper.getYoYWaterByKHBH(khbh,startDate,endDate);
//                while (query.equals(queryEnd)){
//                    Integer dysl = mapper.getYoYWaterByKHBH(khbh, query.toString().replaceAll("-",""));
//                    HashMap<String, String> hashMap = new HashMap<>();
//                    hashMap.put("dysl",String.valueOf(dysl));
//                    hashMap.put("cbrq",query.toString());
//                    res.add(hashMap);
//                    query = query.plusYears(1L);
//                }
                return res;
            } else if ("hbcx".equals(queryType)) {
                return mapper.getMoMWaterByKHBH(khbh,startDate,endDate);
            }
        }
        return res;
    }

    @Override
    public HashMap getWaterFluctuation(String queryType, String queryDate, String numberParam) {
        HashMap<String,Object> map = null;
        if (!StringUtils.isBlank(queryType) && !StringUtils.isBlank(queryDate)) {
            map = new HashMap<>();
            numberParam = numberParam == null ? "30" : numberParam;

            List<MonthReadMeterDataBO> upList = mapper.getMonthReadMeterData(queryDate,"up",numberParam);
            if (upList.size() > 0 ) {
                Map<String, List<MonthReadMeterDataBO>> up = getUpListGruupByQueryType(upList, queryType);
                if (up != null && !up.isEmpty()) {
                    map.put("up", up);
                }
            }

            List<MonthReadMeterDataBO> downList = mapper.getMonthReadMeterData(queryDate,"down",numberParam);
            if (downList.size() > 0) {
                Map<String, List<MonthReadMeterDataBO>> down = getDownListGruupByQueryType(downList, queryType);
                if (down != null && !down.isEmpty()) {
                    map.put("down", down);
                }
            }
//            if (monthRead.size() > 0) {
//                List<MonthReadMeterDataBO> upList = monthRead.stream().filter(x -> x.getSysl() != null && !"0".equals(x.getSysl())
//                        && Double.parseDouble(x.getSjbl()) > 0).collect(Collectors.toList());
//                List<MonthReadMeterDataBO> downList = monthRead.stream().filter(x -> x.getSysl() != null && !"0".equals(x.getSysl())
//                        && Double.parseDouble(x.getSjbl()) < 0).collect(Collectors.toList());
//            }
                return map;
            }
        return map;
    }


    private Map<String, List<MonthReadMeterDataBO>> getDownListGruupByQueryType(List<MonthReadMeterDataBO> downList, String queryType) {
        if ("cbpq".equals(queryType)) {
            return downList.stream().sorted(Comparator.comparing(MonthReadMeterDataBO::getSjbl))
                    .collect(Collectors.groupingBy(MonthReadMeterDataBO::getCbpq));
        } else if ("sbkj".equals(queryType)) {
            return downList.stream().sorted(Comparator.comparing(MonthReadMeterDataBO::getSjbl))
                    .collect(Collectors.groupingBy(MonthReadMeterDataBO::getSbkj));
        } else if ("ysxz".equals(queryType)) {
            return downList.stream().sorted(Comparator.comparing(MonthReadMeterDataBO::getSjbl))
                    .collect(Collectors.groupingBy(MonthReadMeterDataBO::getYsxz));
        }
        return null;
    }

    private Map<String, List<MonthReadMeterDataBO>> getUpListGruupByQueryType(List<MonthReadMeterDataBO> upList, String queryType) {
        if ("cbpq".equals(queryType)) {
            return upList.stream().sorted(Comparator.comparing(MonthReadMeterDataBO::getSjbl).reversed())
                    .collect(Collectors.groupingBy(MonthReadMeterDataBO::getCbpq));
        } else if ("sbkj".equals(queryType)) {
            return upList.stream().sorted(Comparator.comparing(MonthReadMeterDataBO::getSjbl).reversed())
                    .collect(Collectors.groupingBy(MonthReadMeterDataBO::getSbkj));
        } else if ("ysxz".equals(queryType)) {
            return upList.stream().sorted(Comparator.comparing(MonthReadMeterDataBO::getSjbl).reversed())
                    .collect(Collectors.groupingBy(MonthReadMeterDataBO::getYsxz));
        }
        return null;
    }

}
