package cn.iocoder.yudao.module.bpm.controller.admin.task;

import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.datapermission.core.annotation.DataPermission;
import cn.iocoder.yudao.module.bpm.controller.admin.oa.vo.print.BpmProcessInstancePrintDataReqVO;
import cn.iocoder.yudao.module.bpm.controller.admin.oa.vo.print.BpmProcessInstancePrintDataRespVO;
import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance.*;
import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.task.BpmTaskRespVO;
import cn.iocoder.yudao.module.bpm.convert.task.BpmTaskConvert;
import cn.iocoder.yudao.module.bpm.service.message.BpmMessageService;
import cn.iocoder.yudao.module.bpm.service.task.BpmProcessInstanceService;
import cn.iocoder.yudao.module.bpm.service.task.BpmTaskService;
import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.flowable.engine.runtime.ProcessInstance;
import org.flowable.task.api.Task;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.validation.Valid;
import java.util.List;

import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;

@Tag(name = "管理后台 - 流程实例") // 流程实例，通过流程定义创建的一次“申请”
@RestController
@RequestMapping("/bpm/process-instance")
@Validated
public class BpmProcessInstanceController {

    @Resource
    private BpmProcessInstanceService processInstanceService;

    @Resource
    private BpmTaskService bpmTaskService;

    @Resource
    private AdminUserApi adminUserApi;

    @Resource
    private BpmMessageService messageService;

    @GetMapping("/my-page")
    @Operation(summary = "获得我的实例分页列表", description = "在【我的流程】菜单中，进行调用")
    @PreAuthorize("@ss.hasPermission('bpm:process-instance:query')")
    @DataPermission(enable = false)
    public CommonResult<PageResult<BpmProcessInstancePageItemRespVO>> getMyProcessInstancePage(
            @Valid BpmProcessInstanceMyPageReqVO pageReqVO) {
        return success(processInstanceService.getMyProcessInstancePage(getLoginUserId(), pageReqVO));
    }

    @PostMapping("/create")
    @Operation(summary = "新建流程实例")
    @PreAuthorize("@ss.hasPermission('bpm:process-instance:query')")
    @DataPermission(enable = false)
    public CommonResult<String> createProcessInstance(@Valid @RequestBody BpmProcessInstanceCreateReqVO createReqVO) {
        return success(processInstanceService.createProcessInstance(getLoginUserId(), createReqVO));
    }

    @GetMapping("/get")
    @Operation(summary = "获得指定流程实例", description = "在【流程详细】界面中，进行调用")
    @Parameter(name = "id", description = "流程实例的编号", required = true)
    @PreAuthorize("@ss.hasPermission('bpm:process-instance:query')")
    @DataPermission(enable = false)
    public CommonResult<BpmProcessInstanceRespVO> getProcessInstance(@RequestParam("id") String id) {
        return success(processInstanceService.getProcessInstanceVO(id));
    }

    @GetMapping("/urge-approve")
    @Operation(summary = "审批提醒", description = "在【流程详细】界面中，进行调用")
    @Parameter(name = "id", description = "流程实例的编号", required = true)
    @PreAuthorize("@ss.hasPermission('bpm:process-instance:query')")
    @DataPermission(enable = false)
    public CommonResult<Boolean> urgeApprove(@RequestParam("id") String id) {

        //获得流程实例
        ProcessInstance processInstance = processInstanceService.getProcessInstance(id);
        if (processInstance != null) {
            // 获得任务列表
            List<BpmTaskRespVO> BpmTaskRespVOs = bpmTaskService.getTaskListByProcessInstanceId(id);
            AdminUserRespDTO startUser = adminUserApi.getUser(Long.valueOf(processInstance.getStartUserId())).getCheckedData();
            Task task = bpmTaskService.getTasksByProcessInstanceId(id).get(0);
            //发送信息通知
            messageService.sendMessageWhenTaskAssigned(
                    BpmTaskConvert.INSTANCE.convert(processInstance, startUser, task, BpmTaskRespVOs));
        }

        return success(true);
    }

    @DeleteMapping("/cancel")
    @Operation(summary = "取消流程实例", description = "撤回发起的流程")
    @PreAuthorize("@ss.hasPermission('bpm:process-instance:cancel')")
    @DataPermission(enable = false)
    public CommonResult<Boolean> cancelProcessInstance(@Valid @RequestBody BpmProcessInstanceCancelReqVO cancelReqVO) {
        processInstanceService.cancelProcessInstance(getLoginUserId(), cancelReqVO);
        return success(true);
    }

    /**
     * 流程实例数量统计查询
     * 根据流程名称分组，统计各个流程的具体实例数据
     */
    @GetMapping("/process_instance_group_name_statistics")
    @Operation(summary = "根据流程名称分组，统计各个流程的具体实例数据", description = "根据流程名称分组，统计各个流程的具体实例数据")
    //@PreAuthorize("@ss.hasPermission('bpm:task:update')")
    @DataPermission(enable = false)
    public CommonResult<List<BpmProcessInstanceStatisticsRespVO>> getProcessInstancesGroupByModelName(@Valid BpmProcessInstanceStatisticsReqVO reqVO) {
        List<BpmProcessInstanceStatisticsRespVO> list = processInstanceService.getProcessInstancesGroupByModelName(reqVO);
        return success(list);
    }

    /**
     * 流程实例的状态统计查询
     * 根据流程状态（处理中，通过，不通过，取消），统计各个状态的数据量
     */
    @GetMapping("/process_instance_result_status_statistics")
    @Operation(summary = "流程实例的状态统计查询", description = "根据流程状态（处理中，通过，不通过，取消），统计各个状态的数据量")
    @DataPermission(enable = false)
    public CommonResult<List<BpmProcessInstanceStatisticsRespVO>> getProcessInstancesGroupByResultStatus(@Valid BpmProcessInstanceStatisticsReqVO reqVO) {
        List<BpmProcessInstanceStatisticsRespVO> list = processInstanceService.getProcessInstancesGroupByResultStatus(reqVO);
        return success(list);
    }

    @GetMapping("/getAll")
    @Operation(summary = "获得所有实例分页列表", description = "在【统计查询】菜单中，进行调用")
    @PreAuthorize("@ss.hasPermission('bpm:process-instance:query')")
    public CommonResult<PageResult<BpmProcessInstancePageItemRespVO>> getAllProcessInstancePage(
            @Valid BpmProcessInstanceMyPageReqVO pageReqVO) {
        return success(processInstanceService.getStatisticsProcessInstancePage(pageReqVO));
    }

    @GetMapping("/getUserProcessTpo10")
    @Operation(summary = "获得用户审批耗时最长Top10", description = "在工作台-给数据权限是可以查看全部数据的用户查询使用")
    @DataPermission(enable = false)
    public CommonResult<List<BpmProcessFinishStatisticsRespVO>> getUserProcessTpo10(@Valid BpmProcessInstanceStatisticsReqVO reqVO) {
        List<BpmProcessFinishStatisticsRespVO> list = processInstanceService.getUserProcessTpo10(reqVO);
        return success(list);
    }

    @PostMapping("/getOAReportPrintDataByProcessType")
    @Operation(summary = "获取OA打印报表数据", description = "流程审批通过后需要打印的数据，包含用户电子签名的地址")
    @DataPermission(enable = false)
    public CommonResult<BpmProcessInstancePrintDataRespVO> getOAReportPrintData(@Valid @RequestBody BpmProcessInstancePrintDataReqVO reqVO) {
        return success(processInstanceService.getOAReportPrintData(reqVO));
    }

}
