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


import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.yeejoin.amos.boot.module.cylinder.flc.api.dto.CylinderDateInfoDto;
import com.yeejoin.amos.boot.module.cylinder.flc.api.dto.CylinderTableDto;
import com.yeejoin.amos.boot.module.cylinder.flc.api.entity.*;
import com.yeejoin.amos.boot.module.cylinder.flc.api.mapper.CylinderDateInfoMapper;
import com.yeejoin.amos.boot.module.cylinder.flc.api.mapper.CylinderUnitMapper;
import net.javacrumbs.shedlock.spring.annotation.SchedulerLock;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import org.typroject.tyboot.core.rdbms.service.BaseService;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

@Service
public class CylinderDateInfoServiceImpl extends BaseService<CylinderDateInfoDto, CylinderDateInfo, CylinderDateInfoMapper> {
    private static final Logger logger = LogManager.getLogger(CylinderDateInfoServiceImpl.class);

    @Autowired
    private CylinderUnitServiceImpl cylinderUnitService;

    @Autowired
    private CylinderFillingCheckServiceImpl cylinderFillingCheckService;

    @Autowired
    private CylinderFillingExamineServiceImpl cylinderFillingExamineService;

    @Autowired
    private CylinderFillingRecordServiceImpl cylinderFillingRecordService;

    @Autowired
    private CylinderFillingServiceImpl cylinderFillingService;

    @Autowired
    private CylinderInfoServiceImpl cylinderInfoService;

    @Autowired
    private CylinderInspectionServiceImpl cylinderInspectionService;

    @Autowired
    private CylinderTagsServiceImpl cylinderTagsService;

    @Autowired
    private CylinderUnitMapper cylinderUnitMapper;

    public List<CylinderTableDto> selectTodayDate() {
        List<CylinderTableDto> result = new ArrayList<>();

        List<CylinderUnit> cylinderUnits = cylinderUnitMapper.selectList(null);

        for (CylinderUnit token : cylinderUnits) {
            CylinderTableDto temp = new CylinderTableDto();
            temp.setUnitName(token.getUnitName());
            // 获取气瓶基本信息
            Integer cylinderUnit = 0;
            Integer cylinder = 0;
            Integer tags = 0;
            Integer inspection = 0;
            Integer flling = 0;
            Integer fllingRecord = 0;
            Integer fllingCheck = 0;
            Integer examine = 0;
            Integer total = 0;

            // 获取气瓶基本信息
            List<CylinderDateInfo> list = this.list(new LambdaQueryWrapper<CylinderDateInfo>().eq(CylinderDateInfo::getAppId, token.getAppId()));
            for (CylinderDateInfo info : list) {
                cylinder += info.getCylinderInfo();
                cylinderUnit += info.getCylinderUnit();
                tags += info.getCylinderTagInfo();
                inspection += info.getCylinderInspectionInfo();
                flling += info.getCylinderFillingInfo();
                fllingRecord += info.getCylinderFillingRecordInfo();
                fllingCheck += info.getCylinderFillingCheckInfo();
                examine += info.getCylinderExamineInfo();
                total += info.getCylinderTotal();
            }


            temp.setCylinderUnit(cylinderUnit);
            temp.setCylinderFllingCheckInfo(fllingCheck);
            temp.setCylinderExamineInfo(examine);
            temp.setCylinderFllingInfo(flling);
            temp.setCylinderFllingRecordInfo(fllingRecord);
            temp.setCylinderInspectionInfo(inspection);
            temp.setCylinderTagInfo(tags);
            temp.setCylinderInfo(cylinder);
            temp.setCylinderTotal(total);
            temp.setRegionName(token.getDeveloperAgency());
            result.add(temp);
        }
        return result;
    }


    public Page<CylinderTableDto> selectTodayDatePage(String pageNumber, String pageSize, String regionName, String unitName) {
        Page<CylinderTableDto> page = new Page<>();
        List<CylinderTableDto> result = new ArrayList<>();
        Page<CylinderUnit> cylinderUnitPage = new Page<>(Long.parseLong(pageNumber), Long.parseLong(pageSize));
        LambdaQueryWrapper<CylinderUnit> lambda = new QueryWrapper<CylinderUnit>().lambda();
        if (!ObjectUtils.isEmpty(regionName)) {
            lambda.like(CylinderUnit::getRegionCode, regionName);
        }
        if (!ObjectUtils.isEmpty(unitName)) {
            lambda.like(CylinderUnit::getUnitName, unitName);
        }
        IPage<CylinderUnit> cylinderUnitIPage = cylinderUnitMapper.selectPage(cylinderUnitPage, lambda);
        for (CylinderUnit unit : cylinderUnitIPage.getRecords()) {
            CylinderTableDto temp = new CylinderTableDto();
            temp.setUnitName(unit.getUnitName());
            // 获取气瓶基本信息
            Integer cylinderUnit = 0;
            Integer cylinder = 0;
            Integer tags = 0;
            Integer inspection = 0;
            Integer flling = 0;
            Integer fllingRecord = 0;
            Integer fllingCheck = 0;
            Integer examine = 0;
            Integer total = 0;
            // 获取气瓶基本信息
            List<CylinderDateInfo> list = this.list(new LambdaQueryWrapper<CylinderDateInfo>().eq(CylinderDateInfo::getAppId, unit.getAppId()));
            for (CylinderDateInfo info : list) {
                cylinder += info.getCylinderInfo();
                cylinderUnit += info.getCylinderUnit();
                tags += info.getCylinderTagInfo();
                inspection += info.getCylinderInspectionInfo();
                flling += info.getCylinderFillingInfo();
                fllingRecord += info.getCylinderFillingRecordInfo();
                fllingCheck += info.getCylinderFillingCheckInfo();
                examine += info.getCylinderExamineInfo();
                total += info.getCylinderTotal();
            }
            temp.setCylinderUnit(cylinderUnit);
            temp.setCylinderFllingCheckInfo(fllingCheck);
            temp.setCylinderExamineInfo(examine);
            temp.setCylinderFllingInfo(flling);
            temp.setCylinderFllingRecordInfo(fllingRecord);
            temp.setCylinderInspectionInfo(inspection);
            temp.setCylinderTagInfo(tags);
            temp.setCylinderInfo(cylinder);
            temp.setCylinderTotal(total);
            temp.setRegionName(unit.getRegionName());
            result.add(temp);
        }
        page.setRecords(result);
        page.setTotal(cylinderUnitIPage.getTotal());
        return page;
    }

    /**
     * 每天凌晨两点执行
     */
    @Scheduled(cron = "0 0 2 * * ?")
    @SchedulerLock(name="fixedDelayJobCylinderDataTask",lockAtMostFor = "PT6H")
    public void fixedDelayPageDataJob() {
       this.fixedDelayPageData();
    }


    public void fixedDelayPageData() {
        // 每天更新或者添加昨天的数据
        // 获取时间
        Date date = new Date();
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.DATE, -1);
        //这个时间就是日期往后推一天的结果
        date = calendar.getTime();
        LambdaQueryWrapper<CylinderUnit> lambda = new QueryWrapper<CylinderUnit>().lambda();
        List<CylinderUnit> cylinderUnits = cylinderUnitMapper.selectList(lambda);
        for (CylinderUnit token : cylinderUnits) {
            try {
                SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
                String todayStr = sdf.format(date);
                List<CylinderDateInfo> list = this.list(new LambdaQueryWrapper<CylinderDateInfo>().between(CylinderDateInfo::getSyncDate, todayStr + " 00:00:00", todayStr + " 23:59:59").eq(CylinderDateInfo::getAppId, token.getAppId()));
                if (ObjectUtils.isEmpty(list)) {
                    CylinderDateInfoDto temp = new CylinderDateInfoDto();
                    temp.setSyncDate(date);
                    String appid = token.getAppId();
                    temp.setUnitName(token.getUnitName());
                    temp.setAppId(appid);
                    temp.setDeveloperAgency(token.getDeveloperAgency());
                    // 获取气瓶基本信息
                    Integer cylinder = cylinderInfoService.count(new LambdaQueryWrapper<CylinderInfo>().eq(CylinderInfo::getAppId, appid).between(CylinderInfo::getRecDate, todayStr + " 00:00:00", todayStr + " 23:59:59"));
                    Integer cylinderUnit = cylinderUnitService.count(new LambdaQueryWrapper<CylinderUnit>().eq(CylinderUnit::getAppId, appid).between(CylinderUnit::getRecDate, todayStr + " 00:00:00", todayStr + " 23:59:59"));
                    Integer tags = cylinderTagsService.count(new LambdaQueryWrapper<CylinderTags>().eq(CylinderTags::getAppId, appid).between(CylinderTags::getRecDate, todayStr + " 00:00:00", todayStr + " 23:59:59"));
                    Integer inspection = cylinderInspectionService.count(new LambdaQueryWrapper<CylinderInspection>().eq(CylinderInspection::getAppId, appid).between(CylinderInspection::getRecDate, todayStr + " 00:00:00", todayStr + " 23:59:59"));
                    Integer filling = cylinderFillingService.count(new LambdaQueryWrapper<CylinderFilling>().eq(CylinderFilling::getAppId, appid).between(CylinderFilling::getRecDate, todayStr + " 00:00:00", todayStr + " 23:59:59"));
                    Integer fillingRecord = cylinderFillingRecordService.count(new LambdaQueryWrapper<CylinderFillingRecord>().eq(CylinderFillingRecord::getAppId, appid).between(CylinderFillingRecord::getRecDate, todayStr + " 00:00:00", todayStr + " 23:59:59"));
                    Integer fillingCheck = cylinderFillingCheckService.count(new LambdaQueryWrapper<CylinderFillingCheck>().eq(CylinderFillingCheck::getAppId, appid).between(CylinderFillingCheck::getRecDate, todayStr + " 00:00:00", todayStr + " 23:59:59"));
                    Integer examine = cylinderFillingExamineService.count(new LambdaQueryWrapper<CylinderFillingExamine>().eq(CylinderFillingExamine::getAppId, appid).between(CylinderFillingExamine::getRecDate, todayStr + " 00:00:00", todayStr + " 23:59:59"));
                    Integer total = cylinder + cylinderUnit + tags + inspection + filling + fillingRecord + fillingCheck + examine;
                    temp.setCylinderExamineInfo(examine);
                    temp.setCylinderUnit(cylinderUnit);
                    temp.setCylinderFillingCheckInfo(fillingCheck);
                    temp.setCylinderFillingInfo(filling);
                    temp.setCylinderInspectionInfo(inspection);
                    temp.setCylinderTagInfo(tags);
                    temp.setCylinderInfo(cylinder);
                    temp.setCylinderFillingRecordInfo(fillingRecord);
                    temp.setCylinderTotal(total);
                    this.createWithModel(temp);
                } else {
                    list.forEach(info -> {
                        String appId = token.getAppId();
                        // 获取气瓶基本信息
                        Integer cylinder = cylinderInfoService.count(new LambdaQueryWrapper<CylinderInfo>().eq(CylinderInfo::getAppId, appId).between(CylinderInfo::getSyncDate, todayStr + " 00:00:00", todayStr + " 23:59:59"));
                        Integer cylinderUnit = cylinderUnitService.count(new LambdaQueryWrapper<CylinderUnit>().eq(CylinderUnit::getAppId, appId).between(CylinderUnit::getSyncDate, todayStr + " 00:00:00", todayStr + " 23:59:59"));
                        Integer tags = cylinderTagsService.count(new LambdaQueryWrapper<CylinderTags>().eq(CylinderTags::getAppId, appId).between(CylinderTags::getSyncDate, todayStr + " 00:00:00", todayStr + " 23:59:59"));
                        Integer inspection = cylinderInspectionService.count(new LambdaQueryWrapper<CylinderInspection>().eq(CylinderInspection::getAppId, appId).between(CylinderInspection::getSyncDate, todayStr + " 00:00:00", todayStr + " 23:59:59"));
                        Integer filling = cylinderFillingService.count(new LambdaQueryWrapper<CylinderFilling>().eq(CylinderFilling::getAppId, appId).between(CylinderFilling::getSyncDate, todayStr + " 00:00:00", todayStr + " 23:59:59"));
                        Integer fillingRecord = cylinderFillingRecordService.count(new LambdaQueryWrapper<CylinderFillingRecord>().eq(CylinderFillingRecord::getAppId, appId).between(CylinderFillingRecord::getSyncDate, todayStr + " 00:00:00", todayStr + " 23:59:59"));
                        Integer fillingCheck = cylinderFillingCheckService.count(new LambdaQueryWrapper<CylinderFillingCheck>().eq(CylinderFillingCheck::getAppId, appId).between(CylinderFillingCheck::getSyncDate, todayStr + " 00:00:00", todayStr + " 23:59:59"));
                        Integer examine = cylinderFillingExamineService.count(new LambdaQueryWrapper<CylinderFillingExamine>().eq(CylinderFillingExamine::getAppId, appId).between(CylinderFillingExamine::getSyncDate, todayStr + " 00:00:00", todayStr + " 23:59:59"));
                        Integer total = cylinder + cylinderUnit + tags + inspection + filling + fillingRecord + fillingCheck + examine;
                        info.setCylinderExamineInfo(examine);
                        info.setCylinderUnit(cylinderUnit);
                        info.setCylinderFillingCheckInfo(fillingCheck);
                        info.setCylinderFillingInfo(filling);
                        info.setCylinderInspectionInfo(inspection);
                        info.setCylinderTagInfo(tags);
                        info.setCylinderInfo(cylinder);
                        info.setCylinderFillingRecordInfo(fillingRecord);
                        info.setCylinderTotal(total);
                        this.updateById(info);
                    });
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        logger.info("更新昨日数据成功");
    }


    public void initializeData() {
        // 每天更新或者添加昨天的数据
        Date date = new Date();//取时间
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        // 设置同步时间为当前日期前两天（解决定时任务覆盖问题）
        calendar.setTime(date);
        calendar.add(Calendar.DATE, -2);
        date = calendar.getTime();
        LambdaQueryWrapper<CylinderUnit> lambda = new QueryWrapper<CylinderUnit>().lambda();
        List<CylinderUnit> cylinderUnits = cylinderUnitMapper.selectList(lambda);
        logger.info("清除cylinder_date_info表已有数据");
        this.baseMapper.delete(null);
        for (CylinderUnit token : cylinderUnits) {
            try {
                SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
                String todayStr = sdf.format(date);
                CylinderDateInfoDto temp = new CylinderDateInfoDto();
                temp.setSyncDate(date);
                String appid = token.getAppId();
                temp.setUnitName(token.getUnitName());
                temp.setAppId(appid);
                temp.setDeveloperAgency(token.getDeveloperAgency());
                logger.info("初始化数据时间{}", todayStr);

                // 获取气瓶基本信息
                Integer cylinder = cylinderInfoService.count(new LambdaQueryWrapper<CylinderInfo>().eq(CylinderInfo::getAppId, appid).notLike(CylinderInfo::getRecDate, todayStr));
                Integer cylinderUnit = cylinderUnitService.count(new LambdaQueryWrapper<CylinderUnit>().eq(CylinderUnit::getAppId, appid).notLike(CylinderUnit::getRecDate, todayStr));
                Integer tags = cylinderTagsService.count(new LambdaQueryWrapper<CylinderTags>().eq(CylinderTags::getAppId, appid).notLike(CylinderTags::getRecDate, todayStr));
                Integer inspection = cylinderInspectionService.count(new LambdaQueryWrapper<CylinderInspection>().eq(CylinderInspection::getAppId, appid).notLike(CylinderInspection::getRecDate, todayStr));
                Integer filling = cylinderFillingService.count(new LambdaQueryWrapper<CylinderFilling>().eq(CylinderFilling::getAppId, appid).notLike(CylinderFilling::getRecDate, todayStr));
                Integer fillingRecord = cylinderFillingRecordService.count(new LambdaQueryWrapper<CylinderFillingRecord>().eq(CylinderFillingRecord::getAppId, appid).notLike(CylinderFillingRecord::getRecDate, todayStr));
                Integer fillingCheck = cylinderFillingCheckService.count(new LambdaQueryWrapper<CylinderFillingCheck>().eq(CylinderFillingCheck::getAppId, appid).notLike(CylinderFillingCheck::getRecDate, todayStr));
                Integer examine = cylinderFillingExamineService.count(new LambdaQueryWrapper<CylinderFillingExamine>().eq(CylinderFillingExamine::getAppId, appid).notLike(CylinderFillingExamine::getRecDate, todayStr));
                Integer total = cylinder + cylinderUnit + tags + inspection + filling + fillingRecord + fillingCheck + examine;
                temp.setCylinderExamineInfo(examine);
                temp.setCylinderUnit(cylinderUnit);
                temp.setCylinderFillingCheckInfo(fillingCheck);
                temp.setCylinderFillingInfo(filling);
                temp.setCylinderInspectionInfo(inspection);
                temp.setCylinderTagInfo(tags);
                temp.setCylinderInfo(cylinder);
                temp.setCylinderFillingRecordInfo(fillingRecord);
                temp.setCylinderTotal(total);
                this.createWithModel(temp);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        logger.info("更新昨日数据成功");
    }


}
