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

import com.mortals.framework.common.Rest;
import com.mortals.framework.exception.AppException;
import com.mortals.framework.model.OrderCol;
import com.mortals.framework.model.PageInfo;
import com.mortals.framework.model.Result;
import com.mortals.xhx.common.code.TimeUnitEnum;
import com.mortals.xhx.common.utils.BeanUtil;
import com.mortals.xhx.module.ph.model.PhQueueEntity;
import com.mortals.xhx.module.ph.model.PhQueueQuery;
import com.mortals.xhx.module.ph.model.PhQueueStatQuery;
import com.mortals.xhx.module.ph.service.PhQueueService;
import com.mortals.xhx.module.pj.model.PjEvaluateEntity;
import com.mortals.xhx.module.pj.model.PjEvaluateStatEntity;
import com.mortals.xhx.module.pj.model.PjEvaluateStatQuery;
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.model.Context;
import com.mortals.xhx.module.ph.dao.PhQueueStatDao;
import com.mortals.xhx.module.ph.model.PhQueueStatEntity;
import com.mortals.xhx.module.ph.service.PhQueueStatService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.ObjectUtils;

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

/**
 * PhQueueStatService
 * 排队叫号汇总统计 service实现
 *
 * @author zxfei
 * @date 2024-06-24
 */
@Service("phQueueStatService")
@Slf4j
public class PhQueueStatServiceImpl extends AbstractCRUDServiceImpl<PhQueueStatDao, PhQueueStatEntity, Long> implements PhQueueStatService {

    @Autowired
    private PhQueueService phQueueService;

    @Override
    public Rest<Void> updateSitePhStat(PhQueueStatEntity entity, Context context) {

        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());

         PhQueueQuery phQueueQuery = new PhQueueQuery();
        phQueueQuery.setSiteId(entity.getSiteId());
        phQueueQuery.setTaketimeStart(currentDate);
        phQueueQuery.setTaketimeEnd(currentDate);
        //排除掉呼叫转移的号码
        phQueueQuery.setFormernumList(Arrays.asList(""));

        List<PhQueueEntity> phQueueEntities = phQueueService.find(phQueueQuery);

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

        //部门
        updateSiteSectionNamePhCount(currentDate, entity, phQueueEntities);
        //大厅
        updateSiteHallPhCount(currentDate, entity, phQueueEntities);
        //业务
        updateSiteBussinessPhCount(currentDate, entity, phQueueEntities);
        //窗口
        updateSiteWindowPhCount(currentDate, entity, phQueueEntities);
        //组合条件更新
        updateSiteConditionPhCount(entity, phQueueEntities);
        return Rest.ok();
    }


    private void updateSitePhCount(PhQueueStatEntity entity, List<PhQueueEntity> phQueueEntities) {

        PhQueueStatQuery phQueueStatQuery = getPhQueueStatQuery(entity);
        Double intAvg = phQueueEntities.parallelStream().mapToInt(e -> e.getWaitTime()).average().orElse(0D);
        PhQueueStatEntity phQueueStatEntity = getPhQueueStatEntity(entity, phQueueEntities, intAvg, phQueueStatQuery);

        if (phQueueStatEntity.newEntity()) {
            //统计当前站点新增所有评价数量
            this.save(phQueueStatEntity);
        } else {
            this.update(phQueueStatEntity);
        }
    }

    private void updateSiteSectionNamePhCount(String currentDate, PhQueueStatEntity entity, List<PhQueueEntity> phQueueEntities) {

        Map<String, List<PhQueueEntity>> collect = phQueueEntities.parallelStream().collect(Collectors.groupingBy(x -> x.getSectionName()));

        List<PhQueueStatEntity> saveAndUpdatelist = collect.entrySet().parallelStream().map(item -> {
            String sectionName = item.getKey();
            if (ObjectUtils.isEmpty(sectionName)) return null;
            List<PhQueueEntity> value = item.getValue();
            Double intAvg = value.parallelStream().mapToInt(e -> e.getWaitTime()).average().orElse(0D);
            // log.info("更新站点排队统计数据，站点名称：{}，日期：{}，部门：{}，排队数量：{}", entity.getSiteName(), currentDate,sectionName, phQueueEntities.size());
            PhQueueStatQuery phQueueStatQuery = getPhQueueStatQuery(entity);
            phQueueStatQuery.setSectionName(sectionName);
            PhQueueStatEntity phQueueStatEntity = getPhQueueStatEntity(entity, value, intAvg, phQueueStatQuery);
            phQueueStatEntity.setSectionName(sectionName);
            return phQueueStatEntity;
        }).filter(f -> f != null).collect(Collectors.toList());

        saveUpdatePhqueueStatList(saveAndUpdatelist);

    }

    private void updateSiteHallPhCount(String currentDate, PhQueueStatEntity entity, List<PhQueueEntity> phQueueEntities) {

        Map<String, List<PhQueueEntity>> collect = phQueueEntities.parallelStream().collect(Collectors.groupingBy(x -> x.getHallName()));
        List<PhQueueStatEntity> saveAndUpdatelist =collect.entrySet().parallelStream().map(item -> {
            String hallName = item.getKey();
            if (ObjectUtils.isEmpty(hallName)) return null;
            List<PhQueueEntity> value = item.getValue();
            Double intAvg = value.parallelStream().mapToInt(e -> e.getWaitTime()).average().orElse(0D);
            //log.info("更新站点排队统计数据，站点名称：{}，日期：{}，大厅：{}，排队数量：{}", entity.getSiteName(), currentDate, hallName, phQueueEntities.size());
            PhQueueStatQuery phQueueStatQuery = getPhQueueStatQuery(entity);
            phQueueStatQuery.setHallName(hallName);
            PhQueueStatEntity phQueueStatEntity = getPhQueueStatEntity(entity, value, intAvg, phQueueStatQuery);
            phQueueStatEntity.setHallName(hallName);
            return phQueueStatEntity;
        }).filter(f -> f != null).collect(Collectors.toList());
        saveUpdatePhqueueStatList(saveAndUpdatelist);
    }


    private void updateSiteBussinessPhCount(String currentDate, PhQueueStatEntity entity, List<PhQueueEntity> phQueueEntities) {
        Map<String, List<PhQueueEntity>> collect = phQueueEntities.parallelStream().collect(Collectors.groupingBy(x -> x.getBusiness()));
        List<PhQueueStatEntity> saveAndUpdatelist =collect.entrySet().parallelStream().map(item -> {
            String bussiness = item.getKey();
            if (ObjectUtils.isEmpty(bussiness)) return null;
            List<PhQueueEntity> value = item.getValue();
            Double intAvg = value.parallelStream().mapToInt(e -> e.getWaitTime()).average().orElse(0D);
            // log.info("更新站点排队统计数据，站点名称：{}，日期：{}，业务：{}，排队数量：{}", entity.getSiteName(), currentDate, bussiness, phQueueEntities.size());
            PhQueueStatQuery phQueueStatQuery = getPhQueueStatQuery(entity);
            phQueueStatQuery.setBusiness(bussiness);
            PhQueueStatEntity phQueueStatEntity = getPhQueueStatEntity(entity, value, intAvg, phQueueStatQuery);
            phQueueStatEntity.setBusiness(bussiness);
            return phQueueStatEntity;
        }).filter(f -> f != null).collect(Collectors.toList());
        saveUpdatePhqueueStatList(saveAndUpdatelist);
    }

    private void updateSiteWindowPhCount(String currentDate, PhQueueStatEntity entity, List<PhQueueEntity> phQueueEntities) {

        Map<String, List<PhQueueEntity>> collect = phQueueEntities.parallelStream().collect(Collectors.groupingBy(x -> x.getWindowFromnum()));
        List<PhQueueStatEntity> saveAndUpdatelist =collect.entrySet().parallelStream().map(item -> {
            String window = item.getKey();
            if (ObjectUtils.isEmpty(window)) return null;
            List<PhQueueEntity> value = item.getValue();
            Double intAvg = value.parallelStream().mapToInt(e -> e.getWaitTime()).average().orElse(0D);
            //  log.info("更新站点排队统计数据，站点名称：{}，日期：{}，窗口：{}，排队数量：{}", entity.getSiteName(), currentDate,window, phQueueEntities.size());
            PhQueueStatQuery phQueueStatQuery = getPhQueueStatQuery(entity);
            phQueueStatQuery.setWindowFromnum(window);
            PhQueueStatEntity phQueueStatEntity = getPhQueueStatEntity(entity, value, intAvg, phQueueStatQuery);
            phQueueStatEntity.setWindowFromnum(window);
            return phQueueStatEntity;
        }).filter(f -> f != null).collect(Collectors.toList());
        saveUpdatePhqueueStatList(saveAndUpdatelist);
    }


    @Override
    public Result<PhQueueStatEntity> find(PhQueueStatEntity entity, PageInfo pageInfo, Context context) throws AppException {

        Result<PhQueueStatEntity> result = new Result<>();
        PhQueueStatQuery query = new PhQueueStatQuery();
        BeanUtils.copyProperties(entity, query, BeanUtil.getNullPropertyNames(entity));
        List<PhQueueStatEntity> billInfos = this.getBillInfos(query, pageInfo, context);
        result.setList(billInfos);
        result.setPageInfo(pageInfo);
        return result;
    }

    @Override
    public List<PhQueueStatEntity> getBillInfos(PhQueueStatQuery 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 void updateSiteConditionPhCount(PhQueueStatEntity entity, List<PhQueueEntity> phQueueEntities) {

        //业务+部门 busniess+sectionName
        updateBusinessAndSectionName(entity, phQueueEntities);

        //业务+窗口 busniess+WindowFromnum
        updateBusinessAndWindowFromnum(entity, phQueueEntities);

        //部门+窗口 sectionName+WindowFromnum
        updateSectionNameAndWindowFromnum(entity, phQueueEntities);

        //业务+部门+窗口 busniess+sectionName+WindowFromnum
        updateBusinessAndSectionNameAndWindow(entity, phQueueEntities);

    }

    private void updateBusinessAndSectionName(PhQueueStatEntity entity, List<PhQueueEntity> phQueueEntities) {
        Map<String, List<PhQueueEntity>> businessAndSectionCollect = phQueueEntities.parallelStream()
                .collect(Collectors.groupingBy(x -> x.getBusiness() + "&" + x.getSectionName()));
        List<PhQueueStatEntity> saveAndUpdatelist =businessAndSectionCollect.entrySet().parallelStream().map(item -> {
            String vals = item.getKey();
            String[] split = vals.split("&");
            if (ObjectUtils.isEmpty(split[0])||ObjectUtils.isEmpty(split[1])) return null ;
            Double intAvg = item.getValue().parallelStream().mapToInt(e -> e.getWaitTime()).average().orElse(0D);
            //  log.info("更新站点排队统计数据，站点名称：{}，日期：{}，窗口：{}，排队数量：{}", entity.getSiteName(), currentDate,window, phQueueEntities.size());
            PhQueueStatQuery phQueueStatQuery = getPhQueueStatQuery(entity);
            phQueueStatQuery.setBusiness(split[0]);
            phQueueStatQuery.setSectionName(split[1]);
            PhQueueStatEntity phQueueStatEntity = getPhQueueStatEntity(entity, item.getValue(), intAvg, phQueueStatQuery);
            phQueueStatEntity.setBusiness(split[0]);
            phQueueStatEntity.setSectionName(split[1]);
            return phQueueStatEntity;
        }).filter(f -> f != null).collect(Collectors.toList());
        saveUpdatePhqueueStatList(saveAndUpdatelist);
    }


    private void updateBusinessAndWindowFromnum(PhQueueStatEntity entity, List<PhQueueEntity> phQueueEntities) {
        Map<String, List<PhQueueEntity>> businessAndSectionCollect = phQueueEntities.parallelStream()
                .collect(Collectors.groupingBy(x -> x.getBusiness() + "&" + x.getWindowFromnum()));
        List<PhQueueStatEntity> saveAndUpdatelist =businessAndSectionCollect.entrySet().parallelStream().map(item -> {
            String vals = item.getKey();
            String[] split = vals.split("&");
            if (ObjectUtils.isEmpty(split[0])||ObjectUtils.isEmpty(split[1])) return null ;
            Double intAvg = item.getValue().parallelStream().mapToInt(e -> e.getWaitTime()).average().orElse(0D);
            //  log.info("更新站点排队统计数据，站点名称：{}，日期：{}，窗口：{}，排队数量：{}", entity.getSiteName(), currentDate,window, phQueueEntities.size());
            PhQueueStatQuery phQueueStatQuery = getPhQueueStatQuery(entity);
            phQueueStatQuery.setBusiness(split[0]);
            phQueueStatQuery.setWindowFromnum(split[1]);
            PhQueueStatEntity phQueueStatEntity = getPhQueueStatEntity(entity, item.getValue(), intAvg, phQueueStatQuery);
            phQueueStatEntity.setBusiness(split[0]);
            phQueueStatEntity.setWindowFromnum(split[1]);
            return phQueueStatEntity;
        }).filter(f -> f != null).collect(Collectors.toList());
        saveUpdatePhqueueStatList(saveAndUpdatelist);
    }


    private void updateSectionNameAndWindowFromnum(PhQueueStatEntity entity, List<PhQueueEntity> phQueueEntities) {
        Map<String, List<PhQueueEntity>> businessAndSectionCollect = phQueueEntities.parallelStream()
                .collect(Collectors.groupingBy(x -> x.getSectionName() + "&" + x.getWindowFromnum()));
        List<PhQueueStatEntity> saveAndUpdatelist =businessAndSectionCollect.entrySet().parallelStream().map(item -> {
            String vals = item.getKey();
            String[] split = vals.split("&");
            if (ObjectUtils.isEmpty(split[0])||ObjectUtils.isEmpty(split[1])) return null ;
            Double intAvg = item.getValue().parallelStream().mapToInt(e -> e.getWaitTime()).average().orElse(0D);
            //  log.info("更新站点排队统计数据，站点名称：{}，日期：{}，窗口：{}，排队数量：{}", entity.getSiteName(), currentDate,window, phQueueEntities.size());
            PhQueueStatQuery phQueueStatQuery = getPhQueueStatQuery(entity);
            phQueueStatQuery.setSectionName(split[0]);
            phQueueStatQuery.setWindowFromnum(split[1]);
            PhQueueStatEntity phQueueStatEntity = getPhQueueStatEntity(entity, item.getValue(), intAvg, phQueueStatQuery);
            phQueueStatEntity.setSectionName(split[0]);
            phQueueStatEntity.setWindowFromnum(split[1]);
            return phQueueStatEntity;
        }).filter(f -> f != null).collect(Collectors.toList());
        saveUpdatePhqueueStatList(saveAndUpdatelist);
    }

    private void updateBusinessAndSectionNameAndWindow(PhQueueStatEntity entity, List<PhQueueEntity> phQueueEntities) {
        Map<String, List<PhQueueEntity>> businessAndSectionCollect = phQueueEntities.parallelStream()
                .collect(Collectors.groupingBy(x -> x.getBusiness() + "&" + x.getSectionName()+ "&" + x.getWindowFromnum()));
        List<PhQueueStatEntity> saveAndUpdatelist =businessAndSectionCollect.entrySet().parallelStream().map(item -> {
            String vals = item.getKey();
            String[] split = vals.split("&");
            if (ObjectUtils.isEmpty(split[0])||ObjectUtils.isEmpty(split[1])||ObjectUtils.isEmpty(split[2])) return null ;
            Double intAvg = item.getValue().parallelStream().mapToInt(e -> e.getWaitTime()).average().orElse(0D);
            //  log.info("更新站点排队统计数据，站点名称：{}，日期：{}，窗口：{}，排队数量：{}", entity.getSiteName(), currentDate,window, phQueueEntities.size());
            PhQueueStatQuery phQueueStatQuery = getPhQueueStatQuery(entity);
            phQueueStatQuery.setBusiness(split[0]);
            phQueueStatQuery.setSectionName(split[1]);
            phQueueStatQuery.setWindowFromnum(split[2]);
            PhQueueStatEntity phQueueStatEntity = getPhQueueStatEntity(entity, item.getValue(), intAvg, phQueueStatQuery);
            phQueueStatEntity.setBusiness(split[0]);
            phQueueStatEntity.setSectionName(split[1]);
            phQueueStatEntity.setWindowFromnum(split[2]);
            return phQueueStatEntity;
        }).filter(f -> f != null).collect(Collectors.toList());
        saveUpdatePhqueueStatList(saveAndUpdatelist);
    }

    private static PhQueueStatQuery getPhQueueStatQuery(PhQueueStatEntity entity) {
        PhQueueStatQuery phQueueStatQuery = new PhQueueStatQuery().siteId(entity.getSiteId())
                .year(entity.getYear())
                .month(entity.getMonth())
                .day(entity.getDay());
        return phQueueStatQuery;
    }

    private PhQueueStatEntity getPhQueueStatEntity(PhQueueStatEntity entity, List<PhQueueEntity> value, Double intAvg, PhQueueStatQuery phQueueStatQuery) {
        PhQueueStatEntity phQueueStatEntity = this.selectOne(phQueueStatQuery);
        if (ObjectUtils.isEmpty(phQueueStatEntity)) {
            //统计当前站点新增所有评价数量
            phQueueStatEntity = new PhQueueStatEntity();
            phQueueStatEntity.initAttrValue();
            phQueueStatEntity.setSiteId(entity.getSiteId());
            phQueueStatEntity.setSiteCode(entity.getSiteCode());
            phQueueStatEntity.setSiteName(entity.getSiteName());
            phQueueStatEntity.setPhCount(value.size());
            phQueueStatEntity.setWaitTime(intAvg.intValue());
            phQueueStatEntity.setYear(entity.getYear());
            phQueueStatEntity.setMonth(entity.getMonth());
            phQueueStatEntity.setDay(entity.getDay());
            phQueueStatEntity.setCreateTime(new Date());
            phQueueStatEntity.setCreateUserId(1L);
        } else {
            phQueueStatEntity.setPhCount(value.size());
            phQueueStatEntity.setWaitTime(intAvg.intValue());
            phQueueStatEntity.setYear(entity.getYear());
            phQueueStatEntity.setMonth(entity.getMonth());
            phQueueStatEntity.setDay(entity.getDay());
            phQueueStatEntity.setUpdateTime(new Date());
            phQueueStatEntity.setUpdateUserId(1L);
        }
        return phQueueStatEntity;
    }



    private void saveUpdatePhqueueStatList(List<PhQueueStatEntity> saveAndUpdatelist) {
        if (!ObjectUtils.isEmpty(saveAndUpdatelist)) {
            Map<Boolean, List<PhQueueStatEntity>> saveUpdateCollect = saveAndUpdatelist.parallelStream().collect(Collectors.partitioningBy(i -> i.newEntity()));

            if (!ObjectUtils.isEmpty(saveUpdateCollect.get(true))) {
                //新增列表
                log.info("新增站点排队部门统计数据，数量：{}", saveUpdateCollect.get(true).size());
                this.save(saveUpdateCollect.get(true));
            }

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

        }
    }

}