package com.yd.api.practitioner.service.impl;

import com.yd.api.practitioner.service.PractitionerService;
import com.yd.api.practitioner.service.ScheduleTrackService;
import com.yd.api.practitioner.vo.sechedule.*;
import com.yd.api.result.CommonResult;
import com.yd.dal.entity.customer.AclCustomer;
import com.yd.dal.entity.customer.AclPractitioner;
import com.yd.dal.entity.customer.AclPractitionerPotential;
import com.yd.dal.entity.customer.AclPractitionerPotentialAssignedTrack;
import com.yd.dal.entity.customer.practitioner.PractitionerRankInfo;
import com.yd.dal.entity.marketing.MktLeadsAssignedTrack;
import com.yd.dal.entity.meta.MdDropOptions;
import com.yd.dal.entity.practitioner.*;
import com.yd.dal.mapper.customer.AclPractitionerPotentialMapper;
import com.yd.dal.mapper.marketing.ScheduleTrackMapper;
import com.yd.dal.service.agms.AgmsDashboardDALService;
import com.yd.dal.service.customer.AclPractitionerDALService;
import com.yd.dal.service.customer.AclPractitionerPotentialAssignedTrackDALService;
import com.yd.dal.service.marketing.MktLeadsAssignedTrackDALService;
import com.yd.dal.service.meta.MdDropOptionsDALService;
import com.yd.rmi.n22.salary.pojo.Achieve;
import com.yd.util.CommonUtil;
import com.yd.util.config.ZHBErrorConfig;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

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

@Service
public class ScheduleTrackServiceImpl implements ScheduleTrackService {
    @Autowired
    private ScheduleTrackMapper scheduleTrackMapper;
    @Autowired
    private AclPractitionerPotentialAssignedTrackDALService aclPractitionerPotentialAssignedTrackDALService;
    @Autowired
    private MdDropOptionsDALService mdDropOptionsDALService;
    @Autowired
    private MktLeadsAssignedTrackDALService mktLeadsAssignedTrackDALService;
    @Autowired
    private AgmsDashboardDALService agmsDashboardDALService;
    @Autowired
    private AclPractitionerPotentialMapper aclPractitionerPotentialMapper;
    @Autowired
    private PractitionerService practitionerService;
    @Autowired
    private AclPractitionerDALService aclPractitionerDALService;

    @Override
    public AddScheduleTrackResponseVO insert(AddScheduleTrackRequestVO requestVO) {
        // 响应实体
        AddScheduleTrackResponseVO resp = new AddScheduleTrackResponseVO();
        // 数据库实体
        ScheduleTrack schedule = new ScheduleTrack();
        BeanUtils.copyProperties(requestVO, schedule);
        try {
            // id不为空即修改-先删除旧的
            Long id = requestVO.getId();
            Integer taskType = requestVO.getTaskType();
            if (!CommonUtil.isNullOrZero(id)) {
                // 根据id删除日程表记录
                scheduleTrackMapper.deleteScheduleTrackById(id);
                if (Integer.valueOf(1).equals(taskType)) {
                    // 根据id删除商机表记录
                    mktLeadsAssignedTrackDALService.deleteScheduleTrackById(id);
                }
                if (Integer.valueOf(2).equals(taskType)) {
                    // 根据id删除增员记录
                    aclPractitionerPotentialAssignedTrackDALService.deleteScheduleTrackById(id);
                }
                // id置空
                schedule.setId(null);
            }
            String taskTimeFrom = schedule.getTaskTimeFrom();
            String taskTimeEnd = schedule.getTaskTimeEnd();
            String trackTime = CommonUtil.dateParseString(schedule.getTrackTime(), "yyyy-MM-dd");
            Long practitionerId = schedule.getPractitionerId();
            Long mdDropOptionId = schedule.getMdDropOptionId();
            // 判断日程是否重复
            if (!CommonUtil.isNullOrBlank(taskTimeFrom) && !CommonUtil.isNullOrBlank(taskTimeEnd)) {
                boolean isConflict = this.checkTimePeriodConflict(trackTime, taskTimeFrom, taskTimeEnd, practitionerId, mdDropOptionId);
                if (isConflict) {
                    resp.setCommonResult(new CommonResult(false, "该时间段内该类型日程已存在"));
                    return resp;
                }
            } else {
                resp.setCommonResult(new CommonResult(false, "taskTimeFrom,taskTimeEnd不能为空"));
                return resp;
            }

            Map<Long, MdDropOptions> taskTypeMap = this.getScheduleTaskTypeMap();
            Integer trackScore = taskTypeMap.get(mdDropOptionId).getDropOptionScore();
            schedule.setTrackScore(trackScore);
            schedule.setCreatedBy(practitionerId);
            schedule.setUpdatedBy(practitionerId);
            schedule.setUpdatorType(2);
            schedule.setCreatorType(2);
            Date curTime = new Date();
            schedule.setUpdatedAt(new Date());
            schedule.setCreatedAt(curTime);

            scheduleTrackMapper.insert(schedule);
            // 营销日程同步插入到商机活动跟踪表，增员日程同步插入到增援活动跟踪表
            Long referLeadsId = schedule.getReferLeadsId();
            Long referPotentialId = schedule.getReferPotentialId();
            if (1 == taskType && null != referLeadsId) {
                this.insertOpportunityRecord(schedule);
            }
            if (2 == taskType && null != referPotentialId) {
                AclPractitionerPotential potential = aclPractitionerPotentialMapper.selectByPrimaryKey(referPotentialId);
                schedule.setCustomerId(potential.getCustomerId());
                this.insertPotentialAssignedTrack(schedule);
            }
            resp.setCommonResult(new CommonResult(true, "任务添加成功"));
        } catch (Exception e) {
            e.printStackTrace();
            resp.setCommonResult(new CommonResult(false, e.getMessage()));
        }
        return resp;
    }

    private boolean checkTimePeriodConflict(String trackTime, String taskTimeFrom, String taskTimeEnd, Long practitionerId, Long mdDropOptionId) {
        List<ScheduleTrack> showList = new ArrayList<>();
        List<ScheduleTrack> dataList = scheduleTrackMapper.queryScheduleTrackList(practitionerId, trackTime);
        // 获得当天展示的日程列表
        for (ScheduleTrack schedule: dataList) {
            if (this.checkFixedDay(trackTime, schedule)) {
                showList.add(schedule);
            }
        }
        // 检查时间段是否冲突
        boolean isConflict = false;
        String staskTimeFrom;
        String staskTimeEnd;
        Long spractitionerId;
        Long smdDropOptionId;
        for (ScheduleTrack schedule: showList) {

            staskTimeFrom = schedule.getTaskTimeFrom();
            staskTimeEnd = schedule.getTaskTimeEnd();
            spractitionerId = schedule.getPractitionerId();
            smdDropOptionId = schedule.getMdDropOptionId();
            if (taskTimeFrom.equals(staskTimeFrom)
                    && taskTimeEnd.equals(staskTimeEnd)
                    && practitionerId.equals(spractitionerId)
                    && mdDropOptionId.equals(smdDropOptionId)
            ) {
                isConflict = true;
            }
        }
        return isConflict;
    }

    private void insertOpportunityRecord(ScheduleTrack schedule) {
        MktLeadsAssignedTrack track = new MktLeadsAssignedTrack();
        BeanUtils.copyProperties(schedule, track, "id");
        //保存
        mktLeadsAssignedTrackDALService.saveTrack(track);
    }

    private void insertPotentialAssignedTrack(ScheduleTrack schedule) {
        Long practitionerId = schedule.getPractitionerId();
        Long potentialId = schedule.getReferPotentialId();
        Long trackStatusId = schedule.getMdDropOptionId();
        String notice = schedule.getNotice();
        Date trackTimeDate = schedule.getTrackTime();

        AclPractitionerPotentialAssignedTrack assignedTrack = new AclPractitionerPotentialAssignedTrack();
        List<AclPractitionerPotentialAssignedTrack> assignedTrackIsLastedList = aclPractitionerPotentialAssignedTrackDALService.findByPotentialIdAndIsLasted(potentialId,1);
        //1、更新最新的状态
        if(assignedTrackIsLastedList != null && !assignedTrackIsLastedList.isEmpty()){
            List<AclPractitionerPotentialAssignedTrack> assignedTrackUpdateList = new ArrayList<>();
            for(AclPractitionerPotentialAssignedTrack item : assignedTrackIsLastedList){
                item.setIsLasted(0);
                item.setUpdatedBy(practitionerId);
                item.setUpdaterType(2);
                item.setUpdatedAt(new Date());
                assignedTrackUpdateList.add(item);
            }
            aclPractitionerPotentialAssignedTrackDALService.updateAll(assignedTrackUpdateList);
        }
        //2、插入
        MdDropOptions options = mdDropOptionsDALService.findById(trackStatusId);
        assignedTrack.setTrackScore(options.getDropOptionScore());
        assignedTrack.setPractitionerAssignedId(practitionerId);
        assignedTrack.setPractitionerPotentialId(potentialId);
        assignedTrack.setTrackStatusId(trackStatusId);
        assignedTrack.setNotice(notice);
        assignedTrack.setTrackTime(trackTimeDate);
        assignedTrack.setIsActive(1);
        assignedTrack.setIsLasted(1);
        assignedTrack.setCreatorType(2);
        assignedTrack.setCreatedBy(practitionerId);
        assignedTrack.setCreatedAt(new Date());
        aclPractitionerPotentialAssignedTrackDALService.save(assignedTrack);

    }

    @Override
    public QueryScheduleTrackListResponseVO queryScheduleTrackList(QueryScheduleTrackListRequestVO requestVO) {
        QueryScheduleTrackListResponseVO resp = new QueryScheduleTrackListResponseVO();

        Long practitionerId = requestVO.getPractitionerId();
        String trackDate = requestVO.getTrackTime();
        if (StringUtils.isEmpty(trackDate) || null == practitionerId) {
            resp.setCommonResult(new CommonResult(true, "经纪人id和查询时间不能为空"));
            return resp;
        }
        List<ScheduleTrackVO> showList = new ArrayList<>();
        try {
            //等保调整
            List<AclCustomer> findByObjSortable = aclPractitionerDALService.getAclCustomers(practitionerId,null);
            if(null == findByObjSortable ){
                resp.setCommonResult(new CommonResult(false,ZHBErrorConfig.getErrorInfo("630028")));
                return resp;
            }
            List<ScheduleTrack> dataList = scheduleTrackMapper.queryScheduleTrackList(practitionerId, trackDate);
            Map<Long, MdDropOptions> taskTypeMap = this.getScheduleTaskTypeMap();
            String optionName = null;
            for (ScheduleTrack schedule: dataList) {
                if (this.checkFixedDay(trackDate, schedule)) {
                    ScheduleTrackVO scheduleTrackVO = new ScheduleTrackVO();
                    BeanUtils.copyProperties(schedule, scheduleTrackVO);
                    // 获取optionName
                    optionName = taskTypeMap.get(schedule.getMdDropOptionId()).getDropOptionName();
                    scheduleTrackVO.setMdDropOptionName(optionName);
                    showList.add(scheduleTrackVO);
                }
            }
            resp.setDataList(showList);
            resp.setCommonResult(new CommonResult(true, ZHBErrorConfig.getErrorInfo("800000")));
        } catch (Exception e) {
            e.printStackTrace();
            resp.setCommonResult(new CommonResult(false, e.getMessage()));
        }
        return resp;
    }

    private Map<Long, MdDropOptions> getScheduleTaskTypeMap() {
        Map<Long, MdDropOptions> saleOptMap = mdDropOptionsDALService.queryIdObjMapByByDropMasterCode("bizchance_promotion_action");
        Map<Long, MdDropOptions> recruitOptMap = mdDropOptionsDALService.queryIdObjMapByByDropMasterCode("team_building_track");
        Map<Long, MdDropOptions> otherOptMap = mdDropOptionsDALService.queryIdObjMapByByDropMasterCode("pep_schedule_task_others");

        Map<Long, MdDropOptions> taskTypeMap = new HashMap<>();
        taskTypeMap.putAll(saleOptMap);
        taskTypeMap.putAll(recruitOptMap);
        taskTypeMap.putAll(otherOptMap);
        return taskTypeMap;
    }

    private boolean checkFixedDay(String trackDate, ScheduleTrack track) {
        Date date = CommonUtil.stringParseDate(trackDate, "yyyy-MM-dd");
        String week = CommonUtil.getWeekOfDate(date);
        String trackTime = CommonUtil.dateParseString(track.getTrackTime(), "yyyy-MM-dd");
        Integer flag = 0;
        switch (week) {
            case "1":
                flag = track.getTaskRoutineAtweek1();
                break;
            case "2":
                flag = track.getTaskRoutineAtweek2();
                break;
            case "3":
                flag = track.getTaskRoutineAtweek3();
                break;
            case "4":
                flag = track.getTaskRoutineAtweek4();
                break;
            case "5":
                flag = track.getTaskRoutineAtweek5();
                break;
            case "6":
                flag = track.getTaskRoutineAtweek6();
                break;
            case "0":
                flag = track.getTaskRoutineAtweek7();
                break;
            default:
                break;
        }
        return trackTime.equals(trackDate) || Integer.valueOf(1).equals(flag);
    }

    @Override
    public QueryPEPScoreResponseVO queryPEPScore(QueryPEPScoreRequestVO requestVO) {
        QueryPEPScoreResponseVO resp = new QueryPEPScoreResponseVO();
        Long practitionerId = requestVO.getPractitionerId();
        try {
            //等保调整
            List<AclCustomer> findByObjSortable = aclPractitionerDALService.getAclCustomers(practitionerId,null);
            if(null == findByObjSortable ){
                resp.setCommonResult(new CommonResult(false,ZHBErrorConfig.getErrorInfo("630028")));
                return resp;
            }
            // 获取本月第一天
            Calendar cal = Calendar.getInstance();
            cal.add(Calendar.MONTH, 0);
            // 获取到本月起始日
            int actualMinimum = cal.getActualMinimum(Calendar.DAY_OF_MONTH);
            cal.set(cal.get(Calendar.YEAR), cal.get(Calendar.MONDAY), actualMinimum, 00, 00, 00);
            // 获取本月起始日的年月日时分秒格式
            Date monthOne = cal.getTime();

            // 获取本月当前日的年月日时分秒格式
            Date today = new Date();
            // 获取本周第一天（周一为始）
            Calendar cal2 = Calendar.getInstance();
            cal2.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
            cal2.set(Calendar.HOUR_OF_DAY, 0);
            cal2.set(Calendar.MINUTE, 0);
            cal2.set(Calendar.SECOND, 0);
            Date weekOne = cal2.getTime();

            // 获取团队成员或被辅导人的practitionerId
            List<Long> practitionerIdList = practitionerService.getPractitionerIdList(practitionerId,null);
            AclPractitioner practitioner = aclPractitionerDALService.findPractitionerByRaise(practitionerId);
            if(null != practitioner && null != practitioner.getRaiseId()){
                practitionerIdList.add(practitioner.getId());
                List<Long> practitionerRaiseIdList = practitionerService.getPractitionerIdList(practitioner.getId(),null);
                practitionerIdList.addAll(practitionerRaiseIdList);
            }

            // 根据团队长经纪人id查询团队每个成员本日，本周，本月得分以及---线上本月FYC
            List<PersonalPEPScore> saleAndRecuit = scheduleTrackMapper.querySaleRecuitScoreFYC(practitionerIdList);
            // 获取nameList
            List<String> nameList = new ArrayList<>();
            saleAndRecuit.forEach(i->nameList.add(i.getName()));
            List<PersonalOffLineFYC> personalOffLineFYCList = this.offLineFYC(nameList);


            // 计算总FYC
            this.computeTotalFYC(saleAndRecuit, personalOffLineFYCList);

            // 其他活动有长期固定，通过计算时间段内展示次数，算得总分
            // 先获得每个人所有的其他活动
            List<PersonalSchedule> personalScheduleList = scheduleTrackMapper.queryPersonalScheduleList(practitionerIdList, today);

            // 根据活动算本日，本周，本月的分数
            this.computeOtherScore(personalScheduleList, today, weekOne, monthOne);
            // 最后合并营销增员和其他活动的分数
            this.mergeScore(personalScheduleList, saleAndRecuit);
            // 计算团队平均分
            Map<String, Object> average = this.computeTeamAverageScore(saleAndRecuit, practitionerIdList.size());

            resp.setPersonalList(saleAndRecuit);
            resp.setAverage(average);
            for (PersonalPEPScore s: saleAndRecuit) {
                if (s.getPractitionerId().equals(practitionerId)) {
                    resp.setPerson(s);
                }
            }
            resp.setCommonResult(new CommonResult(true, ZHBErrorConfig.getErrorInfo("800000")));
        } catch (Exception e) {
            e.printStackTrace();
            resp.setCommonResult(new CommonResult(false, e.getMessage()));
        }
        return resp;
    }

    private List<PersonalOffLineFYC> offLineFYC(List<String> nameList) {
        List<Achieve> achieveList = agmsDashboardDALService.queryN22FYC(1, 1, "");
        // 组装返回报文
        List<PersonalOffLineFYC> resultList = new ArrayList<>();
        PersonalOffLineFYC offLineFYC = null;
        for (String name: nameList) {
            for (Achieve achieve : achieveList) {
                if (name.equals(achieve.getDescription())) {
                    offLineFYC = new PersonalOffLineFYC();
                    offLineFYC.setFYC(new BigDecimal(achieve.getFYC()));
                    offLineFYC.setName(achieve.getDescription());

                    resultList.add(offLineFYC);
                    break;
                }
            }
        }

        return resultList;
    }

    private void computeTotalFYC(List<PersonalPEPScore> saleAndRecuit, List<PersonalOffLineFYC> personalOffLineFYCList) {
        for (PersonalPEPScore online: saleAndRecuit ) {
            for (PersonalOffLineFYC offline: personalOffLineFYCList) {
                if (online.getMobileNo().equals(offline.getMobileNo())) {
                    BigDecimal totalFYC = online.getFYC().add(offline.getFYC());
                    online.setFYC(totalFYC);
                    break;
                }
            }
        }
    }

    @Override
    public QueryPEPScoreDetailResponseVO queryPEPScoreDetail(QueryPEPScoreDetailRequestVO requestVO) {
        QueryPEPScoreDetailResponseVO resp = new QueryPEPScoreDetailResponseVO();
        Long practitionerId = requestVO.getPractitionerId();
        String time = requestVO.getTime();

        //等保调整
        List<AclCustomer> findByObjSortable = aclPractitionerDALService.getAclCustomers(practitionerId,1L);
        if(null == findByObjSortable ){
            resp.setCommonResult(new CommonResult(false,ZHBErrorConfig.getErrorInfo("630028")));
            return resp;
        }
        // 根据time获取查询起始日期和结束日期，默认当天
        Date startDate = new Date();
        Date endDate = new Date();

        Calendar cal = Calendar.getInstance();
        if ("w".equalsIgnoreCase(time)) {
            cal.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
            cal.set(Calendar.HOUR_OF_DAY, 0);
            cal.set(Calendar.MINUTE, 0);
            cal.set(Calendar.SECOND, 0);
            startDate = cal.getTime();
        }
        if ("m".equalsIgnoreCase(time)) {
            cal.add(Calendar.MONTH, 0);
            // 获取到本月起始日
            int actualMinimum = cal.getActualMinimum(Calendar.DAY_OF_MONTH);
            cal.set(cal.get(Calendar.YEAR), cal.get(Calendar.MONDAY), actualMinimum, 00, 00, 00);
            startDate = cal.getTime();
        }
        try {
            // 根据经纪人id查询个人所有日程
            List<ScheduleTrack> scheduleList = scheduleTrackMapper.queryPersonalScheduleListByTime(practitionerId, time, new Date());
            // 计算增员日程和销售日程的得分
            List<Long> saleOption = mdDropOptionsDALService.queryIdByByDropMasterCode("bizchance_promotion_action");
            List<Long> RecruitOption = mdDropOptionsDALService.queryIdByByDropMasterCode("team_building_track");

            Long recruitScore = 0L;
            Long saleScore = 0L;
            Long coachScore = 0L;
            Long trainScore = 0L;
            Long meetingScore = 0L;
            for (ScheduleTrack schedule : scheduleList) {
                if (saleOption.contains(schedule.getMdDropOptionId())) {
                    saleScore += schedule.getTrackScore();
                    continue;
                }
                if (RecruitOption.contains(schedule.getMdDropOptionId())) {
                    recruitScore += schedule.getTrackScore();
                    continue;
                }
                if (223 == schedule.getMdDropOptionId()) {
                    coachScore += this.calculateScheduleDisplayCount(schedule, startDate, endDate) * schedule.getTrackScore();
                    continue;
                }
                if (224 == schedule.getMdDropOptionId()) {
                    trainScore += this.calculateScheduleDisplayCount(schedule, startDate, endDate) * schedule.getTrackScore();
                    continue;
                }
                if (226 == schedule.getMdDropOptionId()) {
                    meetingScore += this.calculateScheduleDisplayCount(schedule, startDate, endDate) * schedule.getTrackScore();
                    continue;
                }
            }

            PEPScoreDetail PEPScoreDetail = new PEPScoreDetail();
            PEPScoreDetail.setRecruitScore(recruitScore);
            PEPScoreDetail.setSaleScore(saleScore);
            PEPScoreDetail.setCoachScore(coachScore);
            PEPScoreDetail.setTrainScore(trainScore);
            PEPScoreDetail.setMeetingScore(meetingScore);
            // 根据practitionerId查询经纪人姓名
            String name = scheduleTrackMapper.queryNameByPractitionerId(practitionerId);
            PEPScoreDetail.setName(name);

            resp.setDetail(PEPScoreDetail);
            resp.setCommonResult(new CommonResult(true, ZHBErrorConfig.getErrorInfo("800000")));

        } catch (Exception e) {
            e.printStackTrace();
            resp.setCommonResult(new CommonResult(false, e.getMessage()));
        }
        return resp;
    }

    @Override
    public DeleteScheduleByIdResponseVO deleteScheduleTrackById(DeleteScheduleTrackByIdRequestVO requestVO) {
        DeleteScheduleByIdResponseVO resp = new DeleteScheduleByIdResponseVO();
        Long scheduleTrackId = requestVO.getScheduleTrackId();
        Integer taskType = requestVO.getTaskType();
        try {
            // 根据id删除日程表记录
            scheduleTrackMapper.deleteScheduleTrackById(scheduleTrackId);
            if (Integer.valueOf(1).equals(taskType)) {
                // 根据id删除商机表记录
                mktLeadsAssignedTrackDALService.deleteScheduleTrackById(scheduleTrackId);
            }
            if (Integer.valueOf(2).equals(taskType)) {
                // 根据id删除增员记录
                aclPractitionerPotentialAssignedTrackDALService.deleteScheduleTrackById(scheduleTrackId);
            }
            resp.setCommonResult(new CommonResult(true, ZHBErrorConfig.getErrorInfo("800000")));

        } catch (Exception e) {
            e.printStackTrace();
            resp.setCommonResult(new CommonResult(false, e.getMessage()));
        }
        return resp;
    }

    private Map<String, Object> computeTeamAverageScore(List<PersonalPEPScore> saleAndRecuit, int teamSize) {
        PersonalPEPScore personalScore = null;
        Long dayScore = 0L;
        Long weekScore = 0L;
        Long monthScore = 0L;
        BigDecimal FYC = new BigDecimal(0);
        for (int i = 0; i < saleAndRecuit.size(); i++) {
            personalScore = saleAndRecuit.get(i);
            dayScore += personalScore.getDayScore();
            weekScore += personalScore.getWeekScore();
            monthScore += personalScore.getMonthScore();
            FYC = FYC.add(personalScore.getFYC());
        }

        Double dayAverage = 0D;
        Double weekAverage = 0D;
        Double monthAverage = 0D;
        // 平均分效
        Double rate = 0D;
        if (!CommonUtil.isNullOrZero(teamSize)){
            dayAverage = BigDecimal.valueOf(dayScore)
                    .divide(BigDecimal.valueOf(teamSize),2, BigDecimal.ROUND_HALF_UP)
                    .doubleValue();
            weekAverage = BigDecimal.valueOf(weekScore)
                    .divide(BigDecimal.valueOf(teamSize),2, BigDecimal.ROUND_HALF_UP)
                    .doubleValue();
            monthAverage = BigDecimal.valueOf(monthScore)
                    .divide(BigDecimal.valueOf(teamSize),2, BigDecimal.ROUND_HALF_UP)
                    .doubleValue();
        }
        if (!CommonUtil.isNullOrZero(monthScore)){
            rate = FYC.divide(BigDecimal.valueOf(monthScore), 2, BigDecimal.ROUND_HALF_UP)
                    .doubleValue();
        }

        Map<String, Object> average = new HashMap<>();
        average.put("dayScore", dayAverage);
        average.put("weekScore", weekAverage);
        average.put("monthScore", monthAverage);
        average.put("rate", rate);

        return average;
    }

    private void mergeScore(List<PersonalSchedule> personalScheduleList, List<PersonalPEPScore> saleAndRecuit) {
        for (PersonalPEPScore socre : saleAndRecuit) {
            for (PersonalSchedule schedule : personalScheduleList) {
                Long curPractitionerId = schedule.getPractitionerId();
                if (curPractitionerId.equals(socre.getPractitionerId())) {
                    Map<String, Long> otherMap = schedule.getOther();

                    Long dayScore = socre.getDayScore() + otherMap.get("dayScore");
                    Long weekScore = socre.getWeekScore() + otherMap.get("weekScore");
                    Long monthScore = socre.getMonthScore() + otherMap.get("monthScore");

                    socre.setDayScore(dayScore);
                    socre.setWeekScore(weekScore);
                    socre.setMonthScore(monthScore);
                }
            }
            Double rate = 0D;
            if (!CommonUtil.isNullOrZero(socre.getMonthScore())){
                // 单人分效
                rate = socre.getFYC().divide(BigDecimal.valueOf(socre.getMonthScore()), 2, BigDecimal.ROUND_HALF_UP)
                        .doubleValue();
            }
            socre.setRate(rate);
        }
    }

    private void computeOtherScore(List<PersonalSchedule> personalScheduleList,  Date today, Date weekOne, Date monthOne) {
        for (PersonalSchedule perSchedule:personalScheduleList) {
            List<ScheduleTrack> scheduleList = perSchedule.getScheduleList();
            Integer trackScore = null;
            long dayOther = 0L;
            long weekOther = 0L;
            long monthOther = 0L;
            // 计算所有其他活动的本日，本周，本月得分
            for (ScheduleTrack s:scheduleList) {
                trackScore = s.getTrackScore();
                dayOther += this.calculateScheduleDisplayCount(s, today, today) * trackScore;
                weekOther += this.calculateScheduleDisplayCount(s, weekOne, today) * trackScore;
                monthOther += this.calculateScheduleDisplayCount(s, monthOne, today) * trackScore;
            }
            Map<String, Long> map = new HashMap<>();
            map.put("dayScore", dayOther);
            map.put("weekScore", weekOther);
            map.put("monthScore", monthOther);

            perSchedule.setOther(map);
        }
    }

    private long calculateScheduleDisplayCount(ScheduleTrack s, Date firstDay, Date lastDay) {

        Date trackTime = s.getTrackTime();
        String trackTimeStr = CommonUtil.dateParseString(trackTime,"yyyy-MM-dd");
        String firstDayStr = CommonUtil.dateParseString(firstDay,"yyyy-MM-dd");
        String lastDayStr = CommonUtil.dateParseString(lastDay,"yyyy-MM-dd");
        if (trackTimeStr.compareTo(firstDayStr) > 0) {
            firstDay = trackTime;
        }

        long count = 0L;
        if (Integer.valueOf(1).equals(s.getTaskRoutineAtweek1())) {
            count += CommonUtil.weekDayCount(firstDay, lastDay, 1);
        }
        if (Integer.valueOf(1).equals(s.getTaskRoutineAtweek2())) {
            count += CommonUtil.weekDayCount(firstDay, lastDay, 2);
        }
        if (Integer.valueOf(1).equals(s.getTaskRoutineAtweek3())) {
            count += CommonUtil.weekDayCount(firstDay, lastDay, 3);
        }
        if (Integer.valueOf(1).equals(s.getTaskRoutineAtweek4())) {
            count += CommonUtil.weekDayCount(firstDay, lastDay, 4);
        }
        if (Integer.valueOf(1).equals(s.getTaskRoutineAtweek5())) {
            count += CommonUtil.weekDayCount(firstDay, lastDay, 5);
        }
        if (Integer.valueOf(1).equals(s.getTaskRoutineAtweek6())) {
            count += CommonUtil.weekDayCount(firstDay, lastDay, 6);
        }
        if (Integer.valueOf(1).equals(s.getTaskRoutineAtweek7())) {
            count += CommonUtil.weekDayCount(firstDay, lastDay, 7);
        }
        // 判断trackTime是否在时间范围内
        if (trackTimeStr.compareTo(firstDayStr)>=0 && trackTimeStr.compareTo(lastDayStr)<=0) {
            String week = CommonUtil.getWeekOfDate(trackTime);
            Integer flag = 0;
            switch (week) {
                case "1":
                    flag = s.getTaskRoutineAtweek1();
                    break;
                case "2":
                    flag = s.getTaskRoutineAtweek2();
                    break;
                case "3":
                    flag = s.getTaskRoutineAtweek3();
                    break;
                case "4":
                    flag = s.getTaskRoutineAtweek4();
                    break;
                case "5":
                    flag = s.getTaskRoutineAtweek5();
                    break;
                case "6":
                    flag = s.getTaskRoutineAtweek6();
                    break;
                case "0":
                    flag = s.getTaskRoutineAtweek7();
                    break;
                default:
                    break;
            }
            // trackTime星期与长期固定星期不重复
            if (!Integer.valueOf(1).equals(flag)) {
                count += 1;
            }
        }
        return count;
    }

}
