package com.zcxk.task.controller;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.zcxk.client.UserCenterClient;
import com.zcxk.model.AjaxMessage;
import com.zcxk.model.LoginUser;
import com.zcxk.model.Pagination;
import com.zcxk.model.ResultStatus;
import com.zcxk.order.entity.WorkFlowDetail;
import com.zcxk.order.entity.WorkFlowLog;
import com.zcxk.order.service.WorkFlowLogService;
import com.zcxk.process.entity.ProcessDefinition;
import com.zcxk.process.service.WorkFlowService;
import com.zcxk.task.dto.PlanManageDto;
import com.zcxk.task.entity.PlanManage;
import com.zcxk.task.entity.UserEntity;
import com.zcxk.task.service.PlanManageService;
import com.zcxk.util.DatesUtil;
import com.zcxk.util.UserUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.activiti.engine.task.Task;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;

import java.util.*;
import java.util.stream.Collectors;

@RestController
@RequestMapping("/workflow/task/")
@Api(tags = "任务管理")
public class PlanManageController {

    @Autowired
    PlanManageService planManageService;

    @Autowired
    WorkFlowService workFlowService;

    @Autowired
    WorkFlowLogService workFlowLogService;

    @Autowired
    private UserCenterClient userCenterClient;


    @PostMapping("/plan/add")
    @ApiOperation(value = "新增巡检计划")
    public AjaxMessage addPlan(
            @ApiParam(value = "新增巡检计划", required = true) @RequestBody PlanManage planManage
                               ) {
        LoginUser loginUser = UserUtil.getCurrentUser();
        String planId=DatesUtil.formatDate(new Date(),"yyyyMMddHHmmss")+String.valueOf((int) (Math.random()*(9999-1000)+1000));
        PlanManage record = new PlanManage();
        record.setUserId(planManage.getUserId());
        record.setPlanId(planId);
        record.setPlanName(planManage.getPlanName());
        record.setTaskType(planManage.getTaskType());
        record.setTaskChecked(planManage.getTaskChecked());
        record.setPlanStartDate(planManage.getPlanStartDate());
        record.setPlanEndDate(planManage.getPlanEndDate());
        record.setPlanStatus(0);
        record.setTaskContent(planManage.getTaskContent());
        record.setTaskAreaShape(planManage.getTaskAreaShape());
        record.setTaskAreaName(planManage.getTaskAreaName());
        record.setDateCreate(new Date());
        if(loginUser.getId() != null) {
            record.setPlanUserId(String.valueOf(loginUser.getId()));
            record.setCreateBy(String.valueOf(loginUser.getId()));
        }
        if(loginUser.getTenantId() != null) {
            record.setTenantId(loginUser.getTenantId());
        }
        if(loginUser.getCompanyId() != null){
            record.setCompanyOrgId(loginUser.getCompanyId().toString());
        }
        if(loginUser.getDepartmentId() != null){
            record.setDepartmentOrgId(loginUser.getDepartmentId().toString());
        }
        int rows = planManageService.insertSelective(record);
        if(rows > 0) {
            return new AjaxMessage(ResultStatus.OK);
        }
        return new AjaxMessage(ResultStatus.ERROR);
    }

    @GetMapping("/plan/select")
    @ApiOperation(value = "查询巡检计划")
    public AjaxMessage<Pagination<PlanManageDto>> selectPlan(
            @ApiParam(value = "页数", required = true)@RequestParam Integer pageNum,
            @ApiParam(value = "条数", required = true)@RequestParam Integer pageSize,
            @ApiParam(value = "任务类型(巡检:7,侧漏:8,养护:9)", required = false) @RequestParam(required = false) Integer taskType,
            @ApiParam(value = "状态(0:巡检计划;null:所有任务;1:执行中;2:完成)", required = false) @RequestParam(required = false) Integer planStatus,
            @ApiParam(value = "计划单号或计划名称", required = false) @RequestParam(required = false) String key,
            @ApiParam(value = "计划起始日期(yyyy-MM-dd)", required = false) @RequestParam(required = false) String startDate,
            @ApiParam(value = "计划截至日期(yyyy-MM-dd)", required = false) @RequestParam(required = false) String endDate){
        PlanManageDto planManageDto = new PlanManageDto();
        //根据用户编号，获取用户的权限
        LoginUser loginUser = UserUtil.getCurrentUser();
        planManageDto.setKey(key);
        planManageDto.setPlanStatus(planStatus);
        planManageDto.setTaskType(taskType);
        planManageDto.setTenantId(loginUser.getTenantId());
        planManageDto.setProgramItems(loginUser.getProgramItemList());
        planManageDto.setUserType(loginUser.getType());
        //1是公司，2是公司及以下，3部门，4部门及以下，5自定义
        planManageDto.setPermissonType(loginUser.getPermissonType());
        if(!StringUtils.isEmpty(startDate)&& !StringUtils.isEmpty(endDate)) {
            planManageDto.setStartDate(startDate);
            planManageDto.setEndDate(endDate);
        }
        IPage<PlanManageDto> iPage = new Page<>(pageNum, pageSize);
        iPage = planManageService.selectPage(iPage, planManageDto);
        Pagination<PlanManageDto> pages = new Pagination<>(iPage);
        setName(pages.getList());
        return new AjaxMessage<>(ResultStatus.OK, pages);
    }

    @GetMapping("/plan/pending")
    @ApiOperation(value = "查询待处理任务")
    public AjaxMessage<Pagination<PlanManageDto>> selectPendingTask(
            @ApiParam(value = "页数", required = true)@RequestParam Integer pageNum,
            @ApiParam(value = "条数", required = true)@RequestParam Integer pageSize,
            @ApiParam(value = "任务类型(巡检:7,侧漏:8,养护:9)", required = false) @RequestParam(required = false) Integer taskType,
            @ApiParam(value = "计划单号或计划名称", required = false) @RequestParam(required = false) String key,
            @ApiParam(value = "计划起始日期(yyyy-MM-dd)", required = false) @RequestParam(required = false) String startDate,
            @ApiParam(value = "计划截至日期(yyyy-MM-dd)", required = false) @RequestParam(required = false) String endDate){

        PlanManageDto planManageDto = new PlanManageDto();
        //根据用户编号，获取用户的权限
        LoginUser loginUser = UserUtil.getCurrentUser();
        planManageDto.setKey(key);
        planManageDto.setTaskType(taskType);
        planManageDto.setTenantId(loginUser.getTenantId());
        //planManageDto.setProgramItems(loginUser.getProgramItemList());
        //planManageDto.setUserType(loginUser.getType());
        //1是公司，2是公司及以下，3部门，4部门及以下，5自定义
        //planManageDto.setPermissonType(loginUser.getPermissonType());

        if(!StringUtils.isEmpty(startDate)&& !StringUtils.isEmpty(endDate)) {
            planManageDto.setStartDate(startDate);
            planManageDto.setEndDate(endDate);
        }
        if(loginUser.getId() != null) {
            planManageDto.setCurrentUsers(String.format("%s", loginUser.getId()));
        }
        IPage<PlanManageDto> iPage = new Page<>(pageNum, pageSize);
        iPage = planManageService.selectPage(iPage, planManageDto);
        Pagination<PlanManageDto> pages = new Pagination<>(iPage);
        setName(pages.getList());
        return new AjaxMessage<>(ResultStatus.OK, pages);
    }

    @GetMapping("/plan/pending/power")
    @ApiOperation(value = "待处理权限")
    public AjaxMessage<Boolean> selectPendingPower(
            @ApiParam(value = "任务ID", required = true) @RequestParam(required = true) Integer id){
        String currentUsers = null;
        LoginUser loginUser = UserUtil.getCurrentUser();
        if(loginUser.getId() != null) {
            currentUsers = String.format("%s", loginUser.getId());
        }
        Map<String,Object> map = new HashMap<String,Object>();
        map.put("id",id);
        map.put("currentUsers",currentUsers);
        int rows = planManageService.selectPendingPower(map);
        if(rows>0){
            return new AjaxMessage<Boolean>(ResultStatus.OK, true);
        }
        return new AjaxMessage<Boolean>(ResultStatus.OK, false);
    }

    /**
     * APP查询任务详情
     * @return Response对象
     */
    @RequestMapping(value = "selectPlanDetail", method = RequestMethod.GET)
    @ApiOperation(value = "APP查询任务详情")
    public AjaxMessage<PlanManageDto> selectPlanDetail(
            @ApiParam(value = "任务id", required = true) @RequestParam Integer flowId) {
        PlanManageDto result=planManageService.selectPlanDetail(flowId);

        setName(new ArrayList<PlanManageDto>(){{
            this.add(result);
        }});
        return new AjaxMessage<>(ResultStatus.OK, result );
    }

    @GetMapping("/plan/submit")
    @ApiOperation(value = "提交巡检计划")
    public AjaxMessage submitPlan(
            @ApiParam(value = "任务ID", required = true) @RequestParam(required = true) Integer id,
            @ApiParam(value = "任务类型", required = true) @RequestParam(required = true) String taskType){
        LoginUser loginUser = UserUtil.getCurrentUser();
        PlanManage planManage = planManageService.selectByPrimaryKey(id);
//        ProcessDefinition processDefinition = workFlowService.findProcessDefinition(
//                loginUser.getTenantId(),
//                loginUser.getCompanyId(),
//                planManage.getTaskType());
        //流程查询, 测试参数:(test1 1 1)
        ProcessDefinition processDefinition = workFlowService.findProcessDefinition(
                loginUser.getTenantId(),
                loginUser.getCompanyId(),
                planManage.getTaskType());
        if(processDefinition == null){
            return new AjaxMessage(ResultStatus.ERROR,"没有创建流程，不能提交！");
        }
        Map<String,Object> vars = new HashMap<>();
        vars.put("assineeFormUserId",planManage.getUserId());
        //巡检发送系统消息所需参数
        vars.put("任务类型",taskType);
        vars.put("任务编号",planManage.getPlanId());
        vars.put("url",String.format("?id=%s",planManage.getId().toString()));
        vars.put("templateId",4);
        vars.put("msgType",4);
        String startProcess = workFlowService.startProcess(processDefinition,vars);
        Task task = workFlowService.getProcessRuntimeTask(startProcess).get(0);
        Set<String> taskParticipator = workFlowService.getTaskParticipator(task.getId(),false,null);
        String currentUsers = "";
        for (String str : taskParticipator) {
            currentUsers += String.format("%s,",str);
        }
        //更新计划表的流程相关字段值。
        planManage.setPlanStatus(1);//已执行
        if(loginUser.getId() != null) {
            planManage.setUpdateBy(String.valueOf(loginUser.getId()));
        }
        planManage.setPlanDate(new Date());// 提交时间
        planManage.setDateUpdate(new Date());// 更新时间
        planManage.setProcessInstanceId(task.getProcessInstanceId());
        planManage.setProcessDefId(task.getProcessDefinitionId());
        planManage.setCurrentTaskId(task.getId());
        planManage.setCurrentUsers(currentUsers);
        planManage.setCurrentTaskName(task.getName());
        int rows = planManageService.updateByPrimaryKeySelective(planManage);
        if(rows > 0) {
            WorkFlowLog workFlowLog=new WorkFlowLog();
            workFlowLog.setFlowId(id);
            workFlowLog.setFlowType(1);
            workFlowLog.setFlowResult("任务提交【启动流程】");
            workFlowLog.setCreateBy(loginUser.getId().toString());
            workFlowLog.setDateCreate(new Date());
            workFlowLog.setHandleUserId(loginUser.getId()!=null?loginUser.getId().toString():null);
            workFlowLog.setHandleUserName(loginUser.getUsername());
            workFlowLog.setProcessInstanceId(planManage.getProcessInstanceId());
            workFlowLog.setTaskId(planManage.getCurrentTaskId());
            workFlowLogService.insert(workFlowLog);
            return new AjaxMessage<>(ResultStatus.OK);
        }
        return new AjaxMessage<>(ResultStatus.ERROR);
    }

    @PostMapping("/plan/update")
    @ApiOperation(value = "修改巡检计划")
    public AjaxMessage updatePlan(@ApiParam(value = "修改巡检计划", required = true) @RequestBody PlanManage planManage) {
        PlanManage record = new PlanManage();
        record.setId(planManage.getId());
        record.setUserId(planManage.getUserId());
        record.setPlanName(planManage.getPlanName());
        record.setTaskType(planManage.getTaskType());
        record.setTaskChecked(planManage.getTaskChecked());
        record.setPlanStartDate(planManage.getPlanStartDate());
        record.setPlanEndDate(planManage.getPlanEndDate());
        record.setTaskContent(planManage.getTaskContent());
        record.setTaskAreaShape(planManage.getTaskAreaShape());
        record.setTaskAreaName(planManage.getTaskAreaName());
        LoginUser loginUser = UserUtil.getCurrentUser();
        if(loginUser.getId() != null) {
            record.setUpdateBy(String.valueOf(loginUser.getId()));
        }
        record.setDateUpdate(new Date());
        int rows = planManageService.updateByPrimaryKeySelective(record);
        if(rows > 0) {
            return new AjaxMessage(ResultStatus.OK);
        }
        return new AjaxMessage(ResultStatus.ERROR);
    }

    @RequestMapping(value="batchDelete" , method = RequestMethod.DELETE)
    @ApiOperation(value = "批量删除")
    public AjaxMessage<Integer> batchDelete( @ApiParam(value = "巡检计划ids") @RequestParam List<Integer> ids){
        return new AjaxMessage<>(ResultStatus.OK, planManageService.batchDelete(ids));
    }

    @GetMapping("/plan/delProcInst")
    @ApiOperation(value = "终止流程")
    public AjaxMessage deleteProcessInstance(
            @ApiParam(value = "任务ID", required = true) @RequestParam(required = true) Integer id,
            @ApiParam(value = "流程ID", required = true) @RequestParam(required = true) String processInstanceId,
            @ApiParam(value = "流程备注", required = false) @RequestParam(required = false) String remark) {
        workFlowService.stopProcessInstance(processInstanceId);
        PlanManage planManage = new PlanManage();
        planManage.setId(id);
        planManage.setPlanStatus(3);//任务终止状态
        planManage.setCurrentUsers("");
        planManage.setFinishDate(new Date());
        planManageService.updateByPrimaryKeySelective(planManage);
        LoginUser currentUser = UserUtil.getCurrentUser();
        WorkFlowLog workFlowLog=new WorkFlowLog();
        workFlowLog.setFlowId(id);
        workFlowLog.setFlowType(1);
        workFlowLog.setFlowResult(remark);
        workFlowLog.setCreateBy(currentUser.getId()!=null?currentUser.getId().toString():null);
        workFlowLog.setDateCreate(new Date());
        workFlowLog.setHandleUserId(currentUser.getId()!=null?currentUser.getId().toString():null);
        workFlowLog.setHandleUserName(currentUser.getUsername());
        //记录日志
       workFlowLogService.insert(workFlowLog);
       return new AjaxMessage<>(ResultStatus.OK);
    }

    /**
     * 获取并设置用户、任务工单类型名称
     * @param
     */
    private void setName(List<PlanManageDto> planManageDtoList){
        try {
            if(planManageDtoList.size()>0) {
                List<Long> idList = new ArrayList<Long>();
                for (PlanManageDto plan : planManageDtoList) {
                    if(plan.getUserId() != null) {
                        idList.add(Long.parseLong(plan.getUserId()));
                    }
                    if(plan.getPlanUserId() != null){
                        idList.add(Long.parseLong(plan.getPlanUserId()));
                    }
                    if(plan.getCreateBy() != null){
                        idList.add(Long.parseLong(plan.getCreateBy()));
                    }
                    if(plan.getUpdateBy() != null){
                        idList.add(Long.parseLong(plan.getUpdateBy()));
                    }
                }
                Long[] ids = idList.toArray(new Long[0]);
                Map<Long,String> userMap=new HashMap<>();
                if(ids.length>0){
                   userMap = userCenterClient.findUserIdsByUserIds(ids).stream().collect(Collectors.toMap(UserEntity::getId, UserEntity::getUsername));
                }
                Map<String,String> dictMap=userCenterClient.selectListByPCodes("SC_WORK_ORDER_TYPE,SC_TASK_TYPE");
                for(int i=0; i<planManageDtoList.size();i++){
                    PlanManageDto plan = planManageDtoList.get(i);
                    try {
                        if (plan.getTaskType() != null) {
                            plan.setTypeName(dictMap.get(plan.getTaskType().toString()));
                        }
                        if (plan.getUserId() != null) {
                            plan.setUserName(userMap.get(Long.valueOf(plan.getUserId())));
                        }
                        if (plan.getPlanUserId() != null) {
                            plan.setPlanUserName(userMap.get(Long.valueOf(plan.getPlanUserId())));
                        }
                        if (plan.getCreateBy() != null) {
                            plan.setCreateByName(userMap.get(Long.valueOf(plan.getCreateBy())));
                        }
                        if (plan.getUpdateBy() != null) {
                            plan.setUpdateByName(userMap.get(Long.valueOf(plan.getUpdateBy())));
                        }
                        if (plan.getWorkFlowDetail() != null) {
                            WorkFlowDetail workFlowDetail = plan.getWorkFlowDetail();
                            if (workFlowDetail.getCreateBy() != null) {
                                workFlowDetail.setCreateByName(userMap.get(Long.valueOf(workFlowDetail.getCreateBy())));
                            }
                            if (workFlowDetail.getUpdateBy() != null) {
                                workFlowDetail.setUpdateByName(userMap.get(Long.valueOf(workFlowDetail.getUpdateBy())));
                            }
                        }
                        if (plan.getWorkFlowLogList() != null) {
                            for (WorkFlowLog workFlowLog : plan.getWorkFlowLogList()) {
                                try {
                                    if (workFlowLog.getCreateBy() != null) {
                                        workFlowLog.setCreateByName(userMap.get(Long.valueOf(workFlowLog.getCreateBy())));
                                    }
                                    if (workFlowLog.getUpdateBy() != null) {
                                        workFlowLog.setUpdateByName(userMap.get(Long.valueOf(workFlowLog.getUpdateBy())));
                                    }
                                }catch (Exception e){

                                }
                            }
                        }
                    }catch(Exception e){

                    }
                }
            }
        }catch (Exception e){
            e.printStackTrace();
        }
    }

    /**
     * 综合展示/App-查询任务执行情况
     * @return Response对象
     */
    @RequestMapping(value = "selectTaskFinished", method = RequestMethod.GET)
    @ApiOperation(value = "综合展示/App-查询任务执行情况")
    public AjaxMessage<List<PlanManageDto>> selectTaskFinished(
            @ApiParam(value = "公司机构id", required = false)@RequestParam(required = false) Integer companyOrgId,
            @ApiParam(value = "0或null本月、1本年、2近一年", required = false)@RequestParam(required = false) Integer statsType) {
        PlanManageDto planManageDto=new PlanManageDto();
        planManageDto.setCompanyOrgId(companyOrgId!=null?companyOrgId.toString():null);
        planManageDto.setStatsType(statsType);

        LoginUser loginUser = UserUtil.getCurrentUser();
        planManageDto.setTenantId(loginUser.getTenantId());
        planManageDto.setProgramItems(loginUser.getProgramItemList());
        planManageDto.setUserType(loginUser.getType());
        //1是公司，2是公司及以下，3部门，4部门及以下，5自定义
        planManageDto.setPermissonType(loginUser.getPermissonType());
        List<PlanManageDto> result=planManageService.selectTaskFinished(planManageDto);
        setName(result);
        return new AjaxMessage<>(ResultStatus.OK, result );
    }

    @RequestMapping(value = "selectWorkFlowById", method = RequestMethod.GET)
    @ApiOperation(value = "查询任务工作流")
    public AjaxMessage<PlanManageDto> selectWorkFlowById(
            @ApiParam(value = "任务id", required = true) @RequestParam Integer flowId) {
        PlanManageDto result = planManageService.selectWorkFlowById(flowId);
        setName(new ArrayList<PlanManageDto>(){{
            this.add(result);
        }});
        return new AjaxMessage<>(ResultStatus.OK, result );
    }
}