package com.njcn.supervision.controller;

import cn.hutool.core.text.StrPool;
import cn.hutool.extra.spring.SpringUtil;
import com.njcn.bpm.pojo.dto.BpmInstanceInfo;
import com.njcn.bpm.pojo.vo.TodoVO;
import com.njcn.bpm.service.IBpmReasonService;
import com.njcn.common.pojo.annotation.OperateInfo;
import com.njcn.common.pojo.enums.common.LogEnum;
import com.njcn.common.pojo.enums.response.CommonResponseEnum;
import com.njcn.common.pojo.exception.BusinessException;
import com.njcn.common.pojo.response.HttpResult;
import com.njcn.common.utils.HttpResultUtil;
import com.njcn.supervision.enums.SupervisionKeyEnum;
import com.njcn.supervision.enums.SupervisionResponseEnum;
import com.njcn.supervision.service.leaflet.IWarningLeafletService;
import com.njcn.supervision.service.survey.ISurveyTestService;
import com.njcn.web.controller.BaseController;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import springfox.documentation.annotations.ApiIgnore;
import com.njcn.bpm.service.IBpmService;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

/**
 * @author hongawen
 */
@Slf4j
@RestController
@RequestMapping("/supervision")
@Api(tags = "所有业务流程公共方法管理")
@AllArgsConstructor
@ApiIgnore
public class BusinessCommonController extends BaseController {

    @Resource
    private IWarningLeafletService warningLeafletService;

    @Resource
    private ISurveyTestService surveyTestService;


    @ApiIgnore
    @GetMapping("/updateProcessStatus")
    @OperateInfo(info = LogEnum.BUSINESS_COMMON)
    @ApiOperation("更新流程状态")
    public HttpResult<Object> updateProcessStatus(String processKey, String businessId, String reason, Integer status) {
        String methodDescribe = getMethodDescribe("updateProcessStatus");
        getBpmServiceByBusinessStatusKey(processKey, businessId, reason, status);
        return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS, null, methodDescribe);
    }

    @ApiIgnore
    @GetMapping("/getInstanceInfo")
    @OperateInfo(info = LogEnum.BUSINESS_COMMON)
    @ApiOperation("获取业务数据")
    public HttpResult<BpmInstanceInfo> getInstanceInfo(String processKey, String businessId) {
        String methodDescribe = getMethodDescribe("getInstanceInfo");
        BpmInstanceInfo instanceInfo = getBpmServiceByBusinessKey(processKey, businessId);
        return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS, instanceInfo, methodDescribe);
    }

    @ApiIgnore
    @GetMapping("/getAllRejectInstanceId")
    @OperateInfo(info = LogEnum.BUSINESS_COMMON)
    @ApiOperation("获取当前用户所有不通过的流程实例ID")
    public HttpResult<Set<String>> getAllRejectInstanceId() {
        String methodDescribe = getMethodDescribe("getAllRejectInstanceId");
        Set<String> instanceIdList = new HashSet<>();
        List<String> fullServicePathList = SupervisionKeyEnum.getAllFullServicePath();
        for (String fullServicePath : fullServicePathList) {
            IBpmService executor;
            IBpmReasonService executorReason;
            try {
                if(fullServicePath.contains("SupervisionTempLineRunTestServiceImpl")){
                    executorReason = (IBpmReasonService) SpringUtil.getBean(Class.forName(fullServicePath));
                    instanceIdList.addAll(executorReason.getAllRejectInstanceIds());
                }else{
                    executor = (IBpmService) SpringUtil.getBean(Class.forName(fullServicePath));
                    instanceIdList.addAll(executor.getAllRejectInstanceIds());
                }
            } catch (ClassNotFoundException e) {
                throw new RuntimeException(e);
            }
        }
        return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS, instanceIdList, methodDescribe);
    }

    /**
     * 目前不涉及流程的待办工作有
     * 1.预告警单
     * 2.终端周期到期待检测
     */
    @ApiIgnore
    @GetMapping("/getTodoBusiness")
    @OperateInfo(info = LogEnum.BUSINESS_COMMON)
    @ApiOperation("获取当前用户待办的业务")
    public HttpResult<List<TodoVO>> getTodoBusiness() {
        String methodDescribe = getMethodDescribe("getTodoBusiness");
        List<TodoVO> todoVOList = new ArrayList<>();
        //可能需要判断当前用户是否需要处理这些待办，比如专职下发的预告警单，应该由负责单位去处理
        todoVOList.addAll(warningLeafletService.getTodoBusiness());
        todoVOList.addAll(surveyTestService.getTodoBusiness());
        return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS, todoVOList, methodDescribe);
    }


    /**
     * 根据业务流key获取实现类对象
     *
     * @param processKey 业务流key
     */
    private void getBpmServiceByBusinessStatusKey(String processKey, String businessId, String reason, Integer status) {
        String fullServicePath = SupervisionKeyEnum.getFullServicePathByKey(processKey);
        try {
            assert fullServicePath != null;
            if ("SupervisionTempLineRunTestServiceImpl".equals(fullServicePath.substring(fullServicePath.lastIndexOf(StrPool.DOT) + 1))) {
                IBpmReasonService iBpmService = (IBpmReasonService) SpringUtil.getBean(Class.forName(fullServicePath));
                iBpmService.updateProcessStatus(businessId, reason, status);
            } else {
                IBpmService executor = (IBpmService) SpringUtil.getBean(Class.forName(fullServicePath));
                executor.updateProcessStatus(businessId, status);
            }
        } catch (ClassNotFoundException e) {
            throw new BusinessException(SupervisionResponseEnum.SUPERVISION_SERVICE_NOT_FOUND);
        }

    }


    /**
     * 根据业务流key获取实现类对象
     *
     * @param processKey 业务流key
     */
    private BpmInstanceInfo getBpmServiceByBusinessKey(String processKey, String businessId) {
        String fullServicePath = SupervisionKeyEnum.getFullServicePathByKey(processKey);
        BpmInstanceInfo instanceInfo;
        try {
            assert fullServicePath != null;
            if ("SupervisionTempLineRunTestServiceImpl".equals(fullServicePath.substring(fullServicePath.lastIndexOf(StrPool.DOT) + 1))) {
                IBpmReasonService iBpmService = (IBpmReasonService) SpringUtil.getBean(Class.forName(fullServicePath));
                instanceInfo = iBpmService.getInstanceInfo(businessId);
            } else {
                IBpmService executor = (IBpmService) SpringUtil.getBean(Class.forName(fullServicePath));
                instanceInfo = executor.getInstanceInfo(businessId);
            }
        } catch (ClassNotFoundException e) {
            throw new BusinessException(SupervisionResponseEnum.SUPERVISION_SERVICE_NOT_FOUND);
        }
        return instanceInfo;
    }

}
