package com.mortals.xhx.module.pj.service.impl;

import cn.hutool.core.util.StrUtil;
import com.mortals.framework.common.Rest;
import com.mortals.framework.model.OrderCol;
import com.mortals.framework.model.PageInfo;
import com.mortals.framework.model.Result;
import com.mortals.xhx.common.utils.BeanUtil;
import com.mortals.xhx.module.pj.model.PjEvaluateEntity;
import com.mortals.xhx.module.pj.model.PjEvaluateQuery;
import com.mortals.xhx.module.pj.model.PjEvaluateStatQuery;
import com.mortals.xhx.module.pj.service.PjEvaluateService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.mortals.framework.service.impl.AbstractCRUDServiceImpl;
import com.mortals.framework.exception.AppException;
import com.mortals.framework.model.Context;
import com.mortals.xhx.module.pj.dao.PjEvaluateStatDao;
import com.mortals.xhx.module.pj.model.PjEvaluateStatEntity;
import com.mortals.xhx.module.pj.service.PjEvaluateStatService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.ObjectUtils;

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

/**
 * PjEvaluateStatService
 * 评价汇总统计 service实现
 *
 * @author zxfei
 * @date 2024-06-24
 */
@Service("pjEvaluateStatService")
@Slf4j
public class PjEvaluateStatServiceImpl extends AbstractCRUDServiceImpl<PjEvaluateStatDao, PjEvaluateStatEntity, Long> implements PjEvaluateStatService {

    @Autowired
    private PjEvaluateService pjEvaluateService;


    @Override
    public Result<PjEvaluateStatEntity> find(PjEvaluateStatEntity entity, PageInfo pageInfo, Context context) throws AppException {
        Result<PjEvaluateStatEntity> result = new Result<>();
        PjEvaluateStatQuery query = new PjEvaluateStatQuery();
        BeanUtils.copyProperties(entity, query, BeanUtil.getNullPropertyNames(entity));
        List<PjEvaluateStatEntity> billInfos = this.getBillInfos(query, pageInfo, context);
        result.setList(billInfos);
        result.setPageInfo(pageInfo);
        return result;
    }

    @Override
    public Rest<List<PjEvaluateStatEntity>> updateSitePjStat(PjEvaluateStatEntity entity, Context context) {
        //todo 统计站点评价 分站点--部门 ||窗口编号||评价选项  ==》评价数量
        //查询指定日期当前站点所有评价数量
        Calendar calendar = Calendar.getInstance();
        calendar.set(entity.getYear(), entity.getMonth() - 1, entity.getDay());

        SimpleDateFormat date = new SimpleDateFormat("yyyy-MM-dd");//yyyy-年，MM-月，dd-日，HH-时，mm-分，ss-秒
        String currentDate = date.format(calendar.getTime());

        PjEvaluateQuery pjEvaluateQuery = new PjEvaluateQuery();
        pjEvaluateQuery.setSiteId(entity.getSiteId());
        pjEvaluateQuery.setPjTimeStart(currentDate);
        pjEvaluateQuery.setPjTimeEnd(currentDate);

        List<PjEvaluateEntity> pjEvaluateEntities = pjEvaluateService.find(pjEvaluateQuery);

        // log.info("更新站点评价统计数据，站点ID：{}，站点名称：{}，日期：{}，评价数量：{}", entity.getSiteId(), entity.getSiteName(), currentDate, pjEvaluateEntities.size());
        updateSitePjCount(entity, pjEvaluateEntities);

        List<PjEvaluateStatEntity> saveAndUpdatelist = new ArrayList<>();

        List<PjEvaluateStatEntity> pjEvaluateStatEntities = updateSiteSectionNamePjCount(currentDate, entity, pjEvaluateEntities);

        List<PjEvaluateStatEntity> pjEvaluateStatEntities1 = updateSiteHallPjCount(currentDate, entity, pjEvaluateEntities);

        List<PjEvaluateStatEntity> pjEvaluateStatEntities2 = updateSiteWindowPjCount(currentDate, entity, pjEvaluateEntities);

        List<PjEvaluateStatEntity> pjEvaluateStatEntities3 = updateSiteOptionPjCount(currentDate, entity, pjEvaluateEntities);
        //组合条件更新
        List<PjEvaluateStatEntity> pjEvaluateStatEntities4 = updateSiteConditionPhCount(entity, pjEvaluateEntities);

        saveAndUpdatelist.addAll(pjEvaluateStatEntities);
        saveAndUpdatelist.addAll(pjEvaluateStatEntities1);
        saveAndUpdatelist.addAll(pjEvaluateStatEntities2);
        saveAndUpdatelist.addAll(pjEvaluateStatEntities3);
        saveAndUpdatelist.addAll(pjEvaluateStatEntities4);

      //  saveUpdatePjEvaluateStatList(saveAndUpdatelist);

        return Rest.ok();
    }

    private List<PjEvaluateStatEntity> updateSiteConditionPhCount(PjEvaluateStatEntity entity, List<PjEvaluateEntity> pjEvaluateEntities) {

        //评价选项 部门 窗口

        List<PjEvaluateStatEntity> saveAndUpdatelist = new ArrayList<>();

        //评价选项+部门 busniess+sectionName
        List<PjEvaluateStatEntity> pjEvaluateStatEntities = updatePjOptionAndSectionName(entity, pjEvaluateEntities);

        //评价选型+窗口 busniess+WindowFromnum
        List<PjEvaluateStatEntity> pjEvaluateStatEntities1 = updatePjOptionAndWindowFromnum(entity, pjEvaluateEntities);

        //部门+窗口 sectionName+WindowFromnum
        List<PjEvaluateStatEntity> pjEvaluateStatEntities2 = updateSectionNameAndWindowFromnum(entity, pjEvaluateEntities);

        //评价选型+部门+窗口 busniess+sectionName+WindowFromnum
        List<PjEvaluateStatEntity> pjEvaluateStatEntities3 = updatePjOptionAndSectionNameAndWindow(entity, pjEvaluateEntities);

        saveAndUpdatelist.addAll(pjEvaluateStatEntities);
        saveAndUpdatelist.addAll(pjEvaluateStatEntities1);
        saveAndUpdatelist.addAll(pjEvaluateStatEntities2);
        saveAndUpdatelist.addAll(pjEvaluateStatEntities3);

        return saveAndUpdatelist;
    }


    private List<PjEvaluateStatEntity> updatePjOptionAndSectionName(PjEvaluateStatEntity entity, List<PjEvaluateEntity> pjEvaluateEntities) {
        Map<String, Long> pjoptionAndSectionCollect = pjEvaluateEntities.parallelStream()
                .collect(Collectors.groupingBy(x -> x.getPjOption() + "&" + x.getSectionName(), Collectors.counting()));
        List<PjEvaluateStatEntity> saveAndUpdatelist = pjoptionAndSectionCollect.entrySet().parallelStream().map(item -> {
            String vals = item.getKey();
            String[] split = StrUtil.splitToArray(vals, "&");
            if (ObjectUtils.isEmpty(split[0]) || ObjectUtils.isEmpty(split[1])) return null;
            //  log.info("更新站点排队统计数据，站点名称：{}，日期：{}，窗口：{}，排队数量：{}", entity.getSiteName(), currentDate,window, phQueueEntities.size());
            PjEvaluateStatQuery pjEvaluateStatQuery = getPhQueueStatQuery(entity);
            pjEvaluateStatQuery.setPjOption(split[0]);
            pjEvaluateStatQuery.setSectionName(split[1]);
            PjEvaluateStatEntity pjEvaluateStatEntity = getPjEvaluateStatEntity(entity, item.getValue(), pjEvaluateStatQuery);
            pjEvaluateStatEntity.setPjOption(split[0]);
            pjEvaluateStatEntity.setSectionName(split[1]);
            return pjEvaluateStatEntity;
        }).filter(f -> f != null).collect(Collectors.toList());
        // saveUpdatePjEvaluateStatList(saveAndUpdatelist);
        return saveAndUpdatelist;
    }

    private List<PjEvaluateStatEntity> updatePjOptionAndWindowFromnum(PjEvaluateStatEntity entity, List<PjEvaluateEntity> pjEvaluateEntities) {
        Map<String, Long> pjoptionAndSectionCollect = pjEvaluateEntities.parallelStream()
                .collect(Collectors.groupingBy(x -> x.getPjOption() + "&" + x.getWindowFromnum(), Collectors.counting()));
        List<PjEvaluateStatEntity> saveAndUpdatelist = pjoptionAndSectionCollect.entrySet().parallelStream().map(item -> {
            String vals = item.getKey();
            String[] split = StrUtil.splitToArray(vals, "&");
            if (ObjectUtils.isEmpty(split[0]) || ObjectUtils.isEmpty(split[1])) return null;
            //  log.info("更新站点排队统计数据，站点名称：{}，日期：{}，窗口：{}，排队数量：{}", entity.getSiteName(), currentDate,window, phQueueEntities.size());
            PjEvaluateStatQuery pjEvaluateStatQuery = getPhQueueStatQuery(entity);
            pjEvaluateStatQuery.setPjOption(split[0]);
            pjEvaluateStatQuery.setWindowFromnum(split[1]);
            PjEvaluateStatEntity pjEvaluateStatEntity = getPjEvaluateStatEntity(entity, item.getValue(), pjEvaluateStatQuery);
            pjEvaluateStatEntity.setPjOption(split[0]);
            pjEvaluateStatEntity.setWindowFromnum(split[1]);
            return pjEvaluateStatEntity;
        }).filter(f -> f != null).collect(Collectors.toList());
        // saveUpdatePjEvaluateStatList(saveAndUpdatelist);
        return saveAndUpdatelist;
    }


    private List<PjEvaluateStatEntity> updateSectionNameAndWindowFromnum(PjEvaluateStatEntity entity, List<PjEvaluateEntity> pjEvaluateEntities) {
        Map<String, Long> pjoptionAndSectionCollect = pjEvaluateEntities.parallelStream()
                .collect(Collectors.groupingBy(x -> x.getSectionName() + "&" + x.getWindowFromnum(), Collectors.counting()));
        List<PjEvaluateStatEntity> saveAndUpdatelist = pjoptionAndSectionCollect.entrySet().parallelStream().map(item -> {
            String vals = item.getKey();
            String[] split = StrUtil.splitToArray(vals, "&");
            if (ObjectUtils.isEmpty(split[0]) || ObjectUtils.isEmpty(split[1])) return null;
            //  log.info("更新站点排队统计数据，站点名称：{}，日期：{}，窗口：{}，排队数量：{}", entity.getSiteName(), currentDate,window, phQueueEntities.size());
            PjEvaluateStatQuery pjEvaluateStatQuery = getPhQueueStatQuery(entity);
            pjEvaluateStatQuery.setSectionName(split[0]);
            pjEvaluateStatQuery.setWindowFromnum(split[1]);
            PjEvaluateStatEntity pjEvaluateStatEntity = getPjEvaluateStatEntity(entity, item.getValue(), pjEvaluateStatQuery);
            pjEvaluateStatEntity.setSectionName(split[0]);
            pjEvaluateStatEntity.setWindowFromnum(split[1]);
            return pjEvaluateStatEntity;
        }).filter(f -> f != null).collect(Collectors.toList());
        //  saveUpdatePjEvaluateStatList(saveAndUpdatelist);
        return saveAndUpdatelist;
    }


    private List<PjEvaluateStatEntity> updatePjOptionAndSectionNameAndWindow(PjEvaluateStatEntity entity, List<PjEvaluateEntity> pjEvaluateEntities) {
        Map<String, Long> pjoptionAndSectionCollect = pjEvaluateEntities.parallelStream()
                .collect(Collectors.groupingBy(x -> x.getPjOption() + "&" + x.getSectionName() + "&" + x.getWindowFromnum(), Collectors.counting()));
        List<PjEvaluateStatEntity> saveAndUpdatelist = pjoptionAndSectionCollect.entrySet().parallelStream().map(item -> {
            String vals = item.getKey();
            String[] split = StrUtil.splitToArray(vals, "&");
            if (ObjectUtils.isEmpty(split[0]) || ObjectUtils.isEmpty(split[1]) || ObjectUtils.isEmpty(split[2]))
                return null;
            //  log.info("更新站点排队统计数据，站点名称：{}，日期：{}，窗口：{}，排队数量：{}", entity.getSiteName(), currentDate,window, phQueueEntities.size());
            PjEvaluateStatQuery pjEvaluateStatQuery = getPhQueueStatQuery(entity);
            pjEvaluateStatQuery.setPjOption(split[0]);
            pjEvaluateStatQuery.setSectionName(split[1]);
            pjEvaluateStatQuery.setWindowFromnum(split[2]);
            PjEvaluateStatEntity pjEvaluateStatEntity = getPjEvaluateStatEntity(entity, item.getValue(), pjEvaluateStatQuery);
            pjEvaluateStatEntity.setPjOption(split[0]);
            pjEvaluateStatEntity.setSectionName(split[1]);
            pjEvaluateStatEntity.setWindowFromnum(split[2]);
            return pjEvaluateStatEntity;
        }).filter(f -> f != null).collect(Collectors.toList());
        //  saveUpdatePjEvaluateStatList(saveAndUpdatelist);
        return saveAndUpdatelist;
    }

    private void updateSitePjCount(PjEvaluateStatEntity entity, List<PjEvaluateEntity> pjEvaluateEntities) {
        if (ObjectUtils.isEmpty(entity.getSiteId())) return;
        if (0L >= entity.getSiteId()) return;
        PjEvaluateStatEntity pjEvaluateStatEntity = this.selectOne(new PjEvaluateStatQuery()
                .siteId(entity.getSiteId())
                .year(entity.getYear())
                .month(entity.getMonth())
                .day(entity.getDay()));
        if (ObjectUtils.isEmpty(pjEvaluateStatEntity)) {
            //统计当前站点新增所有评价数量
            pjEvaluateStatEntity = new PjEvaluateStatEntity();
            pjEvaluateStatEntity.initAttrValue();
            pjEvaluateStatEntity.setSiteId(entity.getSiteId());
            pjEvaluateStatEntity.setSiteCode(entity.getSiteCode());
            pjEvaluateStatEntity.setSiteName(entity.getSiteName());
            pjEvaluateStatEntity.setPjCount(pjEvaluateEntities.size());
            pjEvaluateStatEntity.setYear(entity.getYear());
            pjEvaluateStatEntity.setMonth(entity.getMonth());
            pjEvaluateStatEntity.setDay(entity.getDay());
            pjEvaluateStatEntity.setCreateTime(new Date());
            pjEvaluateStatEntity.setCreateUserId(1L);
            this.save(pjEvaluateStatEntity);
        } else {
            pjEvaluateStatEntity.setPjCount(pjEvaluateEntities.size());
            pjEvaluateStatEntity.setYear(entity.getYear());
            pjEvaluateStatEntity.setMonth(entity.getMonth());
            pjEvaluateStatEntity.setDay(entity.getDay());
            pjEvaluateStatEntity.setUpdateTime(new Date());
            pjEvaluateStatEntity.setUpdateUserId(1L);
            this.update(pjEvaluateStatEntity);
        }
    }


    private List<PjEvaluateStatEntity> updateSiteSectionNamePjCount(String currentDate, PjEvaluateStatEntity entity, List<PjEvaluateEntity> pjEvaluateEntities) {

        Map<String, Long> collect = pjEvaluateEntities.stream().collect(Collectors.groupingBy(x -> x.getSectionName(), Collectors.counting()));
        List<PjEvaluateStatEntity> saveAndUpdatelist = collect.entrySet().stream().map(item -> {
            String sectionName = item.getKey();
            if (ObjectUtils.isEmpty(sectionName)) return null;
            PjEvaluateStatQuery pjEvaluateStatQuery = getPhQueueStatQuery(entity);
            pjEvaluateStatQuery.setSectionName(sectionName);
            PjEvaluateStatEntity pjEvaluateStatEntity = getPjEvaluateStatEntity(entity, item.getValue(), pjEvaluateStatQuery);
            pjEvaluateStatEntity.setSectionName(sectionName);
            return pjEvaluateStatEntity;
        }).filter(f -> f != null).collect(Collectors.toList());
        //  saveUpdatePjEvaluateStatList(saveAndUpdatelist);
        return saveAndUpdatelist;
    }


    private List<PjEvaluateStatEntity> updateSiteHallPjCount(String currentDate, PjEvaluateStatEntity entity, List<PjEvaluateEntity> pjEvaluateEntities) {
        Map<String, Long> collect = pjEvaluateEntities.stream().collect(Collectors.groupingBy(x -> x.getHallName(), Collectors.counting()));
        List<PjEvaluateStatEntity> saveAndUpdatelist = collect.entrySet().stream().map(item -> {
            String hallName = item.getKey();
            if (ObjectUtils.isEmpty(hallName)) return null;
            //log.info("更新站点评价统计数据，站点名称：{}，日期：{}，部门：{}，评价数量：{}", entity.getSiteName(), currentDate, entity.getSectionName(), pjEvaluateEntities.size());
            PjEvaluateStatQuery pjEvaluateStatQuery = getPhQueueStatQuery(entity);
            pjEvaluateStatQuery.setHallName(hallName);
            PjEvaluateStatEntity pjEvaluateStatEntity = getPjEvaluateStatEntity(entity, item.getValue(), pjEvaluateStatQuery);
            pjEvaluateStatEntity.setHallName(hallName);
            return pjEvaluateStatEntity;
        }).filter(f -> f != null).collect(Collectors.toList());
        //saveUpdatePjEvaluateStatList(saveAndUpdatelist);
        return saveAndUpdatelist;
    }


    private List<PjEvaluateStatEntity> updateSiteWindowPjCount(String currentDate, PjEvaluateStatEntity entity, List<PjEvaluateEntity> pjEvaluateEntities) {
        Map<String, Long> collect = pjEvaluateEntities.parallelStream().collect(Collectors.groupingBy(x -> x.getWindowFromnum(), Collectors.counting()));
        List<PjEvaluateStatEntity> saveAndUpdatelist = collect.entrySet().parallelStream().map(item -> {
            String windowFromnum = item.getKey();
            if (ObjectUtils.isEmpty(windowFromnum)) return null;
            PjEvaluateStatQuery pjEvaluateStatQuery = getPhQueueStatQuery(entity);
            pjEvaluateStatQuery.setWindowFromnum(windowFromnum);
            PjEvaluateStatEntity pjEvaluateStatEntity = getPjEvaluateStatEntity(entity, item.getValue(), pjEvaluateStatQuery);
            pjEvaluateStatEntity.setWindowFromnum(windowFromnum);
            return pjEvaluateStatEntity;
        }).filter(f -> f != null).collect(Collectors.toList());
        //saveUpdatePjEvaluateStatList(saveAndUpdatelist);
        return saveAndUpdatelist;
    }


    private List<PjEvaluateStatEntity> updateSiteOptionPjCount(String currentDate, PjEvaluateStatEntity entity, List<PjEvaluateEntity> pjEvaluateEntities) {
        Map<String, Long> collect = pjEvaluateEntities.parallelStream().collect(Collectors.groupingBy(x -> x.getPjOption(), Collectors.counting()));
        List<PjEvaluateStatEntity> saveAndUpdatelist = collect.entrySet().parallelStream().map(item -> {
            String pjOption = item.getKey();
            if (ObjectUtils.isEmpty(pjOption)) return null;
            Long value = item.getValue();
            //log.info("更新站点评价统计数据，站点名称：{}，日期：{}，窗口：{}，评价数量：{}", entity.getSiteName(), currentDate, entity.getWindowFromnum(), pjEvaluateEntities.size());
            PjEvaluateStatQuery pjEvaluateStatQuery = getPhQueueStatQuery(entity);
            pjEvaluateStatQuery.setPjOption(pjOption);
            PjEvaluateStatEntity pjEvaluateStatEntity = getPjEvaluateStatEntity(entity, value, pjEvaluateStatQuery);
            pjEvaluateStatEntity.setPjOption(pjOption);
            return pjEvaluateStatEntity;
        }).filter(f -> f != null).collect(Collectors.toList());
        //saveUpdatePjEvaluateStatList(saveAndUpdatelist);
        return saveAndUpdatelist;

    }

    private PjEvaluateStatEntity getPjEvaluateStatEntity(PjEvaluateStatEntity entity, Long value, PjEvaluateStatQuery phQueueStatQuery) {
        PjEvaluateStatEntity pjEvaluateStatEntity = this.selectOne(phQueueStatQuery);
        if (ObjectUtils.isEmpty(pjEvaluateStatEntity)) {
            //统计当前站点新增所有评价数量
            pjEvaluateStatEntity = new PjEvaluateStatEntity();
            pjEvaluateStatEntity.initAttrValue();
            pjEvaluateStatEntity.setSiteId(entity.getSiteId());
            pjEvaluateStatEntity.setSiteCode(entity.getSiteCode());
            pjEvaluateStatEntity.setSiteName(entity.getSiteName());
            pjEvaluateStatEntity.setPjCount(value.intValue());
            pjEvaluateStatEntity.setYear(entity.getYear());
            pjEvaluateStatEntity.setMonth(entity.getMonth());
            pjEvaluateStatEntity.setDay(entity.getDay());
            pjEvaluateStatEntity.setCreateTime(new Date());
            pjEvaluateStatEntity.setCreateUserId(1L);
        } else {
            pjEvaluateStatEntity.setPjCount(value.intValue());
            pjEvaluateStatEntity.setYear(entity.getYear());
            pjEvaluateStatEntity.setMonth(entity.getMonth());
            pjEvaluateStatEntity.setDay(entity.getDay());
            pjEvaluateStatEntity.setUpdateTime(new Date());
            pjEvaluateStatEntity.setUpdateUserId(1L);
        }
        return pjEvaluateStatEntity;
    }


    @Override
    public List<PjEvaluateStatEntity> getBillInfos(PjEvaluateStatQuery query, PageInfo pageInfo, Context context) {
        if (!ObjectUtils.isEmpty(query.getGroupList())) {
            //针对groupList分组 进行排序
            if (query.getGroupList().contains("year") && query.getGroupList().contains("month") && query.getGroupList().contains("day")) {
                query.setOrderColList(Arrays.asList(new OrderCol("year", OrderCol.DESCENDING), new OrderCol("month", OrderCol.DESCENDING), new OrderCol("day", OrderCol.DESCENDING)));
            } else if (query.getGroupList().contains("year") && query.getGroupList().contains("month")) {
                query.setOrderColList(Arrays.asList(new OrderCol("year", OrderCol.DESCENDING), new OrderCol("month", OrderCol.DESCENDING)));
            } else if (query.getGroupList().contains("year")) {
                query.setOrderColList(Arrays.asList(new OrderCol("year", OrderCol.DESCENDING)));
            }
        }
        return this.getDao().getStatList(query, pageInfo);
    }


    private PjEvaluateStatQuery getPhQueueStatQuery(PjEvaluateStatEntity entity) {
        PjEvaluateStatQuery pjEvaluateStatQuery = new PjEvaluateStatQuery().siteId(entity.getSiteId())
                .year(entity.getYear())
                .month(entity.getMonth())
                .day(entity.getDay());
        return pjEvaluateStatQuery;
    }

    @Override
    public void saveUpdatePjEvaluateStatList(List<PjEvaluateStatEntity> saveAndUpdatelist) {
        if (!ObjectUtils.isEmpty(saveAndUpdatelist)) {
            Map<Boolean, List<PjEvaluateStatEntity>> saveUpdateCollect = saveAndUpdatelist.parallelStream().collect(Collectors.partitioningBy(i -> i.newEntity()));

            log.info("新增站点评价统计数据，数量：{}", saveUpdateCollect.get(true).size());
            if (!ObjectUtils.isEmpty(saveUpdateCollect.get(true))) {
                //新增列表
                this.save(saveUpdateCollect.get(true));
            }
            log.info("更新站点评价统计数据，数量：{}", saveUpdateCollect.get(true).size());
            if (!ObjectUtils.isEmpty(saveUpdateCollect.get(false))) {
                //更新列表
                this.update(saveUpdateCollect.get(true));
            }

        }
    }


}