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

        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);
        //平均等待时间


        return Rest.ok();
    }


    private void updateSitePhCount(PhQueueStatEntity entity, List<PhQueueEntity> phQueueEntities) {
        PhQueueStatEntity phQueueStatEntity = this.selectOne(new PhQueueStatQuery()
                .siteId(entity.getSiteId())
                .year(entity.getYear())
                .month(entity.getMonth())
                .day(entity.getDay()));
        Double intAvg = phQueueEntities.stream().mapToInt(e -> e.getWaitTime()).average().orElse(0D);

        if (ObjectUtils.isEmpty(phQueueStatEntity)) {
            //统计当前站点新增所有评价数量
            phQueueStatEntity = new PhQueueStatEntity();
            phQueueStatEntity.initAttrValue();
            phQueueStatEntity.setSiteId(entity.getSiteId());
            phQueueStatEntity.setSiteCode(entity.getSiteCode());
            phQueueStatEntity.setSiteName(entity.getSiteName());
            phQueueStatEntity.setPhCount(phQueueEntities.size());

            //计算平均等待时间
            phQueueStatEntity.setWaitTime(intAvg.intValue());
            phQueueStatEntity.setYear(entity.getYear());
            phQueueStatEntity.setMonth(entity.getMonth());
            phQueueStatEntity.setDay(entity.getDay());
            phQueueStatEntity.setCreateTime(new Date());
            phQueueStatEntity.setCreateUserId(1L);
            this.save(phQueueStatEntity);
        } else {
            phQueueStatEntity.setPhCount(phQueueEntities.size());
            phQueueStatEntity.setWaitTime(intAvg.intValue());
            phQueueStatEntity.setYear(entity.getYear());
            phQueueStatEntity.setMonth(entity.getMonth());
            phQueueStatEntity.setDay(entity.getDay());
            phQueueStatEntity.setUpdateTime(new Date());
            phQueueStatEntity.setUpdateUserId(1L);
            this.update(phQueueStatEntity);
        }
    }

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

        Map<String, List<PhQueueEntity>> collect = phQueueEntities.stream().collect(Collectors.groupingBy(x -> x.getSectionName()));
        collect.entrySet().stream().forEach(item -> {
            String sectionName = item.getKey();
            if (ObjectUtils.isEmpty(sectionName)) return;
            List<PhQueueEntity> value = item.getValue();
            Double intAvg = value.stream().mapToInt(e -> e.getWaitTime()).average().orElse(0D);

            log.info("更新站点评价统计数据，站点名称：{}，日期：{}，部门：{}，评价数量：{}", entity.getSiteName(), currentDate, entity.getSectionName(), phQueueEntities.size());
            PhQueueStatEntity phQueueStatEntity = this.selectOne(new PhQueueStatQuery()
                    .siteId(entity.getSiteId())
                    .sectionName(sectionName)
                    .year(entity.getYear())
                    .month(entity.getMonth())
                    .day(entity.getDay()));
            if (ObjectUtils.isEmpty(phQueueStatEntity)) {
                //统计当前站点新增所有评价数量
                phQueueStatEntity = new PhQueueStatEntity();
                phQueueStatEntity.initAttrValue();
                phQueueStatEntity.setSiteId(entity.getSiteId());
                phQueueStatEntity.setSiteCode(entity.getSiteCode());
                phQueueStatEntity.setSiteName(entity.getSiteName());
                phQueueStatEntity.setSectionName(sectionName);
                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);
                this.save(phQueueStatEntity);
            } 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);
                this.update(phQueueStatEntity);
            }
        });
    }


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

        Map<String, List<PhQueueEntity>> collect = phQueueEntities.stream().collect(Collectors.groupingBy(x -> x.getSectionName()));
        collect.entrySet().stream().forEach(item -> {
            String hallName = item.getKey();
            if (ObjectUtils.isEmpty(hallName)) return;
            List<PhQueueEntity> value = item.getValue();
            Double intAvg = value.stream().mapToInt(e -> e.getWaitTime()).average().orElse(0D);
            log.info("更新站点评价统计数据，站点名称：{}，日期：{}，大厅：{}，评价数量：{}", entity.getSiteName(), currentDate, entity.getHallName(), phQueueEntities.size());
            PhQueueStatEntity phQueueStatEntity = this.selectOne(new PhQueueStatQuery()
                    .siteId(entity.getSiteId())
                    .hallName(hallName)
                    .year(entity.getYear())
                    .month(entity.getMonth())
                    .day(entity.getDay()));
            if (ObjectUtils.isEmpty(phQueueStatEntity)) {
                //统计当前站点新增所有评价数量
                phQueueStatEntity = new PhQueueStatEntity();
                phQueueStatEntity.initAttrValue();
                phQueueStatEntity.setSiteId(entity.getSiteId());
                phQueueStatEntity.setSiteCode(entity.getSiteCode());
                phQueueStatEntity.setSiteName(entity.getSiteName());
                phQueueStatEntity.setHallName(hallName);
                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);
                this.save(phQueueStatEntity);
            } 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);
                this.update(phQueueStatEntity);
            }
        });
    }


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

        Map<String, List<PhQueueEntity>> collect = phQueueEntities.stream().collect(Collectors.groupingBy(x -> x.getSectionName()));
        collect.entrySet().stream().forEach(item -> {
            String bussiness = item.getKey();
            if (ObjectUtils.isEmpty(bussiness)) return;
            List<PhQueueEntity> value = item.getValue();
            Double intAvg = value.stream().mapToInt(e -> e.getWaitTime()).average().orElse(0D);
            log.info("更新站点评价统计数据，站点名称：{}，日期：{}，业务：{}，评价数量：{}", entity.getSiteName(), currentDate, entity.getBusiness(), phQueueEntities.size());
            PhQueueStatEntity phQueueStatEntity = this.selectOne(new PhQueueStatQuery()
                    .siteId(entity.getSiteId())
                    .business(bussiness)
                    .year(entity.getYear())
                    .month(entity.getMonth())
                    .day(entity.getDay()));
            if (ObjectUtils.isEmpty(phQueueStatEntity)) {
                //统计当前站点新增所有评价数量
                phQueueStatEntity = new PhQueueStatEntity();
                phQueueStatEntity.initAttrValue();
                phQueueStatEntity.setSiteId(entity.getSiteId());
                phQueueStatEntity.setSiteCode(entity.getSiteCode());
                phQueueStatEntity.setSiteName(entity.getSiteName());
                phQueueStatEntity.setBusiness(bussiness);
                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);
                this.save(phQueueStatEntity);
            } 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);
                this.update(phQueueStatEntity);
            }
        });
    }

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

        Map<String, List<PhQueueEntity>> collect = phQueueEntities.stream().collect(Collectors.groupingBy(x -> x.getSectionName()));
        collect.entrySet().stream().forEach(item -> {
            String window = item.getKey();
            if (ObjectUtils.isEmpty(window)) return;
            List<PhQueueEntity> value = item.getValue();
            Double intAvg = value.stream().mapToInt(e -> e.getWaitTime()).average().orElse(0D);
            log.info("更新站点评价统计数据，站点名称：{}，日期：{}，业务：{}，评价数量：{}", entity.getSiteName(), currentDate, entity.getBusiness(), phQueueEntities.size());
            PhQueueStatEntity phQueueStatEntity = this.selectOne(new PhQueueStatQuery()
                    .siteId(entity.getSiteId())
                    .windowFromnum(window)
                    .year(entity.getYear())
                    .month(entity.getMonth())
                    .day(entity.getDay()));
            if (ObjectUtils.isEmpty(phQueueStatEntity)) {
                //统计当前站点新增所有评价数量
                phQueueStatEntity = new PhQueueStatEntity();
                phQueueStatEntity.initAttrValue();
                phQueueStatEntity.setSiteId(entity.getSiteId());
                phQueueStatEntity.setSiteCode(entity.getSiteCode());
                phQueueStatEntity.setSiteName(entity.getSiteName());
                phQueueStatEntity.setWindowFromnum(window);
                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);
                this.save(phQueueStatEntity);
            } 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);
                this.update(phQueueStatEntity);
            }
        });
    }


    @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 super.find(entity, pageInfo, context);
    }

    @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), new OrderCol("createTime")));
            } else if (query.getGroupList().contains("year") && query.getGroupList().contains("month")) {
                query.setOrderColList(Arrays.asList(new OrderCol("year", OrderCol.DESCENDING), new OrderCol("month", OrderCol.DESCENDING), new OrderCol("createTime")));
            } else if (query.getGroupList().contains("year")) {
                query.setOrderColList(Arrays.asList(new OrderCol("year", OrderCol.DESCENDING), new OrderCol("createTime")));
            }
        }
        return this.getDao().getStatList(query, pageInfo);
    }

}