package com.goafanti.admin.service.impl;

import com.goafanti.admin.bo.*;
import com.goafanti.admin.service.AdminStatisticsService;
import com.goafanti.common.constant.AFTConstants;
import com.goafanti.common.dao.*;
import com.goafanti.common.error.BusinessException;
import com.goafanti.common.model.*;
import com.goafanti.common.utils.DateUtils;
import com.goafanti.common.utils.LoggerUtils;
import com.goafanti.core.shiro.token.TokenManager;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDate;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.*;

@Service
public class AdminStatisticsServiceImpl implements AdminStatisticsService {



    @Resource
    private AdminMapper adminMapper;
    @Resource
    private PublicReleaseMapper publicReleaseMapper;
    @Resource
    private FinanceCountMapper financeCountMapper;
    @Resource
    private CallLogMapper callLogMapper;
    @Resource
    private SalesTeamMapper salesTeamMapper;
    @Resource
    private AdminCallDayMapper adminCallDayMapper;
    @Resource
    private UserFollowMapper userFollowMapper;
    @Resource
    private DepartmentMapper departmentMapper;


    @Override
    public Object info( String startTime, String endTime) {
        String aid=TokenManager.getAdminId();
        endTime=endTime+" 23:59:59";
        //不再计算私有,签单，渠道
        AdminStatisticsBo adminStatisticsBo = adminMapper.adminStatisticsInfo(aid);
        if (adminStatisticsBo==null){
            adminStatisticsBo=new AdminStatisticsBo();
        }else {
            //从客户中计算再添加到adminStatisticsBo
            AdminStatisticsBo ListCount = adminMapper.selectUserCount(aid, null, null);
            if (ListCount==null){
                adminStatisticsBo.setPrivateSum(0);
                adminStatisticsBo.setSignSum(0);
                adminStatisticsBo.setChannelSum(0);
            }else {
                adminStatisticsBo.setPrivateSum(ListCount.getPrivateSum());
                adminStatisticsBo.setSignSum(ListCount.getSignSum());
                adminStatisticsBo.setChannelSum(ListCount.getChannelSum());
            }
            //计算公出次数
            Integer publicSum = publicReleaseMapper.selectCountByaidAndDate(aid, null, null);
            adminStatisticsBo.setPublicReleaseSum(publicSum);
            //计算跟进次数
            Integer followSum = userFollowMapper.selectByaidAndDate(aid, null, null);
            adminStatisticsBo.setFollowSum(followSum);

        }
        if (adminStatisticsBo.getReceivables()==null) adminStatisticsBo.setReceivables(new BigDecimal(0));
        AdminStatisticsBo asb = adminMapper.adminStatisticsInfoByTime(aid, startTime, endTime);
        if (asb==null) {
            adminStatisticsBo.setRangePrivateSum(0);
            adminStatisticsBo.setRangeSignSum(0);
            adminStatisticsBo.setRangeChannelSum(0);
            adminStatisticsBo.setRangeFollowSum(0);
            adminStatisticsBo.setRangeOrderSum(0);
        }else {
            adminStatisticsBo.setRangeFollowSum(asb.getRangeFollowSum());
            adminStatisticsBo.setRangeOrderSum(asb.getRangeOrderSum());
            //从客户中计算再添加到adminStatisticsBo
            AdminStatisticsBo ListCount = adminMapper.selectUserCount(aid, startTime, endTime);
            adminStatisticsBo.setRangePrivateSum(ListCount.getPrivateSum());
            adminStatisticsBo.setRangeSignSum(ListCount.getSignSum());
            adminStatisticsBo.setRangeChannelSum(ListCount.getChannelSum());

        }
        Integer rangePublicReleaseSum=adminMapper.adminStatisticsPublicReleaseByAidAndTime(aid, startTime, endTime);
        if (rangePublicReleaseSum==null)rangePublicReleaseSum=0;
        adminStatisticsBo.setRangePublicReleaseSum(rangePublicReleaseSum);
        BigDecimal rangeReceivables=adminMapper.addAdminContactsRangeReceivables(aid,startTime,endTime);
        adminStatisticsBo.setRangeReceivables(rangeReceivables);
        //添加外呼数据
        AdminStatisticsBo as = adminCallDayMapper.selectByAidCount(aid, startTime, endTime);
        if (as !=null){
            if (as.getCallSum()!=null)adminStatisticsBo.setCallSum(as.getCallSum());
            if (as.getCallDurationSum()!=null)adminStatisticsBo.setCallDurationSum(as.getCallDurationSum());
            if (as.getConnectSum()!=null)adminStatisticsBo.setConnectSum(as.getConnectSum());
            if (as.getValidSum()!=null)adminStatisticsBo.setValidSum(as.getValidSum());
        }else {
            adminStatisticsBo.setCallSum(0);
            adminStatisticsBo.setCallDurationSum(BigDecimal.ZERO);
            adminStatisticsBo.setConnectSum(0);
            adminStatisticsBo.setValidSum(0);
        }
        //添加销售团队数据
        statisticsSalesTeam(adminStatisticsBo,aid,startTime,endTime);

        return adminStatisticsBo;
    }

    private void statisticsSalesTeam(AdminStatisticsBo res,String aid ,String startTime,String endTime) {
        List<String> list =new ArrayList<>();
        List<SalesTeam> salesTeams = salesTeamMapper.queryByAid(aid);
        //如果不是团队负责人，所有数据都为null
        if (salesTeams.isEmpty()){
            res.setTeamPeopleSum(null);
            res.setTeamCallSum(null);
            res.setTeamCallDurationSum(null);
            return;
        }
        //先获取顶层再迭代获取每一层
        for (SalesTeam e : salesTeams) {
            List<Admin> admins = adminMapper.queryByTeamId(e.getId());
            admins.stream().forEach(e1 -> {
                list.add(e1.getId());
            });
            addSonSalesTeam(list,e);
        }
        Set<String> set = new HashSet<>(list);
        int teamCallSum=0;
        int teamConnectSum=0;
        int teamValidSum=0;
        BigDecimal teamCallDurationSum=BigDecimal.ZERO;
        for (String s : set) {
            AdminStatisticsBo as = adminCallDayMapper.selectByAidCount(s, startTime, endTime);
            if (as != null) {
                if (as.getCallSum()!= null) teamCallSum = teamCallSum + as.getCallSum();
                if (as.getCallDurationSum()!= null) teamCallDurationSum = teamCallDurationSum.add(as.getCallDurationSum());
                if (as.getConnectSum() !=null) teamConnectSum = teamConnectSum + as.getConnectSum();
                if (as.getValidSum()!=null) teamValidSum = teamValidSum + as.getValidSum();

            }
        }
        res.setTeamPeopleSum(set.size());
        res.setTeamCallSum(teamCallSum);
        res.setTeamConnectSum(teamConnectSum);
        res.setTeamValidSum(teamValidSum);
        res.setTeamCallDurationSum(teamCallDurationSum);

    }

    /**
     *
     * @param list
     * @param res
     */
    private void addSonSalesTeam(List<String> list, SalesTeam res) {
        List<SalesTeam> salesTeams = salesTeamMapper.queryBySuperId(res.getId());
        if (!salesTeams.isEmpty()){
            for (SalesTeam e : salesTeams) {
                List<Admin> admins = adminMapper.queryByTeamId(e.getId());
                admins.stream().forEach(e1 -> {
                    list.add(e1.getId());
                });
                addSonSalesTeam(list,e);
            }
        }
    }

    @Override
//    @Cacheable(value = "adminStatisticeLists#300", key = "'key:'+#aid")
    public Object lists(String aid) {
        //获取当月的列表
        Map<String,Object> map=new HashMap<>();
        Days days = new Days();
        List<String> thisMonth = getThisMonth(days);
        List<AdminUserCount> userList = adminMapper.thisMonthUser(days.firstDay,days.endDay, aid);
        List<Integer> signList=new ArrayList<>();
        List<Integer> privateList=new ArrayList<>();
        List<Integer> channelList=new ArrayList<>();
        List<Integer> userFollowList=new ArrayList<>();
        List<Integer> orderList=new ArrayList<>();
        List<Integer> publicReleaseList=new ArrayList<>();
            int signCount=0,privateCount=0,channelCount=0,followCount=0,orderCount=0,publicReleaseCount=0;
        for (String dates : thisMonth) {
            boolean flag=true;
            for (AdminUserCount e : userList) {
                String formatDate = DateUtils.formatDate(e.getDateTime(), AFTConstants.YYYYMMDD);
                if (dates.equals(formatDate)){
                    signCount=signCount+e.getSignCount();
                    int newSign=signCount;
                    signList.add(newSign);
                    privateCount=privateCount+e.getPrivateCount();
                    int newPrivate=privateCount;
                    privateList.add(newPrivate);
                    channelCount=channelCount+e.getChannelCount();
                    int newChannel=channelCount;
                    channelList.add(newChannel);
                    followCount=followCount+e.getFollowCount();
                    int newFollow=followCount;
                    userFollowList.add(newFollow);
                    orderCount=orderCount+e.getOrderCount();
                    int newOrder=orderCount;
                    orderList.add(newOrder);
                    publicReleaseCount=publicReleaseCount+e.getPublicReleaseCount();
                    int newPublicRelease=publicReleaseCount;
                    publicReleaseList.add(newPublicRelease);
                    flag=false;
                }
            }
            if (flag){
                signList.add(signCount);
                privateList.add(privateCount);
                channelList.add(channelCount);
                userFollowList.add(followCount);
                orderList.add(orderCount);
                publicReleaseList.add(publicReleaseCount);
            }
        }
        map.put("dates",thisMonth);
        map.put("signList",signList);
        map.put("privateList",privateList);
        map.put("channelList",channelList);
        //跟进数
        map.put("userFollowList",userFollowList);
        //订单数
        map.put("orderList",orderList);
        //公出企业数
        map.put("publicReleaseList",publicReleaseList);
        return map;
    }

    @Override
    public Object consultantInfo(String startTime, String endTime) {
        String aid=TokenManager.getAdminId();
        endTime=endTime+" 23:59:59";
        Integer shiroType=2;
        if(TokenManager.hasRole(AFTConstants.TECH)){
            shiroType=0;
        }else if(TokenManager.hasRole(AFTConstants.TECH_MANAGER)){
            shiroType=1;
        }
        ConsultantStatisticsBo res = adminMapper.consultantStatisticsInfo(aid,shiroType);
        if (res == null) res=new ConsultantStatisticsBo();
        if (res.getCountPublicRelease()==null)res.setCountPublicRelease(0);
        if (res.getOrderPayment()==null)res.setOrderPayment(0);
        ConsultantStatisticsBo asb = adminMapper.consultantStatisticsInfoByTime(aid, startTime, endTime);
        if (asb!=null){
            res.setRangeProjectCount(asb.getProjectCount());
            res.setRangeInProgress(asb.getInProgress());
            res.setRangeNotStarted(asb.getNotStarted());
            res.setRangeComplete(asb.getComplete());
            res.setRangeStop(asb.getStop());
            res.setRangeCountPublicRelease(asb.getCountPublicRelease());
            res.setRangeCountAssist(asb.getCountAssist());
        }
        return res;
    }

    @Override
    public Object consultantLists(String aid) {
        //获取当月的列表
        Map<String,Object> map=new LinkedHashMap<>();
        Days days = new Days();
        List<String> thisMonth = getThisMonth(days);
        List<ConsultantUserCount> list = adminMapper.consultantthisMonthUser(days.firstDay,days.endDay, aid);
        List<Integer>  projectCountList =new ArrayList<>();
        List<Integer>  inProgressList =new ArrayList<>();
        List<Integer>  notStartedList =new ArrayList<>();
        List<Integer>  completeList =new ArrayList<>();
        List<Integer>  stopList =new ArrayList<>();
        List<Integer>  publicReleaseCountList =new ArrayList<>();
        List<Integer>  assistCountList =new ArrayList<>();
        int projectCount=0,inProgressCount=0,notStartedCount=0,completeCount=0,stopCount=0,publicReleaseCount=0,
                assistCount=0;
        for (String dates : thisMonth) {
            for (ConsultantUserCount e : list) {
                if (e.getDates().equals(dates)){
                    projectCount=projectCount+e.getProjectCount();
                    inProgressCount=inProgressCount+e.getInProgress();
                    notStartedCount=notStartedCount+e.getNotStarted();
                    completeCount=completeCount+e.getComplete();
                    stopCount=stopCount+e.getStop();
                    publicReleaseCount=publicReleaseCount+e.getCountPublicRelease();
                    assistCount=assistCount+e.getCountAssist();
                }
            }
            projectCountList.add(projectCount);
            inProgressList.add(inProgressCount);
            notStartedList.add(notStartedCount);
            completeList.add(completeCount);
            stopList.add(stopCount);
            publicReleaseCountList.add(publicReleaseCount);
            assistCountList.add(assistCount);
        }
        map.put("dates",thisMonth);
        map.put("projectCountList",projectCountList);
        map.put("inProgressList",inProgressList);
        map.put("notStartedList",notStartedList);
        map.put("completeList",completeList);
        map.put("stopList",stopList);
        map.put("publicReleaseCountList",publicReleaseCountList);
        map.put("assistCountList",assistCountList);
        return map;
    }

    @Override
    public Object financeInfo(String startTime, String endTime) {
        String aid = TokenManager.getAdminId();
        OutFinanceCount financeCount=adminMapper.financeInfo(aid, startTime, endTime);
        if (financeCount==null)financeCount= new OutFinanceCount();
        String endDate =endTime+" 23:59:59";
        Integer rangePublicCount = publicReleaseMapper.selectCountByaidAndDate(aid, startTime, endDate);
        if (rangePublicCount==null) rangePublicCount=0;
        financeCount.setRangePublicCount(rangePublicCount);
        BigDecimal rangeReceivables=adminMapper.selectFinanceReceivablesCount(aid,startTime,endDate);
        if (rangeReceivables==null)rangeReceivables=new BigDecimal(0);
        financeCount.setRangeReceivables(rangeReceivables);
        OutFinanceCount outFinanceCount = adminMapper.selectFinanceChangeCount(aid);
        if (outFinanceCount==null) outFinanceCount= new OutFinanceCount();
        if (outFinanceCount.getChangeCount()==null)outFinanceCount.setChangeCount(0);
        if (outFinanceCount.getChangeInvoiceCount()==null)outFinanceCount.setChangeInvoiceCount(0);
        financeCount.setChangeCount(outFinanceCount.getChangeCount());
        financeCount.setChangeInvoiceCount(outFinanceCount.getChangeInvoiceCount());
        return financeCount;
    }

    @Override
    public Object financeLists(String aid) {
        //获取当月的列表
        Map<String,Object> map=new LinkedHashMap<>();
        Days days = new Days();
        List<String> thisMonth = getThisMonth(days);
        List<Integer> orderList=new ArrayList<>();
        List<Integer> expenseList=new ArrayList<>();
        List<Integer> invoiceList=new ArrayList<>();
        List<Integer> memberList=new ArrayList<>();
        List<Integer> paymentList=new ArrayList<>();
        List<Integer> publicList=new ArrayList<>();
        List<OutFinanceCount> financeCounts = financeCountMapper.financeLists(aid, days.firstDay, days.endDay+" 23:59:59");
        List<OutFinanceCount> pList = publicReleaseMapper.selectByaidAndDate(aid, days.firstDay, days.endDay + " 23:59:59");
        int orderCount=0,expenseCount=0, invoiceCount=0,memberCount=0,paymentCount=0,publicCount=0;
        for (String e : thisMonth) {
            for (OutFinanceCount f : financeCounts) {
                if (e.equals(f.getDates())){
                    orderCount+=f.getOrderCount();
                    expenseCount+=f.getExpenseCount();
                    invoiceCount+=f.getInvoiceCount();
                    memberCount+=f.getMemberCount();
                    paymentCount+=f.getPaymentCount();
                }
            }
            for (OutFinanceCount p : pList) {
                if (e.equals(p.getDates())){
                    publicCount+=p.getPublicCount();
                }
            }
            orderList.add(orderCount);
            expenseList.add(expenseCount);
            invoiceList.add(invoiceCount);
            memberList.add(memberCount);
            paymentList.add(paymentCount);
            publicList.add(publicCount);
        }
        map.put("dates",thisMonth);
        map.put("orderList",orderList);
        map.put("expenseList",expenseList);
        map.put("invoiceList",invoiceList);
        map.put("memberList",memberList);
        map.put("paymentList",paymentList);
        map.put("publicList",publicList);
        return map;
    }

    @Override
    @Cacheable(value = "salesTeam#600", key = "'key:'+#aid+'_'+#startTime+'_'+#endTime")
    public Object salesTeam(String aid,String startTime, String endTime) {
        endTime=endTime+" 23:59:59";
        List<SalesTeamBo> resList=new ArrayList<>();
        List<SalesTeam> salesTeams=new ArrayList<>();
        if (TokenManager.hasRole(AFTConstants.SUPERADMIN)){
            List<SalesTeamBo> salesTeamLvlList = salesTeamMapper.findSalesTeamLvlList(1);
            salesTeams.addAll(salesTeamLvlList);
        }else {
            salesTeams= salesTeamMapper.queryByAid(aid);
        }
        //如果不是团队负责人，所有数据都为null
        int teamCallSum=0;
        int teamConnectSum=0;
        int teamValidSum=0;
        BigDecimal teamCallDurationSum=BigDecimal.ZERO;
        //先计算负责人
//        AdminStatisticsBo ab=adminCallDayMapper.selectByAidCount(aid,startTime,endTime);
//        if (ab!= null) {
//            if (ab.getCallSum()!= null) teamCallSum = teamCallSum + ab.getCallSum();
//            if (ab.getCallDurationSum()!= null) teamCallDurationSum = teamCallDurationSum.add(ab.getCallDurationSum());
//            if (ab.getConnectSum()!= null) teamConnectSum = teamConnectSum + ab.getConnectSum();
//            if (ab.getValidSum()!= null) teamValidSum = teamValidSum + ab.getValidSum();
//        }
        if (!salesTeams.isEmpty()){
            //先获取顶层再迭代获取每一层
            for (SalesTeam e : salesTeams) {
                SalesTeamBo salesTeamBo = new SalesTeamBo(e);
                //再计算所有成员
                List<Admin> admins = adminMapper.queryByTeamId(e.getId());
                for (Admin e2 : admins) {
                    AdminStatisticsBo as=adminCallDayMapper.selectByAidCount(e2.getId(), startTime,endTime);
                    if (as != null) {
                        if (as.getCallSum()!= null) teamCallSum = teamCallSum + as.getCallSum();
                        if (as.getCallDurationSum()!= null) teamCallDurationSum = teamCallDurationSum.add(as.getCallDurationSum());
                        if (as.getConnectSum()!= null) teamConnectSum = teamConnectSum + as.getConnectSum();
                        if (as.getValidSum()!= null) teamValidSum = teamValidSum + as.getValidSum();
                    }
                }
                salesTeamBo.setTeamCallSum(teamCallSum);
                salesTeamBo.setTeamCallDurationSum(teamCallDurationSum);
                salesTeamBo.setTeamPeopleSum(admins.size());
                salesTeamBo.setTeamConnectSum(teamConnectSum);
                salesTeamBo.setTeamValidSum(teamValidSum);
                resList.add(salesTeamBo);
                addSonTeam(resList,salesTeamBo,startTime,endTime);
            }
        }
        return resList;
    }

    @Override
    @CacheEvict(value = "salesTeam#600", allEntries = true)
    public Object salesTeamClean() {
        LoggerUtils.debug(getClass(),"营销团队缓存清理");
        return 1;
    }



    private void addSonTeam(List<SalesTeamBo>list, SalesTeamBo salesTeamBo, String startTime, String endTime) {
        List<SalesTeam> salesTeams = salesTeamMapper.queryBySuperId(salesTeamBo.getId());

        if (!salesTeams.isEmpty()){
            //计算所有子项数据
            for (SalesTeam e : salesTeams) {
                SalesTeamBo salesTeamBo2 = new SalesTeamBo(e);
                int teamCallSum=0;
                int teamConnectSum=0;
                int teamValidSum=0;
                BigDecimal teamCallDurationSum=BigDecimal.ZERO;
                //先计算负责人
//                AdminStatisticsBo ab=callLogMapper.selectAdminCallSum(e.getAid(),startTime,endTime);
//                if (ab!= null) {
//                    if (ab.getCallSum()!= null) teamCallSum = teamCallSum + ab.getCallSum();
//                    if (ab.getCallDurationSum()!= null) teamCallDurationSum = teamCallDurationSum.add(ab.getCallDurationSum());
//                    if (ab.getConnectSum()!= null) teamConnectSum = teamConnectSum + ab.getConnectSum();
//                    if (ab.getValidSum()!= null) teamValidSum = teamValidSum + ab.getValidSum();
//                }
                List<Admin> admins = adminMapper.queryByTeamId(e.getId());
                for (Admin admin : admins) {
                    AdminStatisticsBo as=callLogMapper.selectAdminCallSum(admin.getId(),startTime,endTime);
                    if (as!= null) {
                        if (as.getCallSum()!= null) teamCallSum = teamCallSum + as.getCallSum();
                        if (as.getCallDurationSum()!= null) teamCallDurationSum = teamCallDurationSum.add(as.getCallDurationSum());
                        if (as.getConnectSum()!= null) teamConnectSum = teamConnectSum + as.getConnectSum();
                        if (as.getValidSum()!= null) teamValidSum = teamValidSum + as.getValidSum();
                    }
                }
                salesTeamBo2.setTeamCallSum(teamCallSum);
                salesTeamBo2.setTeamCallDurationSum(teamCallDurationSum);
                salesTeamBo2.setTeamConnectSum(teamConnectSum);
                salesTeamBo2.setTeamValidSum(teamValidSum);
                salesTeamBo2.setTeamPeopleSum(admins.size());
                //迭代计算并赋值给上一层
                addSonTeam(list,salesTeamBo2,startTime,endTime);
                if (salesTeamBo2.getTeamPeopleSum()!=null)salesTeamBo.setTeamPeopleSum(salesTeamBo.getTeamPeopleSum() + salesTeamBo2.getTeamPeopleSum());
                if (salesTeamBo2.getTeamCallSum()!=null)salesTeamBo.setTeamCallSum(salesTeamBo.getTeamCallSum()+salesTeamBo2.getTeamCallSum());
                if (salesTeamBo2.getTeamCallDurationSum()!=null)salesTeamBo.setTeamCallDurationSum(salesTeamBo.getTeamCallDurationSum().add(salesTeamBo2.getTeamCallDurationSum()));
                if (salesTeamBo2.getTeamConnectSum()!=null)salesTeamBo.setTeamConnectSum(salesTeamBo.getTeamConnectSum()+salesTeamBo2.getTeamConnectSum());
                if (salesTeamBo2.getTeamValidSum()!=null)salesTeamBo.setTeamValidSum(salesTeamBo.getTeamValidSum()+salesTeamBo2.getTeamValidSum());
                list.add(salesTeamBo2);
            }
        }
    }


    public  List<String> getThisMonth(Days days) {
        //获取三十天前的日期
        Date date=new Date();
        Calendar ca=Calendar.getInstance();
        ca.setTime(date);
        ca.add(Calendar.DAY_OF_MONTH,-30);
        days.setFirstDay(DateUtils.formatDate(ca.getTime(),AFTConstants.YYYYMMDD));
        List<String> list=new ArrayList<>();
        for (int i=0;i<31;i++){
            if (i==0){
                Calendar newc=Calendar.getInstance();
                newc.setTime(ca.getTime());
                list.add(DateUtils.formatDate(newc.getTime(), AFTConstants.YYYYMMDD));
            }else {
                ca.add(Calendar.DAY_OF_MONTH,1);
                ca.set(Calendar.HOUR_OF_DAY,0);
                if (ca.getTimeInMillis()<date.getTime()){
                    Calendar newc=Calendar.getInstance();
                    newc.setTime(ca.getTime());
                    days.setEndDay(DateUtils.formatDate(newc.getTime(), AFTConstants.YYYYMMDD));
                    list.add(days.getEndDay());
                }
            }
        }
    return list;

    }
    class Days{
        private String firstDay;
        private String endDay;

        public String getFirstDay() {
            return firstDay;
        }

        public void setFirstDay(String firstDay) {
            this.firstDay = firstDay;
        }

        public String getEndDay() {
            return endDay;
        }

        public void setEndDay(String endDay) {
            this.endDay = endDay;
        }
    }


    /**
     *  月份数据
     * @return
     */
    @Override
    public Map<String,Object>  monthData(String  dateStr) {
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
        LocalDate localDate =LocalDate.parse(dateStr,formatter);
        LocalDate endDate = localDate.plusMonths(1);
        List<PublicRelease> publicReleases = publicReleaseMapper.selectByMonth(localDate, endDate,null);
        List<PublicRelease> publicReleases2 = publicReleaseMapper.selectByMonth(localDate, endDate,1);
        List<AdminPublicDuration> list=new ArrayList<>();
        List<String> errors=new ArrayList<>();
        for (PublicRelease e : publicReleases) {
            AdminPublicDuration a = new AdminPublicDuration();
            pushAdminNameAndProvince(e.getAid(),a);
            //计算时间差,再加一天就是一共多少天
            long daysBetween = DateUtils.getDaysBetween(e.getReleaseStart(), e.getReleaseEnd());
            daysBetween+=1;
            if (daysBetween==1){
                a.setId(e.getAid());
                a.setDate(e.getReleaseStart());
                a.setDuration(e.getDuration());
                list.add(a);
            }else if(daysBetween>0){
                double v = e.getDuration() / daysBetween;
                for (int i = 0; i < daysBetween; i++) {
                    LocalDate localDate1 = e.getReleaseStart().toInstant().atZone(ZoneId.systemDefault()).toLocalDate().plusDays(i);
                    if (localDate1.isBefore(endDate)){
                        a.setId(e.getAid());
                        a.setDate(Date.from(localDate1.atStartOfDay(ZoneId.systemDefault()).toInstant()));
                        a.setDuration(v);
                        list.add(a);
                    }else{
                        errors.add(String.format("用户[%s]公出时间[%s]超出[%s],不计入本月公出",a.getName(),localDate1.format(formatter),endDate.format(formatter)));
                    }

                }
            }
        }
        for (PublicRelease e : publicReleases2) {
            AdminPublicDuration a = new AdminPublicDuration();
            pushAdminNameAndProvince(e.getAid(),a);
            long daysBetween = DateUtils.getDaysBetween(e.getReleaseStart(), e.getReleaseEnd());
            if(daysBetween>0){
                double v = e.getDuration() / daysBetween;
                for (int i = 0; i < daysBetween; i++) {
                    LocalDate localDate1 = e.getReleaseStart().toInstant().atZone(ZoneId.systemDefault()).toLocalDate().plusDays(i);
                    if (localDate1.isAfter(localDate)){
                        a.setId(e.getAid());
                        a.setDate(Date.from(localDate1.atStartOfDay(ZoneId.systemDefault()).toInstant()));
                        a.setDuration(v);
                        list.add(a);
                    }else{
                        errors.add(String.format("用户[%s]公出时间[%s]小于[%s],不计入本月公出",a.getName(),localDate1.format(formatter),endDate.format(formatter)));
                    }

                }
            }

        }
        //将数据统计到人
        Map<String, BigDecimal> durationMap = new HashMap<>();
        for (AdminPublicDuration e : list) {
            String id = e.getId(); // 假设 AdminStatisticsBo 有一个 getId() 方法
            BigDecimal duration = BigDecimal.valueOf(e.getDuration()); // 假设 AdminStatisticsBo 有一个 getCallDurationSum() 方法
            if (durationMap.containsKey(id)) {
                BigDecimal currentDuration = durationMap.get(id);
                durationMap.put(id, currentDuration.add(duration));
            } else {
                durationMap.put(id, duration);
            }
        }
        List<AdminPublicDuration> list2=sumDurationsById(list);
        Map<String,Object> map=new HashMap<>();
        map.put("date",list);
        map.put("count",list2);
        map.put("errors",errors);
        return map;
    }

    @Override
    public List<selectAllUserDataBo> AllDataExport() {
        // 获取今天，明天，本周第一天，下周第一天，本月第一天，下月第一天，本年第一天，下年第一天
        Date today = new Date();
        //获取明天
        Calendar md = Calendar.getInstance();
        md.setTime(today);
        md.add(Calendar.DATE, 1);
        Date tomorrow = md.getTime();
        //获取本周的第一天
        Date firstDayOfWeek = DateUtils.getFirstDayOfWeek(today);
        //获取下周的第一天
        Calendar c = Calendar.getInstance();
        c.setTime(firstDayOfWeek);
        c.add(Calendar.DATE, 7);
        Date firstDayOfNextWeek = c.getTime();
        //获取本月的第一天
        Date firstDayOfMonth = DateUtils.getFirstDayOfMonth(today);
        //获取下月的第一天
        Calendar c2 = Calendar.getInstance();
        c2.setTime(firstDayOfMonth);
        c2.add(Calendar.MONTH, 1);
        Date firstDayOfNextMonth = c2.getTime();
        //获取本年的第一天
        Calendar c3 = Calendar.getInstance();
        c3.setTime(today);
        c3.set(Calendar.DAY_OF_YEAR, 1);
        c3.set(Calendar.HOUR_OF_DAY, 0);
        Date firstDayOfYear = c3.getTime();
        //获取下年的第一天
        Calendar c4 = Calendar.getInstance();
        c4.setTime(firstDayOfYear);
        c4.add(Calendar.YEAR, 1);
        Date firstDayOfNextYear = c4.getTime();
        // 将日期转换为字符串
        String d1 = DateUtils.formatDate(today, AFTConstants.YYYYMMDD);
        String d2 = DateUtils.formatDate(tomorrow, AFTConstants.YYYYMMDD);
        String w1 = DateUtils.formatDate(firstDayOfWeek, AFTConstants.YYYYMMDD);
        String w2 = DateUtils.formatDate(firstDayOfNextWeek, AFTConstants.YYYYMMDD);
        String m1 = DateUtils.formatDate(firstDayOfMonth, AFTConstants.YYYYMMDD);
        String m2 = DateUtils.formatDate(firstDayOfNextMonth, AFTConstants.YYYYMMDD);
        String y1 = DateUtils.formatDate(firstDayOfYear, AFTConstants.YYYYMMDD);
        String y2 = DateUtils.formatDate(firstDayOfNextYear, AFTConstants.YYYYMMDD);
        List<selectAllUserDataBo> list = adminMapper.selectAllUserData(d1, d2, w1, w2, m1, m2, y1, y2);
        return list;
    }


    private void pushAdminNameAndProvince(String aid, AdminPublicDuration a) {
        Admin admin = adminMapper.selectById(aid);
        Department department = departmentMapper.selectByPrimaryKey(admin.getDepartmentId());
        String name = admin.getName();
        // 去掉括号及其内部的内容
        if (name.contains("(")){
            int index = name.indexOf('(');
            name = name.substring(0, index);
        }else if (name.contains("（")){
            int index = name.indexOf('（');
            name = name.substring(0, index);
        }
        a.setName(name);
        a.setWorkingHours(department.getWorkingHoursType());
    }


    public List<AdminPublicDuration>  sumDurationsById(List<AdminPublicDuration> adminPublicDurations) {
        Map<String, AdminPublicDuration> durationMap = new HashMap<>();
        for (AdminPublicDuration adminPublicDuration : adminPublicDurations) {
            String id = adminPublicDuration.getId();
            String name = adminPublicDuration.getName();
            double duration = adminPublicDuration.getDuration();
            if (durationMap.containsKey(id)) {
                AdminPublicDuration summary = durationMap.get(id);
                summary.setWorkingHours(adminPublicDuration.getWorkingHours());
                BigDecimal countDuration = BigDecimal.valueOf(summary.getDuration()).add(BigDecimal.valueOf(duration));
                summary.setDuration(countDuration.doubleValue());
                summary.setName(name);
                summary.setCountNumber(summary.getCountNumber()+1);
                if (summary.getWorkingHours()==null){
                    throw new BusinessException(String.format("用户[%s]未设置工作类型",name));
                }
               if (summary.getWorkingHours()==2){
                    summary.setConversion(7.0);
                } else{
                    summary.setConversion(7.5);
                }
                if (summary.getConversion()!=null){
                    BigDecimal divide = BigDecimal.valueOf(summary.getDuration()).divide(BigDecimal.valueOf(summary.getConversion()), 2, RoundingMode.HALF_UP);
                    summary.setDays(divide.doubleValue());
                }
            } else {
                AdminPublicDuration e = new AdminPublicDuration(id, name, duration);
                e.setWorkingHours(adminPublicDuration.getWorkingHours());
                if (e.getWorkingHours()==null){
                    throw new BusinessException(String.format("用户[%s]未设置工作类型",name));
                }
                if (e.getWorkingHours()==2){
                    e.setConversion(7.0);
                } else{
                    e.setConversion(7.5);
                }
                if (e.getConversion()!=null){
                    BigDecimal divide = BigDecimal.valueOf(e.getDuration()).divide(BigDecimal.valueOf(e.getConversion()), 2, RoundingMode.HALF_UP);
                    e.setDays(divide.doubleValue());
                }
                durationMap.put(id, e);
            }
        }
        return new ArrayList<>(durationMap.values());
    }






}
