package com.chinaweal.aiccs.aiccs.business.controller;


import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.chinaweal.aiccs.aiccs.abnormal.entity.TSAttachment;
import com.chinaweal.aiccs.aiccs.abnormal.service.TSAttachmentService;
import com.chinaweal.aiccs.aiccs.auditing.entity.TSOpinion;
import com.chinaweal.aiccs.aiccs.auditing.service.TSOpinionService;
import com.chinaweal.aiccs.aiccs.business.entity.BizProblemReport;
import com.chinaweal.aiccs.aiccs.business.entity.TSHwfProcessNode;
import com.chinaweal.aiccs.aiccs.business.entity.TSTaskList;
import com.chinaweal.aiccs.aiccs.business.entity.TSTwfProcessNode;
import com.chinaweal.aiccs.aiccs.business.entity.dto.BaseProcessDto;
import com.chinaweal.aiccs.aiccs.business.service.BizProblemReportService;
import com.chinaweal.aiccs.aiccs.business.service.TSHwfProcessNodeService;
import com.chinaweal.aiccs.aiccs.business.service.TSTaskListService;
import com.chinaweal.aiccs.aiccs.business.service.TSTwfProcessNodeService;
import com.chinaweal.aiccs.common.base.controller.BaseController;
import com.chinaweal.aiccs.common.constant.BaseDataConstant;
import com.chinaweal.aiccs.common.constant.Constant;
import com.chinaweal.aiccs.common.util.StringUtils;
import com.chinaweal.aicorg.model.AICUser;
import com.chinaweal.aicorg.services.OrgUM;
import com.chinaweal.youfool.framework.springboot.exception.custom.BusinessException;
import com.chinaweal.youfool.framework.springboot.mybatis.plus.page.PageRequestDto;
import com.chinaweal.youfool.framework.springboot.rest.RestResult;
import com.chinaweal.youfool.framework.springboot.rest.ResultCode;
import com.chinaweal.youfool.framework.springboot.util.AssertUtils;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.time.LocalDateTime;
import java.util.*;

/**
 * <p>
 * 问题上报业务记录表 前端控制器
 * </p>
 *
 * @author <a href="https://blog.lroyia.top">lroyia</a>
 * @since 2021-04-21
 */
@RestController
@RequestMapping("/problem")
public class BizProblemReportController extends BaseController {

    @Autowired
    private BizProblemReportService bizProblemReportService;
    @Autowired
    private TSTaskListService taskListService;
    @Autowired
    private TSAttachmentService attachmentService;
    @Autowired
    private TSOpinionService opinionService;
    @Autowired
    private TSTwfProcessNodeService twfProcessNodeService;
    @Autowired
    private TSHwfProcessNodeService hwfProcessNodeService;
    @Autowired
    private OrgUM orgUM;

    /**
     * 简单分页
     *
     * @param request        请求
     * @param pageRequestDto 分页参数与
     * @return 分页结果
     * @author lroyia
     * @since 2021年4月22日 10:23:21
     */
    @PostMapping("page")
    @ApiOperation("简单分页")
    public RestResult<?> simplePage(HttpServletRequest request, @ApiParam("分页参数") @RequestBody PageRequestDto pageRequestDto) {
        AssertUtils.isNotNull(pageRequestDto);
        pageRequestDto.checkDefault(1, 10, "create_time");
        return RestResult.ok(bizProblemReportService.simplePage(new Page<>(pageRequestDto.getCurPage(), pageRequestDto.getPageSize()), pageRequestDto.getParamMap()));
    }


    /**
     * 暂存问题
     * 注意：为了在保存信息前可以上传文件并关联上，前端会生成一个guid作为附件的业务号，
     * 为了生成的业务号能保证在业务中唯一，将在问题数据保存后，将
     * <b>使用问题数据的id更新到附件的业务号</b>作为关联，并在后期
     *
     * @param problem 问题
     * @return 保存结果
     * @author lroyia
     * @since 2021年4月21日 16:10:31
     */
    @PostMapping("save")
    @ApiOperation("暂存问题")
    public RestResult<?> saveProblem(HttpServletRequest request, @ApiParam("问题参数") BizProblemReport problem) {
        AssertUtils.isNotNull(problem);

        problem.setLauptime(LocalDateTime.now());
        String bizseq = problem.getBizseq();
        problem.setBizseq(null);
        if (StringUtils.isBlank(problem.getProblemId())) {
            AICUser curUser = getLoginUser(request);
            problem.setReporterId(curUser.getPrimaryKey())
                    .setReportOrg(curUser.getOrgID());
            bizProblemReportService.save(problem);
        } else {
            problem.setLauptime(LocalDateTime.now());
            bizProblemReportService.updateById(problem);
        }
        /*
         * 保存后会生成问题id作为附件的业务号
         */
        if(StringUtils.isNotBlank(bizseq)
                && StringUtils.isNotBlank(problem.getProblemId())){
            attachmentService.update(new TSAttachment().setBizseq(problem.getProblemId()), new LambdaQueryWrapper<TSAttachment>().eq(TSAttachment::getBizseq, bizseq));
        }
        return RestResult.ok(problem.getProblemId());
    }

    /**
     * 上报问题
     *
     * @param request 请求
     * @param problem 问题上报信息
     * @return 处理结果
     * @author lroyia
     * @since 2021年4月21日 16:24:39
     */
    @PostMapping("report")
    @ApiOperation("上报问题（开启问题上报待办）")
    @Transactional(rollbackFor = Exception.class)
    public RestResult<?> reportProblem(HttpServletRequest request, @ApiParam("问题参数") BizProblemReport problem) {
        // 参数校验
        AssertUtils.isNotNull(problem);

        // 保存问题信息
        problem.setIsReport(Constant.TRUE_1_STR)
                .setState(Constant.TRUE_1_STR)
                .setReportTime(LocalDateTime.now());
        saveProblem(request, problem);

        return RestResult.ok(problem.getProblemId());
    }

    /**
     * 创建反馈待办
     *
     * @param request   请求
     * @param problemId 问题id
     * @return 创建待办结果
     * @author lroyia
     * @since 2021年4月22日 13:57:48
     */
    @ApiOperation("创建反馈待办")
    @PostMapping("createFeedbackTask")
    @Transactional(rollbackFor = Exception.class)
    public RestResult<?> createFeedbackTask(HttpServletRequest request, @ApiParam("问题id") String problemId) {
        // 参数校验
        AssertUtils.isNotBlank(problemId);
        BizProblemReport problem = bizProblemReportService.getById(problemId);

        String bizseq = UUID.randomUUID().toString();

        // 创建上报流程
        TSTaskList taskListModel = new TSTaskList();
        taskListModel.setBizseqid(bizseq);
        taskListModel.setBustype(BaseDataConstant.PROBLEM_FEEDBACK_BIZ);//上报流程
        taskListModel.setBusname(problem.getProblemTitle());
        bizProblemReportService.feedbackProblem(getLoginUser(request), taskListModel, problem);
        if (StringUtils.isNotBlank(taskListModel.getTasklistid())) {
            Map<String, Object> result = new HashMap<>();
            result.put("tasklistid", taskListModel.getTasklistid());
            result.put("bizseq", bizseq);
            result.put("workflowId", taskListModel.getWorkflowid());
            return RestResult.ok(result);
        }
        throw new BusinessException("发起反馈问题流程失败");
    }

    /**
     * 进入下一个反馈流程
     *
     * @param processDto    反馈问题参数信息体
     * @param feedbackOpinion 问题处理意见
     * @return 处理结果
     */
    @PostMapping("nextFeedbackProcess")
    @ApiOperation("进入下一个反馈流程")
    @Transactional(rollbackFor = Exception.class)
    public RestResult<?> nextFeedbackProcess(@ApiParam("反馈问题参数信息体") BaseProcessDto processDto, @ApiParam("反馈意见") String feedbackOpinion,
                                             HttpServletRequest request) {
        // 参数校验
        AssertUtils.isNotNull(processDto);

        AICUser curUser = getLoginUser(request);

        // 读取必须参数
        String[] ids = StringUtils.split(processDto.getNextUserIds(), ",");
        if(StringUtils.isBlank(processDto.getNextUserNames())){
            AICUser nextUser = orgUM.findUserByPrimaryKey(processDto.getNextUserIds());
            processDto.setNextUserNames(nextUser.getName());
        }
        String[] names = StringUtils.split(processDto.getNextUserNames(), ",");
        TSTaskList taskListModel = taskListService.selectByTasklistID(processDto.getTasklistid());
        TSOpinion opinionModel = new TSOpinion()
                .setWorkflowid(taskListModel.getWorkflowid())
                .setOpiniontype(processDto.getOpiniontype())
                .setOpinioncontent(processDto.getOpinioncontent());
        List<BizProblemReport> problemReports = bizProblemReportService.list(new LambdaQueryWrapper<BizProblemReport>().eq(BizProblemReport::getBizseq, taskListModel.getBizseqid()));

        // 更新处理结果
        if (StringUtils.isNotBlank(feedbackOpinion)) {
            for (BizProblemReport each : problemReports) {
                each.setFeedbackResult(feedbackOpinion);
            }
        }

        // 处理流程
        bizProblemReportService.nextProcess(curUser, taskListModel, opinionModel, processDto.getNextNodeId(), ids, names, problemReports.toArray(new BizProblemReport[0]));
        Map<String, Object> resultMap = new HashMap<>();
        resultMap.put("bizseq", taskListModel.getBizseqid());
        resultMap.put("workflowid", taskListModel.getWorkflowid());
        resultMap.put("nextNodeID", processDto.getNextNodeId());
        resultMap.put("tasklistid", processDto.getTasklistid());

        return RestResult.ok(resultMap);
    }

    /**
     * 获取问题详情
     * @param request 请求信息
     * @param id    数据id
     * @return  问题详情信息（含流程）
     * @author lroyia
     * @since  2021年4月23日 16:36:27
     */
    @GetMapping("detail/{id}")
    @ApiOperation("获取问题详情信息")
    public RestResult<?> getProblemDetail(HttpServletRequest request, @PathVariable @ApiParam("问题id") String id){

        // 查询问题基本信息
        BizProblemReport problem = bizProblemReportService.getProblemById(id);
        if(problem == null) return RestResult.error(ResultCode.DATA_NONE);

        // 封装结果
        Map<String, Object> result = new HashMap<>();
        result.put("problem", problem);
        // 附件
        result.put("files", attachmentService.list(new LambdaQueryWrapper<TSAttachment>().eq(TSAttachment::getBizseq, id)));

        // 如果没有业务流程信息，则直接返回结果
        if(StringUtils.isBlank(problem.getBizseq())) return RestResult.ok(result);

        // 查询业务流程信息
        String bizseq = problem.getBizseq();
        // 待办
        TSTaskList taskList = taskListService.getOne(new LambdaQueryWrapper<TSTaskList>().eq(TSTaskList::getBizseqid, bizseq));
        if(taskList == null) return RestResult.ok(result);
        result.put("taskList", taskList);
        String workFlowId = taskList.getWorkflowid();
        // 流程节点
        List<TSTwfProcessNode> nodes = twfProcessNodeService.list(new LambdaQueryWrapper<TSTwfProcessNode>().eq(TSTwfProcessNode::getProcessid, workFlowId).orderByDesc(TSTwfProcessNode::getLauptime));
        if(CollectionUtils.isNotEmpty(nodes)){
            result.put("nodes", nodes);
            return RestResult.ok(result);
        }
        List<TSHwfProcessNode> hNodes = hwfProcessNodeService.list(new LambdaQueryWrapper<TSHwfProcessNode>().eq(TSHwfProcessNode::getProcessid, workFlowId).orderByDesc(TSHwfProcessNode::getLauptime));
        result.put("nodes", hNodes);
        return RestResult.ok(result);
    }

    /**
     * 查询问题处置反馈总数
     *
     * @author lwd
     * @since 2021年06月29日 17:23:56
     */
    @PostMapping("simpleSize")
    @ApiOperation("问题处置反馈总数")
    public RestResult<?> simpleSize() {
        Map<String,Object> resultMap = new HashMap<>();
        List<BizProblemReport> bizProblemReportList = new ArrayList<>();
        bizProblemReportList = bizProblemReportService.selectbizProblemReportList();

        resultMap.put("wtczfk",bizProblemReportList.size());
        return RestResult.ok(resultMap);
    }
}

