package com.yh.saas.plugin.yiliangyiyun.service.impl;


import com.alibaba.fastjson.JSONObject;
import com.alipay.sofa.runtime.api.annotation.SofaReference;
import com.alipay.sofa.runtime.api.annotation.SofaService;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.mapper.Wrapper;
import com.baomidou.mybatisplus.plugins.Page;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import com.baomidou.mybatisplus.toolkit.StringUtils;
import com.google.common.collect.Lists;
import com.winsea.svc.base.base.entity.CommonStaffRole;
import com.winsea.svc.base.base.entity.CommonStaffVessel;
import com.winsea.svc.base.base.service.ICommonStaffRoleService;
import com.winsea.svc.base.base.service.ICommonStaffVesselService;
import com.winsea.svc.base.base.util.MessagePusherUtils;
import com.winsea.svc.base.security.util.AuthSecurityUtils;
import com.winsea.svc.notice.command.NoticeCommand.NoticeBusinessTypeNumber;
import com.winsea.svc.notice.entity.NoticeBusinessConstantInfo;
import com.winsea.svc.notice.entity.NoticeTaskInfo;
import com.winsea.svc.notice.entity.NoticeTaskInfo.NoticeTaskPushStatus;
import com.winsea.svc.notice.entity.NoticeTaskInfo.NoticeTaskStatus;
import com.winsea.svc.notice.entity.base.BaseNotice.AcceptStatus;
import com.winsea.svc.notice.exception.NoticeErrorCodeEnums;
import com.winsea.svc.notice.exception.NoticeException;
import com.winsea.svc.notice.mapper.NoticeTaskMapper;
import com.winsea.svc.notice.service.INoticeBusinessConstantService;
import com.winsea.svc.notice.service.INoticeBusinessResourceService;
import com.winsea.svc.notice.service.INoticeTimePushService;
import com.yh.saas.common.support.util.BeanUtils;
import com.yh.saas.common.support.util.IdGenerator;
import com.yh.saas.common.support.util.query.QueryUtils;

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

import com.yh.saas.plugin.yiliangyiyun.mapper.NewNoticeTaskMapper;
import com.yh.saas.plugin.yiliangyiyun.service.INewNoticeTaskService;
import com.yh.saas.plugin.yiliangyiyun.service.INewNoticeUtilService;
import org.apache.commons.collections.CollectionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;

@SofaService
public class NewNoticeTaskServiceImpl extends ServiceImpl<NoticeTaskMapper, NoticeTaskInfo> implements INewNoticeTaskService {
    private static final Logger log = LoggerFactory.getLogger(com.winsea.svc.notice.service.impl.NoticeTaskServiceImpl.class);
    @Autowired
    private INoticeBusinessResourceService businessResourceService;
    @Autowired
    private INoticeBusinessConstantService businessConstantService;
    @SofaReference
    private ICommonStaffVesselService staffVesselService;
    @SofaReference
    private ICommonStaffRoleService staffRoleService;
    @Autowired
    private INoticeTimePushService notificationTimePushService;
    @Autowired
    private NewNoticeTaskMapper newNoticeTaskMapper;
    @Autowired
    private INewNoticeUtilService noticeUtilService;
    private Set<String> businessCodes;
    @Value("${taskmsg.isPushed:true}")
    private boolean isTaskmsgPushed;

    public NewNoticeTaskServiceImpl() {
    }

    public Page<NoticeTaskInfo> findPageNoticeTasks(NoticeTaskInfo noticeTask) {
        if (null == noticeTask.getPageSize()) {
            noticeTask.setPageSize(10);
        }

        if (null == noticeTask.getCurrentPage() || 0 == noticeTask.getCurrentPage()) {
            noticeTask.setCurrentPage(1);
        }

        if (null == noticeTask.getNoticeTaskStatus()) {
            noticeTask.setNoticeTaskStatus(NoticeTaskStatus.TO_BE_PROCESSED);
        }

        //2022-02-22 程长江 start

        String staffId = AuthSecurityUtils.getCurrentUserId();
        List<CommonStaffVessel> staffVessels = this.staffVesselService.findStaffVessel(AuthSecurityUtils.getCurrentUserId());
        Map<String, List<CommonStaffVessel>> map = (Map)staffVessels.stream().collect(Collectors.groupingBy(CommonStaffVessel::getRoleId));
        Set<String> roleIds = map.keySet();
        Iterator var9 = roleIds.iterator();
        String roleIdParam = "'";
        while(var9.hasNext()) {
           String roleId = (String)var9.next();
           roleIdParam += roleId +"',";
        }
        roleIdParam = roleIdParam.substring(0,roleIdParam.length() -1 );
        staffId = "'" + staffId + "'";
        Map<String, Object> pageView = new HashMap<>();
        if(roleIdParam == null || roleIdParam.equals("")){
            roleIdParam = "''";
        }
        pageView.put("roleId", roleIdParam);
        pageView.put("staffId", staffId);
        List<NoticeTaskInfo> list = newNoticeTaskMapper.getTaskList(pageView);
        Page<NoticeTaskInfo> noticeTaskInfoPage = new Page<>();
        noticeTaskInfoPage.setRecords(list);
        noticeTaskInfoPage.setTotal(list.size());
        //2022-02-22 程长江 end

//        Wrapper<NoticeTaskInfo> noticeTaskWrapper = this.getCurrentUserNoticeTaskWrapper(noticeTask);
//        noticeTaskWrapper.orderDesc(Sets.newHashSet(new String[]{"create_date"}));
//        noticeTaskWrapper.groupBy("business_code");
//        noticeTaskWrapper.groupBy("DATE_FORMAT(create_date,'%Y-%m-%d')");
//        noticeTaskWrapper.and("group by DATE_FORMAT(create_date,'%Y-%m-%d')");
//        Page<NoticeTaskInfo> noticeTaskInfoPage = this.selectPage(noticeTask.getQueryPage(), noticeTaskWrapper);
//        List<NoticeTaskInfo> taskInfos = noticeTaskInfoPage.getRecords();
//        List<NoticeTaskInfo> newTaskInfos = new ArrayList();
//        this.filterResource(taskInfos, newTaskInfos);

//        noticeTaskInfoPage.setRecords(newTaskInfos);
//        Page<NoticeTaskInfo> noticeTaskInfoPage = this.selectPage(noticeTask.getQueryPage(), noticeTaskWrapper);
//        noticeTaskInfoPage.setRecords(list);
//        if (noticeTask.getPageSize() > taskInfos.size()) {
//            int sum = (int)noticeTaskInfoPage.getTotal();
//            int pageSize = noticeTask.getPageSize();
//
//            for(int i = 1; i < (new BigDecimal(sum)).divide(new BigDecimal(pageSize)).intValue() + 1; ++i) {
//                noticeTask.setCurrentPage(noticeTask.getCurrentPage() + 1);
//                Page<NoticeTaskInfo> taskInfoPage = this.selectPage(noticeTask.getQueryPage(), noticeTaskWrapper);
//                if (!CollectionUtils.isEmpty(taskInfoPage.getRecords())) {
//                    Iterator var10 = taskInfoPage.getRecords().iterator();
//
//                    while(var10.hasNext()) {
//                        NoticeTaskInfo noticeTaskInfo = (NoticeTaskInfo)var10.next();
//                        List<NoticeBusinessResourceInfo> noticeBusinessResourceInfos = this.businessResourceService.findNoticeBusinessResourceInfos(noticeTaskInfo.getBusinessCode());
//                        List<String> noticeResource = (List)noticeBusinessResourceInfos.stream().map(NoticeBusinessResourceInfo::getResourceId).collect(Collectors.toList());
//                        List<String> resourceIds = AuthSecurityUtils.getUserResources(AuthSecurityUtils.getCurrentUserId());
//                        if (resourceIds.containsAll(noticeResource)) {
//                            noticeTaskInfo.setMessageTitle(this.businessConstantService.findBusinessCodeInfo(noticeTaskInfo.getBusinessCode()).getReceiptName());
//                            taskInfos.add(noticeTaskInfo);
//                            if (taskInfos.size() >= pageSize) {
//                                return noticeTaskInfoPage;
//                            }
//                        }
//                    }
//                }
//            }
//        }

        noticeTaskInfoPage.getRecords().forEach((noticeTaskInfox) -> {
            String messageTitle = null;
            NoticeBusinessConstantInfo businessConstantInfo = this.businessConstantService.findBusinessCodeInfo(noticeTaskInfox.getBusinessCode());
            String messageTitleEn;
            if (null == businessConstantInfo) {
                messageTitle = "未知数据";
                messageTitleEn = "Unknown data";
            } else {
                messageTitle = businessConstantInfo.getReceiptName();
                messageTitleEn = businessConstantInfo.getReceiptNameEn();
            }

            noticeTaskInfox.setMessageTitle(messageTitle);
            noticeTaskInfox.setMessageTitleEn(messageTitleEn);
        });
        return noticeTaskInfoPage;
    }

    public void createNoticeTask(List<String> acceptIds, String vesselId, NoticeTaskInfo noticeTask) {
        if (null == noticeTask.getAcceptType()) {
            throw new NoticeException(NoticeErrorCodeEnums.NOTICE_ACCEPT_TYPE_NULL_ERROR);
        } else if (StringUtils.isEmpty(noticeTask.getCompId())) {
            throw new NoticeException(NoticeErrorCodeEnums.NOTICE_COMP_ID_NULL_ERROR);
        } else if (CollectionUtils.isEmpty(acceptIds) && AcceptStatus.All != noticeTask.getAcceptType()) {
            throw new NoticeException(NoticeErrorCodeEnums.NOTICE_ACCEPT_ID_NULL_ERROR);
        } else {
            if (null == noticeTask.getNoticeTaskPushStatus()) {
                noticeTask.setNoticeTaskPushStatus(NoticeTaskPushStatus.ALL);
            }

            List<NoticeTaskInfo> noticeTaskInfos = new ArrayList();
            acceptIds.forEach((acceptId) -> {
                NoticeTaskInfo taskInfo = (NoticeTaskInfo)BeanUtils.map(noticeTask, NoticeTaskInfo.class);
                taskInfo.setId(IdGenerator.generateUUID());
                taskInfo.setAcceptId(acceptId);
                if (null == noticeTask.getNoticeTaskStatus()) {
                    taskInfo.setNoticeTaskStatus(NoticeTaskStatus.TO_BE_PROCESSED);
                }

                taskInfo.setVesselId(vesselId);
                taskInfo.setNoticeTaskPushStatus(NoticeTaskPushStatus.ALL);
                noticeTaskInfos.add(taskInfo);
                if ("1a4a82511d68454dada09f3fb2192e7d".equals(noticeTask.getCompId())) {
                    this.push(taskInfo);
                }

            });
            this.insertBatch(noticeTaskInfos);
        }
    }

    public Integer findNumber() {
        NoticeTaskInfo noticeTaskInfo = new NoticeTaskInfo();
        noticeTaskInfo.setNoticeTaskStatus(NoticeTaskStatus.TO_BE_PROCESSED);
        Wrapper<NoticeTaskInfo> noticeTaskWrapper = this.getCurrentUserNoticeTaskWrapper(noticeTaskInfo);
        noticeTaskWrapper.groupBy("business_id");
        List<NoticeTaskInfo> noticeTaskInfos = this.selectList(noticeTaskWrapper);
        List<NoticeTaskInfo> noticeTaskInfoList = new ArrayList();
        this.filterResource(noticeTaskInfos, noticeTaskInfoList);
        return noticeTaskInfoList.size();
    }

    public List<NoticeTaskInfo> findOverdueTaskByCurrentUser() {
        Wrapper<NoticeTaskInfo> noticeTaskWrapper = this.getCurrentUserNoticeTaskWrapper((NoticeTaskInfo)null);
        noticeTaskWrapper.isNotNull("overdue_date").lt("overdue_date", new Date());
        return this.selectList(noticeTaskWrapper);
    }

    public List<NoticeTaskInfo> findOverdueTask() {
        Wrapper<NoticeTaskInfo> noticeTaskWrapper = new EntityWrapper();
        noticeTaskWrapper.lt("overdue_date", new Date());
        noticeTaskWrapper.eq("overdue_date_flag", 0);
        return this.selectList(noticeTaskWrapper);
    }

    public List<NoticeBusinessTypeNumber> findBusinessTypeCount() {
        NoticeTaskInfo noticeTaskInfo = new NoticeTaskInfo();
        noticeTaskInfo.setNoticeTaskStatus(NoticeTaskStatus.TO_BE_PROCESSED);
        Wrapper<NoticeTaskInfo> noticeTaskWrapper = this.getCurrentUserNoticeTaskWrapper(noticeTaskInfo);
        noticeTaskWrapper.groupBy("business_id");
        List<NoticeTaskInfo> noticeTaskInfos = this.selectList(noticeTaskWrapper);
        List<NoticeTaskInfo> noticeTaskInfoList = new ArrayList();
        this.filterResource(noticeTaskInfos, noticeTaskInfoList);
        Map<String, Long> businessTypeNoticeTask = (Map)noticeTaskInfoList.stream().collect(Collectors.groupingBy(NoticeTaskInfo::getBusinessType, Collectors.counting()));
        List<NoticeBusinessTypeNumber> noticeBusinessTypeNumbers = new ArrayList();
        businessTypeNoticeTask.keySet();
        Iterator var7 = businessTypeNoticeTask.keySet().iterator();

        while(var7.hasNext()) {
            String businessType = (String)var7.next();
            if ((Long)businessTypeNoticeTask.get(businessType) > 0L) {
                this.businessConstantService.filterBusinessTypeCount(noticeBusinessTypeNumbers, businessType, ((Long)businessTypeNoticeTask.get(businessType)).intValue());
            }
        }

        return noticeBusinessTypeNumbers;
    }

    public void handleNoticeTaskInfo(String staffId, String businessCode, String businessKey, String vesselId) {
        List<String> roleIds = null;
        if (StringUtils.isEmpty(vesselId)) {
            List<CommonStaffRole> roles = this.staffRoleService.findStaffRoles(Lists.newArrayList(new String[]{staffId}));
            roleIds = (List)roles.stream().map(CommonStaffRole::getRoleId).collect(Collectors.toList());
        } else {
            roleIds = this.staffVesselService.getRoleIdsWithStaffAndVessel(staffId, vesselId);
        }

        Wrapper<NoticeTaskInfo> wrapper = new EntityWrapper();
        wrapper.eq("business_code", businessCode);
        wrapper.eq("business_id", businessKey);
        Wrapper<NoticeTaskInfo> currentTaskWrapper = new EntityWrapper();
        currentTaskWrapper.orNew().eq("accept_type", AcceptStatus.All);
        currentTaskWrapper.orNew().eq("accept_type", AcceptStatus.STAFF).eq("accept_id", staffId).and(QueryUtils.getQueryString(this.noticeUtilService.getFilterVesselWrapper(vesselId), NoticeTaskInfo.class), new Object[0]);
        currentTaskWrapper.orNew().in("accept_id", roleIds).eq("accept_type", AcceptStatus.ROLE).and(QueryUtils.getQueryString(this.noticeUtilService.getFilterVesselWrapper(vesselId), NoticeTaskInfo.class), new Object[0]);
        wrapper.andNew(QueryUtils.getQueryString(currentTaskWrapper, NoticeTaskInfo.class), new Object[0]);
        NoticeTaskInfo noticeTaskInfo = new NoticeTaskInfo();
        noticeTaskInfo.setNoticeTaskStatus(NoticeTaskStatus.PROCESSED);
        this.update(noticeTaskInfo, wrapper);
    }

    public List<NoticeTaskInfo> findNoticeTaskByBusiness(String businessCode, String businessId, NoticeTaskStatus noticeTaskStatus) {
        return this.selectList((new EntityWrapper()).eq("business_code", businessCode).eq("business_id", businessId).eq("notice_task_status", NoticeTaskStatus.TO_BE_PROCESSED));
    }

    public void removeReturnTask(String businessCode, String businessKey) {
        this.delete((new EntityWrapper()).eq("business_code", businessCode).eq("business_id", businessKey).eq("notice_task_status", NoticeTaskStatus.RETURN));
    }

    private void push(NoticeTaskInfo noticeTaskInfo) {
        if (NoticeTaskPushStatus.NONE != noticeTaskInfo.getNoticeTaskPushStatus()) {
            if ((NoticeTaskPushStatus.WEB == noticeTaskInfo.getNoticeTaskPushStatus() || NoticeTaskPushStatus.ALL == noticeTaskInfo.getNoticeTaskPushStatus()) && this.isTaskmsgPushed) {
                List<String> staffIds = new ArrayList();
                if (AcceptStatus.STAFF == noticeTaskInfo.getAcceptType()) {
                    staffIds = Lists.newArrayList(new String[]{noticeTaskInfo.getAcceptId()});
                }

                if (AcceptStatus.ROLE == noticeTaskInfo.getAcceptType()) {
                    List<CommonStaffRole> staffRoles = this.staffRoleService.findStaff(Lists.newArrayList(new String[]{noticeTaskInfo.getAcceptId()}));
                    staffIds = (List)staffRoles.stream().map(CommonStaffRole::getStaffId).collect(Collectors.toList());
                }

                this.webPush((List)staffIds);
            }

        }
    }

    private void webPush(List<String> staffIds) {
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("msg", "你有1个新的任务");
        Iterator var3 = staffIds.iterator();

        while(var3.hasNext()) {
            String staffId = (String)var3.next();
            MessagePusherUtils.sendPrivateMessage(staffId, JSONObject.toJSONString(jsonObject));
        }

    }

    private void filterResource(List<NoticeTaskInfo> taskInfos, List<NoticeTaskInfo> newTaskInfos) {
        this.businessCodes = new HashSet();
        List<String> resourceIds = AuthSecurityUtils.getUserResources(AuthSecurityUtils.getCurrentUserId());
        Iterator var4 = taskInfos.iterator();

        while(true) {
            NoticeTaskInfo taskInfo;
            do {
                if (!var4.hasNext()) {
                    return;
                }

                taskInfo = (NoticeTaskInfo)var4.next();
            } while(!this.businessCodes.contains(taskInfo.getBusinessCode()) && !this.businessResourceService.determineBusinessCodeResource(resourceIds, taskInfo.getBusinessCode()));

            this.businessCodes.add(taskInfo.getBusinessCode());
            newTaskInfos.add(taskInfo);
        }
    }

    private Wrapper<NoticeTaskInfo> getCurrentUserNoticeTaskWrapper(NoticeTaskInfo noticeTask) {
        boolean returnFlag = false;
        if (null != noticeTask && NoticeTaskStatus.TO_BE_PROCESSED.equals(noticeTask.getNoticeTaskStatus())) {
            returnFlag = true;
            noticeTask.setNoticeTaskStatus((NoticeTaskStatus)null);
        }

        Object wrapper;
        if (null == noticeTask) {
            wrapper = new EntityWrapper();
        } else {
            wrapper = QueryUtils.convertExampleToWrapper(noticeTask);
        }

        if (returnFlag) {
            ((Wrapper)wrapper).in("notice_task_status", Lists.newArrayList(new NoticeTaskStatus[]{NoticeTaskStatus.TO_BE_PROCESSED, NoticeTaskStatus.RETURN, NoticeTaskStatus.TO_BE_REPAIRED}));
        }

        return (Wrapper<NoticeTaskInfo>) this.noticeUtilService.getCurrentUserNoticeTaskWrapper((Wrapper)wrapper, NoticeTaskInfo.class);
    }
}