package com.mortals.xhx.daemon.task;

import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import com.mortals.framework.common.Rest;
import com.mortals.framework.exception.AppException;
import com.mortals.framework.service.ICacheService;
import com.mortals.framework.service.ITask;
import com.mortals.framework.service.ITaskExcuteService;
import com.mortals.xhx.common.code.AccessTypeEnum;
import com.mortals.xhx.common.code.YesNoEnum;
import com.mortals.xhx.common.key.RedisKey;
import com.mortals.xhx.common.keys.RedisCacheKeys;
import com.mortals.xhx.common.pdu.RespData;
import com.mortals.xhx.common.pdu.site.SitePdu;
import com.mortals.xhx.feign.site.ISiteFeign;
import com.mortals.xhx.module.access.model.AccessEntity;
import com.mortals.xhx.module.access.model.AccessQuery;
import com.mortals.xhx.module.access.model.AccessStatLogEntity;
import com.mortals.xhx.module.access.service.AccessService;
import com.mortals.xhx.module.access.service.AccessStatLogService;
import com.mortals.xhx.module.ph.model.PhQueueStatEntity;
import com.mortals.xhx.module.ph.model.PhQueueStatQuery;
import com.mortals.xhx.module.ph.service.PhQueueStatService;
import com.mortals.xhx.module.pj.model.PjEvaluateStatEntity;
import com.mortals.xhx.module.pj.model.PjEvaluateStatQuery;
import com.mortals.xhx.module.pj.service.PjEvaluateStatService;
import com.mortals.xhx.module.stat.model.StatEntity;
import com.mortals.xhx.module.stat.service.StatService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StopWatch;

import java.util.*;
import java.util.stream.Collectors;

import static java.util.stream.Collectors.collectingAndThen;
import static java.util.stream.Collectors.toCollection;

/**
 * 站点评价统计任务
 *
 * @author: zxfei
 * @date: 2022/3/9 15:19
 */
@Slf4j
@Service("SiteStatTask")
public class SiteStatTaskImpl implements ITaskExcuteService {


    @Autowired
    private ISiteFeign siteFeign;
    @Autowired
    private PjEvaluateStatService pjEvaluateStatService;
    @Autowired
    private PhQueueStatService phQueueStatService;
    @Autowired
    private StatService statService;
    @Autowired
    private ICacheService cacheService;

    @Autowired
    private AccessService accessService;
    @Autowired
    private AccessStatLogService accessStatLogService;


    @Override
    public void excuteTask(ITask task) throws AppException {
        log.info("站点评价统计任务");
        //统计最近一周
        statByDate();
        log.info("站点统计缓存任务");
        //统计排号与评价 部门，等字典顺序记录次数
        updateSiteCache();
    }

    private void statByDate() {
        List<SitePdu> sitePduList = getStatSiteList();
        for (SitePdu site : sitePduList) {
            if (ObjectUtils.isEmpty(site.getId())) continue;
            StopWatch allStopWatch = new StopWatch("allStopWatch");
            StopWatch pjqStopWatch = new StopWatch("pjqStopWatch");
            StopWatch pdjStopWatch = new StopWatch("pdjStopWatch");
            allStopWatch.start();

            AccessStatLogEntity statLogAllEntity = new AccessStatLogEntity();
            statLogAllEntity.initAttrValue();
            statLogAllEntity.setCreateUserId(1L);
            statLogAllEntity.setCreateTime(new Date());
            statLogAllEntity.setSiteId(site.getId());
            statLogAllEntity.setSiteCode(site.getSiteCode());
            statLogAllEntity.setSiteName(site.getSiteName());
            statLogAllEntity.setStatStartTime(new Date());
            statLogAllEntity.setType(AccessTypeEnum.全部.getValue());

            pjqStopWatch.start();

            AccessStatLogEntity statLogEntity = new AccessStatLogEntity();
            statLogEntity.initAttrValue();
            statLogEntity.setCreateUserId(1L);
            statLogEntity.setCreateTime(new Date());
            statLogEntity.setSiteId(site.getId());
            statLogEntity.setSiteCode(site.getSiteCode());
            statLogEntity.setSiteName(site.getSiteName());

            AccessQuery accessQuery = new AccessQuery();
            accessQuery.setSiteId(site.getId() == null ? 0L : site.getId());
            AccessEntity accessEntity = accessService.selectOne(accessQuery);
            if (!ObjectUtils.isEmpty(accessEntity)) {
                statLogEntity.setAccessId(accessEntity.getId());
            }

            statLogEntity.setStatStartTime(new Date());
            statLogEntity.setType(AccessTypeEnum.评价器.getValue());

            int range = 4;
            for (int i = 0; i < range; i++) {

                DateTime beforeDate = DateUtil.offsetDay(new Date(), -i);
                int year = beforeDate.year();
                int month = beforeDate.month() + 1;
                int day = beforeDate.dayOfMonth();

                PjEvaluateStatEntity sitestatEntity = new PjEvaluateStatEntity();
                sitestatEntity.initAttrValue();
                sitestatEntity.setSiteId(site.getId());
                sitestatEntity.setSiteName(site.getSiteName());
                sitestatEntity.setSiteCode(site.getSiteCode());

                sitestatEntity.setYear(year);
                sitestatEntity.setMonth(month);
                sitestatEntity.setDay(day);
                //设置年月日
                pjEvaluateStatService.updateSitePjStat(sitestatEntity, null);
            }
            pjqStopWatch.stop();
            statLogEntity.setStatEndTime(new Date());
            statLogEntity.setDuration(pjqStopWatch.getLastTaskTimeMillis());
            accessStatLogService.save(statLogEntity, null);

            pdjStopWatch.start();
            statLogEntity.setStatStartTime(new Date());
            statLogEntity.setType(AccessTypeEnum.排队机.getValue());
            for (int i = 0; i < range; i++) {

                DateTime beforeDate = DateUtil.offsetDay(new Date(), -i);
                int year = beforeDate.year();
                int month = beforeDate.month() + 1;
                int day = beforeDate.dayOfMonth();
                //设置排号
                PhQueueStatEntity phQueueStatEntity = new PhQueueStatEntity();
                phQueueStatEntity.initAttrValue();
                phQueueStatEntity.setSiteId(site.getId());
                phQueueStatEntity.setSiteName(site.getSiteName());
                phQueueStatEntity.setSiteCode(site.getSiteCode());

                phQueueStatEntity.setYear(year);
                phQueueStatEntity.setMonth(month);
                phQueueStatEntity.setDay(day);
                phQueueStatService.updateSitePhStat(phQueueStatEntity, null);

            }
            pdjStopWatch.stop();
            statLogEntity.setStatEndTime(new Date());
            statLogEntity.setDuration(pjqStopWatch.getLastTaskTimeMillis());
            accessStatLogService.save(statLogEntity, null);

            for (int i = 0; i < range; i++) {
                DateTime beforeDate = DateUtil.offsetDay(new Date(), -i);
                int year = beforeDate.year();
                int month = beforeDate.month() + 1;
                int day = beforeDate.dayOfMonth();
                StatEntity statEntity = new StatEntity();
                statEntity.initAttrValue();
                statEntity.setSiteId(site.getId());
                statEntity.setSiteName(site.getSiteName());
                statEntity.setSiteCode(site.getSiteCode());

                statEntity.setYear(year);
                statEntity.setMonth(month);
                statEntity.setDay(day);
                //设置年月日
                statService.updateSiteStat(statEntity, null);

            }

            allStopWatch.stop();
            statLogAllEntity.setStatEndTime(new Date());
            statLogAllEntity.setDuration(pjqStopWatch.getLastTaskTimeMillis());
            accessStatLogService.save(statLogAllEntity, null);
        }
    }


    private List<SitePdu> getStatSiteList() {
        AccessQuery accessQuery = new AccessQuery();
        accessQuery.setTagNotList(Arrays.asList(""));
        List<AccessEntity> accessEntities = accessService.find(accessQuery);

        List<SitePdu> sitePduList = new ArrayList<>();
        for (AccessEntity accessEntity : accessEntities) {
            if(accessEntity.getSiteId()==1L){
                SitePdu site = new SitePdu();
                site.setId(accessEntity.getSiteId());
                site.setSiteName(accessEntity.getSiteName());
                site.setSiteCode(accessEntity.getSiteCode());
                site.setAreaCode(accessEntity.getAreaCode());
                sitePduList.add(site);
                continue;
            }
            SitePdu sitePdu = new SitePdu();
            sitePdu.setId(accessEntity.getSiteId());
            Rest<List<SitePdu>> sitesRest = siteFeign.getFlatSitesBySiteId(sitePdu);
            if (YesNoEnum.YES.getValue() == sitesRest.getCode()) {
                sitePduList.addAll(sitesRest.getData());
            }
        }

        if (!ObjectUtils.isEmpty(sitePduList)) {
            sitePduList = sitePduList.stream().collect(
                    collectingAndThen(
                            toCollection(() -> new TreeSet<>(Comparator.comparing(SitePdu::getId))), ArrayList::new));
        }
        return sitePduList;
    }

    private void updateSiteCache() {
        List<SitePdu> sitePduList = getStatSiteList();

        for (SitePdu site : sitePduList) {
            updatePjSectionCache(site);
            updatePjWindowCache(site);
            updatePjHallNameCache(site);

            updatePhQueueBusniessCache(site);
            updatePhQueueSectionNameCache(site);
            updatePhQueueWindowsCache(site);
            updatePhQueueHallNameCache(site);

        }
        int total = sitePduList.size();




       /* for (AccessEntity accessEntity : accessEntities) {

            SitePdu sitePdu = new SitePdu();
            sitePdu.setId(accessEntity.getId());
            Rest<List<SitePdu>> sitesRest = siteFeign.getFlatSitesBySiteId(sitePdu);
            if(YesNoEnum.YES.getValue()==sitesRest.getCode()){
                List<SitePdu> sitePduList = sitesRest.getData();
                for (SitePdu site : sitePduList) {
                    updatePjSectionCache(site);
                    updatePjWindowCache(site);
                    updatePjHallNameCache(site);

                    updatePhQueueBusniessCache(site);
                    updatePhQueueSectionNameCache(site);
                    updatePhQueueWindowsCache(site);
                    updatePhQueueHallNameCache(site);
                    total++;
                }
            }

*//*            SitePdu site = new SitePdu();
            site.setId(accessEntity.getSiteId());
            site.setSiteName(accessEntity.getSiteName());
            site.setSiteCode(accessEntity.getSiteCode());
            site.setAreaCode(accessEntity.getAreaCode());

            updatePjSectionCache(site);
            updatePjWindowCache(site);
            updatePjHallNameCache(site);

            updatePhQueueBusniessCache(site);
            updatePhQueueSectionNameCache(site);
            updatePhQueueWindowsCache(site);
            updatePhQueueHallNameCache(site);*//*
        }*/


        cacheService.set(RedisKey.KEY_SITE_STAT_COUNT_CHCHE, total);
        cacheService.set(RedisKey.KEY_SITE_STAT_TIME_CHCHE, DateUtil.formatDateTime(new Date()));



/*        SitePdu sitePdu = new SitePdu();
        sitePdu.setSize(-1);
        Rest<RespData<List<SitePdu>>> resp = siteFeign.list(sitePdu);
        if (resp.getCode() == 1) {
            List<SitePdu> sitePduList = resp.getData().getData();
            for (SitePdu site : sitePduList) {
                updatePjSectionCache(site);
                updatePjWindowCache(site);
                updatePjHallNameCache(site);

                updatePhQueueBusniessCache(site);
                updatePhQueueSectionNameCache(site);
                updatePhQueueWindowsCache(site);
                updatePhQueueHallNameCache(site);
            }
        }*/
    }

    private void updatePhQueueBusniessCache(SitePdu site) {
        PhQueueStatQuery phQueueStatQuery = new PhQueueStatQuery();
        phQueueStatQuery.setSiteId(site.getId());
        phQueueStatQuery.setBusinessNotList(Arrays.asList(""));
        List<PhQueueStatEntity> phQueueStatEntities = phQueueStatService.find(phQueueStatQuery, null);
        if (!ObjectUtils.isEmpty(phQueueStatEntities)) {
            cacheService.del(RedisKey.KEY_SITE_QUEUE_BUSNIESS_CHCHE + site.getId());
            for (PhQueueStatEntity phQueueStatEntity : phQueueStatEntities) {
                cacheService.hset(RedisKey.KEY_SITE_QUEUE_BUSNIESS_CHCHE + site.getId(), phQueueStatEntity.getBusiness(), phQueueStatEntity.getPhCount());
            }
        }
    }

    private void updatePhQueueSectionNameCache(SitePdu site) {
        PhQueueStatQuery phQueueStatQuery = new PhQueueStatQuery();
        phQueueStatQuery.setSiteId(site.getId());
        phQueueStatQuery.setSectionNameNotList(Arrays.asList(""));
        List<PhQueueStatEntity> phQueueStatEntities = phQueueStatService.find(phQueueStatQuery, null);
        if (!ObjectUtils.isEmpty(phQueueStatEntities)) {
            cacheService.del(RedisKey.KEY_SITE_QUEUE_SECTIONNAME_CHCHE + site.getId());
            for (PhQueueStatEntity phQueueStatEntity : phQueueStatEntities) {
                cacheService.hset(RedisKey.KEY_SITE_QUEUE_SECTIONNAME_CHCHE + site.getId(), phQueueStatEntity.getSectionName(), phQueueStatEntity.getPhCount());
            }
        }
    }

    private void updatePhQueueWindowsCache(SitePdu site) {
        PhQueueStatQuery phQueueStatQuery = new PhQueueStatQuery();
        phQueueStatQuery.setSiteId(site.getId());
        phQueueStatQuery.setWindowFromnumNotList(Arrays.asList(""));
        List<PhQueueStatEntity> phQueueStatEntities = phQueueStatService.find(phQueueStatQuery, null);
        if (!ObjectUtils.isEmpty(phQueueStatEntities)) {
            cacheService.del(RedisKey.KEY_SITE_QUEUE_WINDOW_CHCHE + site.getId());
            for (PhQueueStatEntity phQueueStatEntity : phQueueStatEntities) {
                cacheService.hset(RedisKey.KEY_SITE_QUEUE_WINDOW_CHCHE + site.getId(), phQueueStatEntity.getWindowFromnum(), phQueueStatEntity.getPhCount());
            }
        }
    }

    private void updatePhQueueHallNameCache(SitePdu site) {
        PhQueueStatQuery phQueueStatQuery = new PhQueueStatQuery();
        phQueueStatQuery.setSiteId(site.getId());
        phQueueStatQuery.setHallNameNotList(Arrays.asList(""));
        List<PhQueueStatEntity> phQueueStatEntities = phQueueStatService.find(phQueueStatQuery, null);
        if (!ObjectUtils.isEmpty(phQueueStatEntities)) {
            cacheService.del(RedisKey.KEY_SITE_QUEUE_HALLNAME_CHCHE + site.getId());
            for (PhQueueStatEntity phQueueStatEntity : phQueueStatEntities) {
                cacheService.hset(RedisKey.KEY_SITE_QUEUE_HALLNAME_CHCHE + site.getId(), phQueueStatEntity.getHallName(), phQueueStatEntity.getPhCount());
            }
        }
    }


    private void updatePjSectionCache(SitePdu site) {
        PjEvaluateStatQuery pjEvaluateStatQuery = new PjEvaluateStatQuery();
        pjEvaluateStatQuery.setSiteId(site.getId());
        pjEvaluateStatQuery.setSectionNameNotList(Arrays.asList(""));
        List<PjEvaluateStatEntity> pjEvaluateStatEntities = pjEvaluateStatService.find(pjEvaluateStatQuery, null);
        if (!ObjectUtils.isEmpty(pjEvaluateStatEntities)) {
            cacheService.del(RedisKey.KEY_SITE_PJ_SECTIONNAME_CHCHE + site.getId());
            for (PjEvaluateStatEntity pjEvaluateStatEntity : pjEvaluateStatEntities) {
                cacheService.hset(RedisKey.KEY_SITE_PJ_SECTIONNAME_CHCHE + site.getId(), pjEvaluateStatEntity.getSectionName(), pjEvaluateStatEntity.getPjCount());
            }
        }
    }

    private void updatePjWindowCache(SitePdu site) {
        PjEvaluateStatQuery pjEvaluateStatQuery = new PjEvaluateStatQuery();
        pjEvaluateStatQuery.setSiteId(site.getId());
        pjEvaluateStatQuery.setWindowFromnumNotList(Arrays.asList(""));
        List<PjEvaluateStatEntity> pjEvaluateStatEntities = pjEvaluateStatService.find(pjEvaluateStatQuery, null);
        if (!ObjectUtils.isEmpty(pjEvaluateStatEntities)) {
            cacheService.del(RedisKey.KEY_SITE_PJ_WINDOW_CHCHE + site.getId());
            for (PjEvaluateStatEntity pjEvaluateStatEntity : pjEvaluateStatEntities) {
                cacheService.hset(RedisKey.KEY_SITE_PJ_WINDOW_CHCHE + site.getId(), pjEvaluateStatEntity.getWindowFromnum(), pjEvaluateStatEntity.getPjCount());
            }
        }
    }

    private void updatePjHallNameCache(SitePdu site) {
        PjEvaluateStatQuery pjEvaluateStatQuery = new PjEvaluateStatQuery();
        pjEvaluateStatQuery.setSiteId(site.getId());
        pjEvaluateStatQuery.setHallNameNotList(Arrays.asList(""));
        List<PjEvaluateStatEntity> pjEvaluateStatEntities = pjEvaluateStatService.find(pjEvaluateStatQuery, null);
        if (!ObjectUtils.isEmpty(pjEvaluateStatEntities)) {
            cacheService.del(RedisKey.KEY_SITE_PJ_HALLNAME_CHCHE + site.getId());
            for (PjEvaluateStatEntity pjEvaluateStatEntity : pjEvaluateStatEntities) {
                cacheService.hset(RedisKey.KEY_SITE_PJ_HALLNAME_CHCHE + site.getId(), pjEvaluateStatEntity.getHallName(), pjEvaluateStatEntity.getPjCount());
            }
        }
    }


    @Override
    public void stopTask(ITask task) throws AppException {

    }

    public static void main(String[] args) {


        for (int i = 0; i < 7; i++) {
            DateTime beforeDate = DateUtil.offsetDay(new Date(), -i);
            int year = beforeDate.year();
            int month = beforeDate.month() + 1;
            int day = beforeDate.dayOfMonth();

            System.out.println(year + "年" + month + "月" + day + "日");

        }



/*        int year = DateUtil.date().year();
        int month = DateUtil.date().month() + 1;
        int day = DateUtil.date().dayOfMonth();

        //  System.out.println(year + "年" + month + "月" + day + "日");


        System.out.println(dateTime.toString("yyyy-MM-dd"));*/

    }


}
