package com.yeejoin.amos.boot.module.tzs.flc.biz.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.yeejoin.amos.boot.module.tzs.flc.api.dto.CylinderAreaDataDto;
import com.yeejoin.amos.boot.module.tzs.flc.api.dto.CylinderFillingUnloadDataDto;
import com.yeejoin.amos.boot.module.tzs.flc.api.dto.CylinderInfoDataDto;
import com.yeejoin.amos.boot.module.tzs.flc.api.dto.CylinderIntegrityDataDto;
import com.yeejoin.amos.boot.module.tzs.flc.api.dto.CylinderUnitDataDto;
import com.yeejoin.amos.boot.module.tzs.flc.api.entity.CylinderFillingUnloadData;
import com.yeejoin.amos.boot.module.tzs.flc.api.entity.CylinderInfo;
import com.yeejoin.amos.boot.module.tzs.flc.api.entity.CylinderInfoData;
import com.yeejoin.amos.boot.module.tzs.flc.api.entity.CylinderIntegrityData;
import com.yeejoin.amos.boot.module.tzs.flc.api.entity.CylinderUnit;
import com.yeejoin.amos.boot.module.tzs.flc.api.entity.CylinderUnitData;
import com.yeejoin.amos.boot.module.tzs.flc.api.mapper.CylinderInfoMapper;
import com.yeejoin.amos.boot.module.tzs.flc.api.service.ICylinderInfoService;
import com.yeejoin.amos.boot.module.tzs.flc.api.dto.CylinderInfoDto;
import com.yeejoin.amos.feign.systemctl.Systemctl;
import com.yeejoin.amos.feign.systemctl.model.RegionModel;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.typroject.tyboot.core.rdbms.service.BaseService;
import org.springframework.stereotype.Service;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

/**
 * 气瓶基本信息服务实现类
 *
 * @author system_generator
 * @date 2021-12-14
 */
@Service
public class CylinderInfoServiceImpl extends BaseService<CylinderInfoDto,CylinderInfo,CylinderInfoMapper> implements ICylinderInfoService {


    @Autowired
    CylinderUnitServiceImpl cylinderUnitServiceImpl;

    @Autowired
    CylinderUnitDataServiceImpl cylinderUnitDataServiceImpl;

    @Autowired
    CylinderInfoDataServiceImpl cylinderInfoDataServiceImpl;

    @Autowired
    CylinderTagsServiceImpl cylinderTagsServiceImpl;

    @Autowired
    CylinderFillingServiceImpl cylinderFillingServiceImpl;

    @Autowired
    CylinderIntegrityDataServiceImpl cylinderIntegrityDataServiceImpl;

    @Autowired
    CylinderFillingRecordServiceImpl cylinderFillingRecordServiceImpl;

    @Autowired
    CylinderFillingCheckServiceImpl cylinderFillingCheckServiceImpl;

    @Autowired
    CylinderAreaDataServiceImpl cylinderAreaDataServiceImpl;

    @Autowired
    CylinderFillingUnloadDataServiceImpl cylinderFillingUnloadDataServiceImpl;


    /**
     * 分页查询
     */
    public Page<CylinderInfoDto> queryForCylinderInfoPage(Page<CylinderInfoDto> page)   {
        return this.queryForPage(page, null, false);
    }

    /**
     * 列表查询 示例
     */
    public List<CylinderInfoDto> queryForCylinderInfoList()   {
        return this.queryForList("" , false);
    }

    @Override
    public Map<String, Long> queryNumAndOutOfDateNum(Long unitId) {
        return baseMapper.queryNumAndOutOfDateNum(unitId);
    }


    /**
     * 获取上个月气瓶总量
     * @return
     */
    public Integer getLastMonthInfoTotal(String regionCode) {
        return baseMapper.getLastMonthInfoTotal(regionCode);
    }

    /**
     * 获取上上个月气瓶总量
     * @return
     */
    public Integer getMonthBeforeLastInfoTotal(String regionCode) {
        return baseMapper.getMonthBeforeLastInfoTotal(regionCode);
    }

    public Integer getInfoTotalByRegionCode(String regionCode) {
        return baseMapper.getInfoTotalByRegionCode(regionCode);
    }

    public Double queryIntegirtyByAppId(String appId) {
        return this.baseMapper.queryIntegirtyByAppId(appId);
    }

    public Integer getWarnNum(String code) {
        return baseMapper.getWarnNum(code);
    }

    @Scheduled(cron = "0 0 2 * * ?") //每天凌晨两点执行
    public Boolean synFillingUnloadData() {
        cylinderFillingUnloadDataServiceImpl.remove(new LambdaQueryWrapper<CylinderFillingUnloadData>());
        Collection<RegionModel> regions = Systemctl.regionClient.queryForTree(null).getResult();
        List<String> regionCodes = new ArrayList<String>();
        regions.stream().forEach(t -> {
            this.addRegionsList(regionCodes,t);
        });
        regionCodes.stream().forEach(r -> {
            Calendar now = Calendar.getInstance();
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
            for(int i = 0 ; i < 30 ; i ++) {
                now.add(Calendar.DATE,-1);
                CylinderFillingUnloadDataDto temp = new CylinderFillingUnloadDataDto();
                Double fillingSum = cylinderFillingRecordServiceImpl.getFillingSum(r,now.getTime());
                Double unloadSum = 0d;
                temp.setFillingSum(fillingSum);
                temp.setRegionCode(r);
                temp.setStatisDate(now.getTime());
                temp.setStatisDateStr(sdf.format(now.getTime()));
                temp.setUnloadSum(unloadSum);
                cylinderFillingUnloadDataServiceImpl.createWithModel(temp);

            }
        });

        return true;
    }

    private void addRegionsList(List<String> regionList, RegionModel region) {
        regionList.add(region.getRegionCode() + "");
        if (region.getChildren() != null) {
            region.getChildren().stream().forEach(c -> {
                addRegionsList(regionList, c);
            });
        }
    }

    private void addRegionsList1(List<RegionModel> regionList, RegionModel region) {
        regionList.add(region);
        if(region.getChildren() != null) {
            region.getChildren().stream().forEach(c -> {
                addRegionsList1(regionList,c);
            });
        }
    }

    @Scheduled(cron = "0 0 2 * * ?") //每天凌晨两点执行
    public Boolean synAreaData() {
        Collection<RegionModel> regions = Systemctl.regionClient.queryForTree(null).getResult();
        List<RegionModel> regionCodes = new ArrayList<RegionModel>();
        regions.stream().forEach(t -> {
            this.addRegionsList1(regionCodes,t);
        });
        regionCodes.stream().forEach(r -> {
            CylinderAreaDataDto temp = new CylinderAreaDataDto();
            temp.setAreaName(r.getRegionName());
            String code = r.getRegionCode() +"";
            Integer cylinderTotal = this.getInfoTotalByRegionCode(code);
            Integer cylinderUnitTotal = cylinderUnitServiceImpl.getUnitTotalByRegionCode(code);
            Integer cylinderUnitWarn = cylinderUnitServiceImpl.getWarnNum(code);
            Integer cylinderInfoWarn = this.getWarnNum(code);
            Integer warmTotal = cylinderUnitWarn + cylinderInfoWarn;
            String parentCode = "";
            if("610000".equals(code)) {
                parentCode = "-1";
            } else if(!"00".equals(code.substring(4,6))) {
                parentCode = code.substring(0,4) + "00";
            } else {
                parentCode = "610000";
            }
            temp.setCylinderNum(Long.valueOf(cylinderTotal));
            temp.setParentRegionCode(parentCode);
            temp.setRegionCode(r.getRegionCode()+"");
            temp.setUnitNum(Long.valueOf(cylinderUnitTotal));
            temp.setWarnNum(Long.valueOf(warmTotal));
            cylinderAreaDataServiceImpl.createWithModel(temp);
        });

        return  true;
    }

    @Scheduled(cron = "0 0 2 * * ?") //每天凌晨两点执行
    public Boolean addIntegrityData() {
        // 每日清空再重新获取数据
        cylinderIntegrityDataServiceImpl.remove(new LambdaQueryWrapper<CylinderIntegrityData>());

        Collection<RegionModel> regions = Systemctl.regionClient.queryForTree(null).getResult();
        List<String> regionCodes = new ArrayList<String>();
        regions.stream().forEach(t -> {
            this.addRegionsList(regionCodes,t);
        });
        regionCodes.stream().forEach(u -> {
            String regionCode = u;
            List<CylinderUnit> unitlist = cylinderUnitServiceImpl.list(new LambdaQueryWrapper<CylinderUnit>().like(CylinderUnit::getRegionCode,u));
            List<CylinderIntegrityDataDto> tempList = new LinkedList<>();

            unitlist.stream().forEach(t -> {
                CylinderIntegrityDataDto temp = new CylinderIntegrityDataDto();
                String appId = t.getAppId();
                Double totalIntegirty = 0d;
                // tz_cylinder_info
                Double unitIntegirty = t.getIntegrity();
                //tz_cylinder_tags
                Double tagIntegirty = cylinderTagsServiceImpl.queryIntegirtyByAppId(appId);
                //tz_cylinder_info
                Double infoIntegirty = this.queryIntegirtyByAppId(appId);
                // tz_cylinder_filling_record 30天内
                Double recordIntegirty = cylinderFillingRecordServiceImpl.queryIntegirtyByAppId(appId);
                //tz_cylinder_filling  30天内
                Double fillingIntegirty = cylinderFillingServiceImpl.queryIntegirtyByAppId(appId);
                //tz_cylinder_filling_check 30天内
                Double checkIntegirty = cylinderFillingCheckServiceImpl.queryIntegirtyByAppId(appId);
                totalIntegirty = (unitIntegirty + tagIntegirty+infoIntegirty+recordIntegirty+fillingIntegirty+checkIntegirty) / 6;
                BigDecimal bg = new BigDecimal(totalIntegirty);
                totalIntegirty = bg.setScale(4, BigDecimal.ROUND_HALF_UP).doubleValue() * 100;

                temp.setAppId(appId);
                temp.setRegionCode(u);
                temp.setIntegrity(totalIntegirty);
                temp.setUnitName(t.getUnitName());

                // 判断list 是否达到5个，如果达到则对比最后一个进行替换
                if(tempList.size() == 5) {
                    if(tempList.get(0).getIntegrity() < totalIntegirty) {
                        tempList.set(0,temp);
                    }
                } else {
                    tempList.add(temp);
                }
                Collections.sort(tempList, new Comparator<CylinderIntegrityDataDto>() {
                    @Override
                    public int compare(CylinderIntegrityDataDto o1, CylinderIntegrityDataDto o2) {
                        //升序
                        return o1.getIntegrity().compareTo(o2.getIntegrity());
                    }
                });
            });
            tempList.stream().forEach(t -> {
                cylinderIntegrityDataServiceImpl.createWithModel(t);
            });


        });
        return true;
    }



    @Scheduled(cron = "0 0 2 * * ?") //每天凌晨两点执行
    public Boolean getCylinderUnitInfo() {
        // 每日清空再重新获取数据
        cylinderUnitDataServiceImpl.remove(new LambdaQueryWrapper<CylinderUnitData>());

        Collection<RegionModel> regions = Systemctl.regionClient.queryForTree(null).getResult();
        List<String> regionCodes = new ArrayList<String>();
        regions.stream().forEach(t -> {
            this.addRegionsList(regionCodes,t);
        });
        regionCodes.stream().forEach(u -> {
            String regionCode = u;
            Integer cylinderUnitTotal = cylinderUnitServiceImpl.getUnitTotalByRegionCode(regionCode);
            Double lastUnitTotal = Double.valueOf(cylinderUnitServiceImpl.getLastMonthUnitTotal(regionCode));
            Double monthUnitLastInfo = Double.valueOf(cylinderUnitServiceImpl.getMonthBeforeLastUnitTotal(regionCode));
            Double percent = 0d;
            if(monthUnitLastInfo != 0) {
                percent = (lastUnitTotal - monthUnitLastInfo) / monthUnitLastInfo;
                BigDecimal bg = new BigDecimal(percent);
                percent = bg.setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();
            }
            CylinderUnitDataDto temp = new CylinderUnitDataDto();
            temp.setChangeSum((long) (lastUnitTotal - monthUnitLastInfo));
            temp.setChangePercent( (int )(percent*100) + "");
            temp.setRegionCode(regionCode);
            temp.setTotalSum((long) cylinderUnitTotal);
            cylinderUnitDataServiceImpl.createWithModel(temp);
        });
        return true;
    }

    @Scheduled(cron = "0 0 2 * * ?") //每天凌晨两点执行
    public Boolean getCylinderInfo() {
        // 每日清空再重新获取数据
        cylinderInfoDataServiceImpl.remove(new LambdaQueryWrapper<CylinderInfoData>());
        Collection<RegionModel> regions = Systemctl.regionClient.queryForTree(null).getResult();
        List<String> regionCodes = new ArrayList<String>();
        regions.stream().forEach(t -> {
            this.addRegionsList(regionCodes,t);
        });

        List<CylinderUnit> units = cylinderUnitServiceImpl.list();
        regionCodes.stream().forEach(u -> {
            CylinderInfoDataDto temp = new CylinderInfoDataDto();
            String regionCode = u;
            Integer cylinderTotal = this.getInfoTotalByRegionCode(regionCode);
            Double lastInfoTotal = Double.valueOf(this.getLastMonthInfoTotal(regionCode));
            Double monthBeforeLastInfo = Double.valueOf(this.getMonthBeforeLastInfoTotal(regionCode));
            Double percent = 0d;
            if(monthBeforeLastInfo != 0) {
                percent = (lastInfoTotal - monthBeforeLastInfo) / monthBeforeLastInfo;
                BigDecimal bg = new BigDecimal(percent);
                percent = bg.setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();
            }
            temp.setChangeSum((long) (lastInfoTotal - monthBeforeLastInfo));
            temp.setChangePercent((int )(percent*100)+"");
            temp.setRegionCode(regionCode);
            temp.setTotalSum((long) cylinderTotal);
            cylinderInfoDataServiceImpl.createWithModel(temp);
        });
        return true;
    }
}