package com.yeejoin.amos.boot.module.jyjc.biz.service.impl;


import com.alibaba.fastjson.JSONObject;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.yeejoin.amos.boot.module.jyjc.biz.config.LocalBadRequest;
import com.yeejoin.amos.boot.module.jyjc.biz.feign.WorkflowFeignClient;
import com.yeejoin.amos.boot.module.jyjc.biz.service.ICmWorkflowService;
import com.yeejoin.amos.component.feign.config.InnerInvokException;
import com.yeejoin.amos.component.feign.utils.FeignUtil;
import com.yeejoin.amos.feign.workflow.model.ActWorkflowBatchDTO;
import com.yeejoin.amos.feign.workflow.model.FlowTaskVo;
import com.yeejoin.amos.feign.workflow.model.ProcessTaskDTO;
import com.yeejoin.amos.feign.workflow.model.TaskResultDTO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.typroject.tyboot.core.foundation.exception.BaseException;

import java.nio.charset.StandardCharsets;
import java.util.List;
import java.util.Map;

/**
 * @author Administrator
 */
@Service
@Slf4j
public class CmWorkflowServiceImpl implements ICmWorkflowService {

    /**
     * 通过
     */
    public static String PASS_OPERATE = "0";

    /**
     * 驳回
     */
    public static String REJECT_OPERATE = "1";

    @Autowired
    private WorkflowFeignClient workflowFeignClient;

    @Override
    public List<ProcessTaskDTO> startBatch(ActWorkflowBatchDTO params) {
        List<ProcessTaskDTO> processTasks;
        try {
            log.info("开始请求工作流启动接口:/start/batch,请求参数：{}", JSONObject.toJSONString(params));
            processTasks = workflowFeignClient.startForBatch(params).getResult();
        } catch (InnerInvokException e) {
            //拦截无审核人异常信息
            String devMessage = e.getDevMessage();
            devMessage = devMessage.contains(";") ? devMessage.split(";")[0] : devMessage;
            log.error(devMessage);
            throw new LocalBadRequest(devMessage);
        } catch (Exception e) {
            log.error("调用工作流批量启动失败", e);
            throw new RuntimeException("调用工作流批量启动失败");
        }
        return processTasks;
    }

    @Override
    public ProcessTaskDTO completeOrReject(String taskId, TaskResultDTO data, String operate) {
        ProcessTaskDTO processTaskDTO;
        try {
            if(PASS_OPERATE.equals(operate)){
                // 通过操作
                log.info("开始请求工作流-完成任务-接口:/complete/standard/{taskId},请求参数：{},{},{}", taskId, operate, JSONObject.toJSONString(data));
                processTaskDTO = workflowFeignClient.completeByTaskFroStandard(taskId, data).getResult();
            } else if(REJECT_OPERATE.equals(operate)) {
                // 驳回操作
                log.info("开始请求工作流-驳回任务-接口:/reject/{taskId},请求参数：{},{},{}", taskId, operate, JSONObject.toJSONString(data));
                processTaskDTO = workflowFeignClient.reject(taskId, data).getResult();
            } else {
                // 执行普通节点（提交）
                log.info("开始请求工作流完成任务接口:/complete/standard/{taskId},请求参数：{},{},{}", taskId, operate, JSONObject.toJSONString(data));
                processTaskDTO = workflowFeignClient.completeByTaskFroStandard(taskId, data).getResult();
            }
            log.info("请求工作流接口completeOrReject结束，返回结果：{}", JSONObject.toJSONString(processTaskDTO));
        } catch (InnerInvokException e) {
            //拦截无审核人异常信息
            String devMessage = getErrorMessage(e);
            log.error(devMessage);
            throw new LocalBadRequest(devMessage);
        } catch (Exception e) {
            log.error("调用工作流完成任务接口失败", e);
            String responseBody = extractFeignResponseBody(e);
            String devMessage = extractDevMessageFromJson(responseBody);
            throw new RuntimeException( devMessage != null ? devMessage : "流程处理失败", e);
        }
        return processTaskDTO;
    }



    private String extractDevMessageFromJson(String jsonStr) {
        if (jsonStr == null || jsonStr.trim().isEmpty()) return null;

        try {
            ObjectMapper mapper = new ObjectMapper();
            Map<String, Object> json = mapper.readValue(jsonStr, Map.class);
            Object devMessage = json.get("devMessage");
            Object message = json.get("message");

            if (devMessage != null && !String.valueOf(devMessage).trim().isEmpty()) {
                return String.valueOf(devMessage);
            } else if (message != null) {
                return String.valueOf(message);
            }
        } catch (Exception ex) {
            log.warn("解析响应JSON出错: {}", jsonStr, ex);
        }
        return null;
    }


    private String getErrorMessage(BaseException e){
        String devMessage = e.getDevMessage();
        if(devMessage.contains(";")){
            String tempMsg = devMessage.split(";")[0];
            if(tempMsg.contains(":")){
                devMessage =  tempMsg.split(":")[1];
            } else {
                devMessage = tempMsg;
            }
        }
        return devMessage;
    }

    private String extractFeignResponseBody(Exception e) {
        if (e instanceof feign.FeignException) {
            feign.FeignException fe = (feign.FeignException) e;
            try {
                return new String(fe.content(), StandardCharsets.UTF_8);
            } catch (Exception ex) {
                log.warn("读取Feign响应体失败", ex);
            }
        }
        return e.getMessage();
    }

    @Override
    public ProcessTaskDTO complete(String taskId, TaskResultDTO data) {
        ProcessTaskDTO processTaskDTO;
        try {
            log.info("开始请求工作流完成任务接口:/complete/standard/{taskId},请求参数：{},{}", taskId, JSONObject.toJSONString(data));
            processTaskDTO = workflowFeignClient.completeByTaskFroStandard(taskId, data).getResult();
        } catch (InnerInvokException e) {
            //拦截无审核人异常信息
            String devMessage = e.getDevMessage();
            devMessage = devMessage.contains(";") ? devMessage.split(";")[0] : devMessage;
            log.error(devMessage);
            throw new LocalBadRequest(devMessage);
        } catch (Exception e) {
            log.error("调用工作流完成任务接口失败", e);
            throw new RuntimeException("调用工作流完成任务接口失败");
        }
        return processTaskDTO;
    }

    @Override
    public ProcessTaskDTO reject(String taskId, TaskResultDTO data) {
        ProcessTaskDTO processTaskDTO;
        try {
            log.info("开始请求工作流驳回任务接口:/v2/task/reject/{taskId},请求参数：{},{}", taskId, JSONObject.toJSONString(data));
            processTaskDTO = workflowFeignClient.reject(taskId, data).getResult();
        } catch (InnerInvokException e) {
            //拦截无审核人异常信息
            String devMessage = e.getDevMessage();
            devMessage = devMessage.contains(";") ? devMessage.split(";")[0] : devMessage;
            log.error(devMessage);
            throw new LocalBadRequest(devMessage);
        } catch (Exception e) {
            log.error("调用工作流完成任务接口失败", e);
            throw new RuntimeException("调用工作流完成任务接口失败");
        }
        return processTaskDTO;
    }

    @Override
    public ProcessTaskDTO rejectSpecifiedNode(String taskId, TaskResultDTO data) {
        ProcessTaskDTO processTaskDTO;
        try {
            log.info("开始请求工作流驳回到指定节点接口:/reject/specifiedNode/{taskId},请求参数：{},{}", taskId, JSONObject.toJSONString(data));
            processTaskDTO = workflowFeignClient.specifiedNode(taskId, data).getResult();
        } catch (InnerInvokException e) {
            //拦截无审核人异常信息
            String devMessage = e.getDevMessage();
            devMessage = devMessage.contains(";") ? devMessage.split(";")[0] : devMessage;
            log.error(devMessage);
            throw new LocalBadRequest(devMessage);
        } catch (Exception e) {
            log.error("调用工作流完成任务接口失败", e);
            throw new RuntimeException("调用工作流完成任务接口失败");
        }
        return processTaskDTO;
    }

    @Override
    public ProcessTaskDTO rollBack(String processInstanceId) {
        log.info("开始请求工作流撤回接口:/rollBack/standard/{processInstanceId},请求参数：{}", processInstanceId);
        return FeignUtil.remoteCall(() -> workflowFeignClient.rollBackTask(processInstanceId));
    }

    @Override
    public ProcessTaskDTO assign(FlowTaskVo taskVo) {
        ProcessTaskDTO processTaskDTO = new ProcessTaskDTO();
        try {
            log.info("开始请求工作流转办任务接口:/assign/{taskVo},请求参数：{},{}", taskVo);
            processTaskDTO = workflowFeignClient.assign(taskVo).getResult();
        } catch (InnerInvokException e) {
            //拦截无审核人异常信息
            String devMessage = e.getDevMessage();
            devMessage = devMessage.contains(";") ? devMessage.split(";")[0] : devMessage;
            log.error(devMessage);
            throw new LocalBadRequest(devMessage);
        } catch (Exception e) {
            log.error("调用工作流转办任务接口失败", e);
            throw new RuntimeException("调用工作流转办任务接口失败");
        }
        return processTaskDTO;
    }
}
