/**
 *
 */
package com.sifang.modules.taskdispatch.service;


import com.jfinal.plugin.activerecord.Record;
import com.sifang.modules.flowable.dao.ItemManageDao;
import com.sifang.modules.flowable.entity.ItemManage;
import com.sifang.modules.sunshine.SystemSetting.dao.CrmPlatformEmpDao;
import com.sifang.modules.sunshine.SystemSetting.entity.CrmPlatformEmployee;
import com.sifang.modules.sunshine.SystemSetting.utils.BusinessException;
import com.sifang.modules.sys.common.UserUtils;
import com.sifang.modules.sys.common.entity.User;
import com.sifang.modules.sys.common.service.BaseService;
import com.sifang.modules.sys.common.utils.IdGen;
import com.sifang.modules.sys.dao.UserDao;
import com.sifang.modules.sys.util.CrmUtils;
import com.sifang.modules.sys.util.LayuiPage;
import com.sifang.modules.taskdispatch.constant.ReviewDispatchConst;
import com.sifang.modules.taskdispatch.constant.ReviewMemberConst;
import com.sifang.modules.taskdispatch.dao.CrmPriorReviewSettingMemberDao;
import com.sifang.modules.taskdispatch.dao.CrmReviewDispatchDao;
import com.sifang.modules.taskdispatch.dao.CrmReviewGroupDao;
import com.sifang.modules.taskdispatch.dao.CrmReviewGroupMemberDao;
import com.sifang.modules.taskdispatch.entity.CrmPriorReviewSettingMember;
import com.sifang.modules.taskdispatch.entity.CrmReviewDispatch;
import com.sifang.modules.taskdispatch.entity.CrmReviewGroup;
import com.sifang.modules.taskdispatch.entity.CrmReviewGroupMember;
import com.sifang.modules.taskdispatch.util.BatchItem;
import com.sifang.modules.taskdispatch.util.ReviewGroupUtil;
import com.sifang.modules.taskdispatch.vo.ItemAssignReq;
import org.apache.commons.lang3.StringUtils;
import org.jetbrains.annotations.NotNull;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.util.*;

/**
 * 待办派工Service
 *
 * @author gaols
 */
@Component
public class CrmReviewDispatchService extends BaseService {

    @Autowired
    private CrmReviewDispatchDao crmReviewDispatchDao;
    @Autowired
    CrmReviewGroupMemberDao reviewGroupMemberDao;
    @Autowired
    ItemManageDao itemManageDao;
    @Autowired
    CrmPlatformEmpDao platformEmpDao;
    @Autowired
    UserDao userDao;
    @Autowired
    CrmReviewGroupDao reviewGroupDao;
    @Autowired
    CrmPriorReviewSettingMemberDao priorReviewSettingMemberDao;

    public CrmReviewDispatch get(String id) {
        return crmReviewDispatchDao.get(id);
    }

    public void listData(LayuiPage<Record> page, Map<String, String> params) {
        crmReviewDispatchDao.listData(page, params);
        crmReviewDispatchDao.listDataCount(page, params);
    }

    /**
     * 批量派工
     */
    @Transactional(rollbackFor = Exception.class)
    public void batchAssign(ItemAssignReq req) {
        CrmPlatformEmployee employee = checkMember(req.getMemberId());
        List<String> itemIds = req.getItemIds();
        if (CollectionUtils.isEmpty(itemIds)) {
            throw new BusinessException(ReviewDispatchConst.ERR_CODE_ITEM_REQUIRED, "待办事项不能为空！");
        }
        BatchItem batchItem = new BatchItem(itemIds);
        List<Record> items = batchItem.getItems();
        checkNotAssigned(items);
        String formKey = batchItem.getFormKey();
        CrmReviewGroupMember member = reviewGroupMemberDao.get(req.getMemberId());
        CrmReviewGroup reviewGroup = reviewGroupDao.get(member.getGroupId());
        ensureMemberCanHandleItems(member, reviewGroup, formKey, batchItem.getPartnerId());

        if (req.isAuto()) {
            // ensure member online
            if (!(member.getSigninTime() != null && member.getSignoutTime() == null)) {
                throw new BusinessException(ReviewDispatchConst.ERR_CODE_MEMBER_OFFLINE, "审单员工当前不在线！");
            }
        }

        User assigneeUser = userDao.getById(employee.getUserId());
        Date dispatchTime = new Date();
//        String assignee = CrmUtils.getUserXM(user);
//        int affected = itemManageDao.assignUserId(itemIds, employee.getUserId(), dispatchTime, assignee);
//        if (affected != items.size()) {
//            throw new BusinessException("部分待办事项已经被分配，请刷新页面，重新选择待分配任务。");
//        }

        List<CrmReviewDispatch> dispatches = new ArrayList<>();
        for (Record item : items) {
            CrmReviewDispatch dispatch = createReviewDispatch(item, dispatchTime, employee, req.isAuto());
            dispatches.add(dispatch);
            int affected = itemManageDao.assignUserId(item.getStr("id"), employee.getUserId(), dispatchTime, CrmUtils.getUserXM(assigneeUser), dispatch.getId());
            //当formKey为 91：设计审核、92：档案审核、93：安装验收、94：并网验收时，判断优先审核单据条数，总条数保持在六条内
            if("91".equals(formKey) || "92".equals(formKey) || "93".equals(formKey) || "94".equals(formKey)){
                //判断该员工是否为大代理优先审核员
                List<CrmPriorReviewSettingMember> list = priorReviewSettingMemberDao.findReviewSettingMemberByUserId(employee.getUserId());
                if(list.size()>0){
                    //正常审核单据仅可有一条
                    Long count = itemManageDao.priorityTaskCount(employee.getUserId(),"1");
                    if(count + 1 > 6){
                        throw new BusinessException(ReviewDispatchConst.ERR_CODE_ITEM_COUNT, "该审核员还有过多未审核的单据请选择其他审核员派单！");
                    }
                }
            }
            if (affected < 1) {
                throw new BusinessException(ReviewDispatchConst.ERR_CODE_ITEM_ASSIGN_ERROR, String.format("【%s】状态已经改变，请刷新页面，重新选择待分配任务！", item.getStr("name")));
            }
        }
        crmReviewDispatchDao.save(dispatches);
    }

    private void checkNotAssigned(List<Record> items) {
        for (Record item : items) {
            if (StringUtils.isNotBlank(item.getStr("assign_audit_user_id"))) {
                throw new BusinessException(ReviewDispatchConst.ERR_CODE_ITEM_CONSUMED, String.format("【%s】已经分配，请刷新页面！", item.getStr("name")));
            }
        }
    }

    private void checkSameType(List<Record> items) {
        String type = items.get(0).getStr("form_key");
        for (Record item : items) {
            if (!Objects.equals(item.getStr("form_key"), type)) {
                throw new BusinessException(ReviewDispatchConst.ERR_CODE_ITEM_NOT_SAME_TYPE, "分配的待办事项必须为同一类型！");
            }
        }
    }

    /**
     * 批量转派
     */
    @Transactional(rollbackFor = Exception.class)
    public void batchReAssign(ItemAssignReq req) {
        CrmPlatformEmployee employee = checkMember(req.getMemberId());
        List<String> itemIds = req.getItemIds();
        if (CollectionUtils.isEmpty(itemIds)) {
            throw new BusinessException("待办事项不能为空！");
        }
        BatchItem batchItem = new BatchItem(itemIds);
        List<Record> items = batchItem.getItems();
        Date reDispatchTime = new Date();
        String assignee = CrmUtils.getUserXM(userDao.getById(employee.getUserId()));

        for (Record item : items) {
            if (Objects.equals(item.getStr("assign_audit_user_id"), employee.getUserId())) {
                throw new BusinessException(String.format("【%s】已经在用户名下，无需重复指派！", item.getStr("name")));
            }
        }

        List<CrmReviewDispatch> dispatches = new ArrayList<>();
        for (Record item : items) {
            CrmReviewDispatch dispatch = createReviewDispatch(item, reDispatchTime, employee, false);
            String lastDispatchId = item.getStr("latest_dispatch_id");
            int affected = crmReviewDispatchDao.updateAsReAssigned(reDispatchTime, lastDispatchId);
            if (affected < 1) {
                throw new BusinessException(String.format("【%s】状态已经改变，请刷新页面，重新选择转派任务！", item.getStr("name")));
            }
//            ItemManage itemManage = itemManageDao.get(item.getStr("id"));
//            if("1".equals(itemManage.getIsPriority())){
//                throw new BusinessException(ReviewDispatchConst.ERR_CODE_ITEM_COUNT, "优先审核的单据不可转派！");
//            }
            dispatches.add(dispatch);
            affected = itemManageDao.reAssignUserId(item.getStr("id"), employee.getUserId(), reDispatchTime, assignee, dispatch.getId());
            if (affected < 1) {
                throw new BusinessException(String.format("【%s】状态已经改变，请刷新页面，重新选择转派任务！", item.getStr("name")));
            }
        }
        crmReviewDispatchDao.save(dispatches);
    }

    private void ensureMemberCanHandleItems(CrmReviewGroupMember member, CrmReviewGroup reviewGroup, String itemFormKey, String itemPartnerId) {
        String groupType = ReviewGroupUtil.formKey2GroupType(itemFormKey);
        if (!Objects.equals(groupType, reviewGroup.getType())) {
            throw new BusinessException(ReviewDispatchConst.ERR_CODE_ITEM_MISMATCH, "待办事项和用户所在审核组类型不匹配，请重新分配！");
        }
        if (!Objects.equals(itemPartnerId, member.getPartnerId())) {
            throw new BusinessException(ReviewDispatchConst.ERR_CODE_ITEM_MISMATCH, "待办事项和用户资方不匹配，请重新分配！");
        }
    }

    @NotNull
    private static CrmReviewDispatch createReviewDispatch(Record item, Date reDispatchTime, CrmPlatformEmployee employee, boolean auto) {
        User currentUser = UserUtils.getUser();
        CrmReviewDispatch dispatch = new CrmReviewDispatch();
        dispatch.setId(IdGen.uuid());
        dispatch.setStatus(ReviewDispatchConst.STATUS_ONGOING);
        dispatch.setDispatchType(ReviewDispatchConst.DISPATCH_TYPE_MANUAL);
        if (auto) {
            dispatch.setCreateBy("1");
            dispatch.setCreator("system");
        } else {
            dispatch.setCreateBy(UserUtils.getUser().getId());
            dispatch.setCreator(CrmUtils.getUserXM(currentUser));
        }
        dispatch.setCreateTime(reDispatchTime);
        dispatch.setRedispatchTime(null);
        dispatch.setFinishTime(null);
        dispatch.setEmployeeId(employee.getId());
        dispatch.setAssignUserId(employee.getUserId());
        dispatch.setItemId(item.getStr("id"));
        return dispatch;
    }

    @NotNull
    private CrmPlatformEmployee checkMember(String memberId) {
        CrmReviewGroupMember member = reviewGroupMemberDao.get(memberId);
        if (member == null || !Objects.equals(ReviewMemberConst.STATUS_NORMAL, member.getStatus())) {
            throw new BusinessException(ReviewDispatchConst.ERR_CODE_MEMBER_STATE_ERROR, "审核人不存在，请确认审核人是否在审核组中！");
        }
        CrmPlatformEmployee employee = platformEmpDao.get(member.getEmployeeId());
        if (!Objects.equals(employee.getStatus(), "0")) { // 正常
            throw new BusinessException(ReviewDispatchConst.ERR_CODE_MEMBER_STATE_ERROR, "用户被删除或禁用，无法派工！");
        }
        return employee;
    }

}
