package com.yeejoin.amos.supervision.business.service.impl;

import com.yeejoin.amos.boot.biz.common.bo.ReginParams;
import com.yeejoin.amos.boot.biz.common.service.IWorkflowExcuteService;
import com.yeejoin.amos.boot.biz.common.workflow.feign.WorkflowFeignService;
import com.yeejoin.amos.feign.privilege.model.AgencyUserModel;
import com.yeejoin.amos.supervision.business.dao.repository.IPlanAuditDao;
import com.yeejoin.amos.supervision.business.dao.repository.IPlanAuditLogDao;
import com.yeejoin.amos.supervision.business.dao.repository.IPlanDao;
import com.yeejoin.amos.supervision.business.feign.JCSFeignClient;
import com.yeejoin.amos.supervision.business.service.intfc.IPlanAuditService;
import com.yeejoin.amos.supervision.common.enums.CheckTypeSuEnum;
import com.yeejoin.amos.supervision.common.enums.DangerCheckTypeLevelEnum;
import com.yeejoin.amos.supervision.common.enums.PlanStatusEnum;
import com.yeejoin.amos.supervision.common.enums.WorkFlowBranchEnum;
import com.yeejoin.amos.supervision.dao.entity.Plan;
import com.yeejoin.amos.supervision.dao.entity.PlanAudit;
import com.yeejoin.amos.supervision.dao.entity.PlanAuditLog;
import com.yeejoin.amos.supervision.exception.YeeException;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.typroject.tyboot.core.foundation.utils.ValidationUtil;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

@Service("planAuditService")
public class PlanAuditServiceImpl implements IPlanAuditService {

    @Autowired
    private IWorkflowExcuteService workflowExcuteService;

    @Autowired
    private IPlanAuditDao planAuditDao;

    @Autowired
    private IPlanAuditLogDao planAuditLogDao;

    @Autowired
    private IPlanDao planDao;

    @Autowired
    WorkflowFeignService workflowFeignService;

    @Autowired
    private PlanServiceImpl planService;

    @Autowired
    JCSFeignClient jcsFeignClient;

    @Override
    @Transactional
    public Boolean auditWorkFlow(PlanAuditLog planAuditLog, Integer status, String condition, ReginParams reginParams) throws Exception {
        PlanAudit planAudit = planAuditDao.findByPlanId(planAuditLog.getPlanId());
        if (ObjectUtils.isNotEmpty(planAudit)) {
            String instanceId = planAudit.getProcessInstanceId();
            Map<String, Object> taskAuthMap = workflowExcuteService.checkTaskAuthMap(instanceId, reginParams);
            if (taskAuthMap != null && !taskAuthMap.isEmpty()) {
                // 获取当前计划
                Plan plan = planDao.getOne(planAuditLog.getPlanId());
                String taskId = taskAuthMap.get("taskId") == null ? null : taskAuthMap.get("taskId").toString();
                String name = taskAuthMap.get("name") == null ? null : taskAuthMap.get("name").toString();
                String roleName = reginParams.getRole().getRoleName();
                // 获取审核最后一步所需条件
                String conditionValue = getConditionValue(plan, condition);
                workflowExcuteService.CompleteTask(instanceId, conditionValue, reginParams);
                ReginParams.PersonIdentity personIdentity = reginParams.getPersonIdentity();
                String userId = reginParams.getUserModel().getUserId();
                // 更新计划状态,指定执行人
                updatePlanStatus(condition,plan,instanceId, conditionValue);
                // 更新流水表
                planAuditLog.setPlanId(planAudit.getPlanId());
                planAuditLog.setPlanAuditId(planAudit.getId());
                planAuditLog.setExcuteUserId(personIdentity.getPersonSeq());
                planAuditLog.setExcuteUserName(personIdentity.getPersonName());
                planAuditLog.setFlowTaskId(taskId);
                planAuditLog.setFlowTaskName(name);
                planAuditLog.setFlowJson(condition);
                planAuditLog.setRoleName(roleName);
                planAuditLogDao.save(planAuditLog);
                planService.getUserIdsByWorkflow(plan, instanceId, status, planAuditLog.getExcuteState());
                return Boolean.TRUE;
            }
        }
        return Boolean.FALSE;
    }

    /**
     * 获取最后一步审核通过下一步条件
     * @param plan 计划
     * @param condition 前端传的是否通过
     * @return 下一步条件
     */
    private String getConditionValue(Plan plan, String condition) throws Exception {
        String fail = "1";
        String nextCondition = "outer";
        // 前端传递为0表示通过，通过才区分下一步
        if (!fail.equals(condition) && DangerCheckTypeLevelEnum.EXTERNAL.getCode().equals(plan.getCheckLevel())) {
            String workFlowBranch = getWorkFlowBranch(plan);
            if (workFlowBranch.equals(WorkFlowBranchEnum.DAILY.getWorkFlowBranch())) {
                if (PlanStatusEnum.EXAMINE_THREE.getValue() == plan.getStatus()) {
                    return nextCondition;
                }
            } else {
                if (PlanStatusEnum.EXAMINE_ONE.getValue() == plan.getStatus()) {
                    return nextCondition;
                }
            }
            return fail;
        }
        return condition;
    }

    /**
     * 更新计划id
     * @param condition 同意0 不同意1
     * @param plan 当前计划对象
     */
    private void updatePlanStatus (String condition, Plan plan, String instanceId, String conditionValue) throws Exception {
        String fail = "1";
        String nextCondition = "outer";
        if (fail.equals(condition)) {
            planDao.updatePlanStatus(PlanStatusEnum.DRAFT.getValue(), plan.getId());
        } else {
            // 获取检查组长
            AgencyUserModel userModel = jcsFeignClient.getAmosIdByUserId(plan.getLeadPeopleIds()).getResult();
            if (ValidationUtil.isEmpty(userModel)) {
                throw new YeeException("业务信息错误");
            }
            // 工作流中使用平台用户名称，因此这里取userName
            String checkLeaderId = userModel.getUserName();
            String workFlowBranch = getWorkFlowBranch(plan);
            PlanStatusEnum statusEnum = PlanStatusEnum.getEnum(plan.getStatus());
            if (workFlowBranch.equals(WorkFlowBranchEnum.DAILY.getWorkFlowBranch())) {
                if (PlanStatusEnum.EXAMINE_THREE.getValue() == plan.getStatus()) {
                    workflowExcuteService.setTaskAssign(instanceId, checkLeaderId);
                }
                int status = statusEnum != null ? statusEnum.getNextStatus() : PlanStatusEnum.DRAFT.getValue();
                if (nextCondition.equals(conditionValue) && PlanStatusEnum.EXAMINE_THREE.getValue() == status) {
                    status = PlanStatusEnum.IN_EXECUTION.getValue();
                }
                planDao.updatePlanStatus(status, plan.getId());
            } else {
                int status = PlanStatusEnum.EXAMINE_FORMULATE.getValue();
                if (PlanStatusEnum.EXAMINE_ONE.getValue() == plan.getStatus()) {
                    workflowExcuteService.setTaskAssign(instanceId, checkLeaderId);
                } else {
                    status =  statusEnum != null ? statusEnum.getNextStatus() : PlanStatusEnum.DRAFT.getValue();
                }

                if (nextCondition.equals(conditionValue)) {
                    status = PlanStatusEnum.IN_EXECUTION.getValue();
                }
                planDao.updatePlanStatus(status, plan.getId());
            }
        }
    }

    /**
     * 获取当前流程分支
     * @param plan 计划对象
     * @return 流程分支
     */
    private String getWorkFlowBranch(Plan plan) throws Exception {
        //检查级别
        DangerCheckTypeLevelEnum dangerCheckTypeLevelEnum = DangerCheckTypeLevelEnum.getEumByCode(plan.getCheckLevel());
        //检查类型
        CheckTypeSuEnum checkTypeSuEnum = CheckTypeSuEnum.getEumByCode(plan.getCheckTypeId());
        return PlanServiceImpl.workFlowExcuteBranch(dangerCheckTypeLevelEnum.getCondition(), checkTypeSuEnum.getCondition());
    }

    @Override
    public List<PlanAuditLog> listByPlanId(Long planId) {
        Sort.Order idOrder = new Sort.Order(Sort.Direction.ASC, "createDate");
        List<Sort.Order> orders = new ArrayList<Sort.Order>();
        orders.add(idOrder);
        Sort sort = Sort.by(orders);
        return planAuditLogDao.findAllByPlanId(planId, sort);
    }

    @Override
    public Map<String, Object> checkTaskAuth(Long planId, ReginParams reginParams) {
        PlanAudit planAudit = planAuditDao.findByPlanId(planId);
        if (ObjectUtils.isNotEmpty(planAudit)) {
            String instanceId = planAudit.getProcessInstanceId();
            return workflowExcuteService.checkTaskAuthMap(instanceId, reginParams);
        } else  {
            throw new YeeException("该计划暂无流程实例!");
        }
    }

//    @Override
//    @Transactional
//    public Boolean auditWorkFlow(PlanAuditLog planAuditLog, String condition, ReginParams reginParams) {
//        PlanAudit planAudit = planAuditDao.findByPlanId(planAuditLog.getPlanId());
//        Map<String, Object> taskAuthMap = workflowExcuteService.checkTaskAuthMap(instanceId);
//        if (taskAuthMap != null && !taskAuthMap.isEmpty()) {
//            String taskId = taskAuthMap.get("taskId").toString();
//            String name = taskAuthMap.get("name").toString();
//            if (StringUtils.isNotBlank(taskId)) {
//                String roleName = reginParams.getRole().getRoleName();
////                JSONObject taskGroupName = workflowFeignService.getTaskGroupName(taskId);
////                JSONArray taskGroupNameDetail = taskGroupName.getJSONArray("data");
//////                JSONObject taskGroupNameDetail = JSONObject.parseObject(JSONObject.toJSONString(data.get(data.size() - 2)));
////                if (!ObjectUtils.isEmpty(taskGroupNameDetail)) {
////                    String defaultExecutionRoleProcess = taskGroupNameDetail.getJSONObject(0).getString("groupId");
////                }
//                boolean b = workflowExcuteService.CompleteTask(instanceId, condition);
//                if (b) {
//                    ReginParams.PersonIdentity personIdentity = reginParams.getPersonIdentity();
//                    workflowExcuteService.setTaskAssign(instanceId, personIdentity.getPersonSeq());
//
//                    if (ObjectUtils.isNotEmpty(planAudit)) {
//                        planAuditLog.setPlanId(planAudit.getPlanId());
//                        planAuditLog.setPlanAuditId(planAudit.getId());
//                        planAuditLog.setExcuteUserId(personIdentity.getPersonSeq());
//                        planAuditLog.setExcuteUserName(personIdentity.getPersonName());
//                        planAuditLog.setFlowTaskId(taskId);
//                        planAuditLog.setFlowTaskName(name);
//                        planAuditLog.setFlowJson(condition);
//                        planAuditLog.setRoleName(roleName);
//                        planAuditLogDao.save(planAuditLog);
//                    }
//                }
//                return b;
//            }
//        }
//        return Boolean.FALSE;
//    }
}
