package com.ruoyi.flowable.service.impl;

import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;

import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.enums.FileType;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.sms.SmsSenderUtils;
import com.ruoyi.common.utils.uuid.IdUtils;
import com.ruoyi.flowable.common.constant.ProcessConstants;
import com.ruoyi.flowable.common.constant.UUIDGenerator;
import com.ruoyi.flowable.common.enums.FlowStatusEnum;
import com.ruoyi.flowable.factory.FlowServiceFactory;
import com.ruoyi.flowable.service.IFlowInstanceService;
import com.ruoyi.flowable.service.IFlowService;
import com.ruoyi.flowable.service.ISysFormService;
import com.ruoyi.flowable.service.ISysTaskFormService;
import com.ruoyi.invest.domain.*;
import com.ruoyi.invest.service.IFlowBaseInfoService;
import com.ruoyi.invest.service.ITProjectCirculationService;
import com.ruoyi.invest.service.ITProjectPoolService;
import com.ruoyi.system.mapper.SysDeptMapper;
import com.ruoyi.system.service.ISysUserService;
import com.ruoyi.tool.service.ITUnifyFileService;
import org.flowable.engine.RepositoryService;
import org.flowable.engine.repository.ProcessDefinition;
import org.flowable.engine.runtime.ProcessInstance;
import org.flowable.task.api.Task;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.ruoyi.invest.mapper.TProjectInvestigateMapper;
import com.ruoyi.invest.service.ITProjectInvestigateService;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;

/**
 * 尽调关联Service业务层处理
 * 
 * @author zjc
 * @date 2024-03-13
 */
@Service
public class TProjectInvestigateServiceImpl extends FlowServiceFactory implements ITProjectInvestigateService
{

    protected final Logger logger = LoggerFactory.getLogger(this.getClass());
    @Resource
    protected RepositoryService repositoryService;
    @Autowired
    private TProjectInvestigateMapper tProjectInvestigateMapper;
    @Autowired
    private SysDeptMapper sysDeptMapper;
    @Autowired
    private ISysUserService sysUserService;
    @Autowired
    private ITProjectCirculationService tProjectCirculationService;

    @Autowired
    private ITUnifyFileService tUnifyFileService;

    @Autowired
    private ITProjectPoolService tProjectPoolService;

    @Autowired
    private IFlowBaseInfoService activitiBaseInfoService;
    @Autowired
    private IFlowInstanceService flowInstanceService;

    @Autowired
    private IFlowService flowService;

    @Autowired
    private ISysFormService sysFormService;

    /**
     * 查询尽调关联
     * 
     * @param id 尽调关联主键
     * @return 尽调关联
     */
    @Override
    public TProjectInvestigate selectTProjectInvestigateById(String id)
    {
        return tProjectInvestigateMapper.selectTProjectInvestigateById(id);
    }

    /**
     * 查询尽调关联列表
     * 
     * @param tProjectInvestigate 尽调关联
     * @return 尽调关联
     */
    @Override
    public List<TProjectInvestigate> selectTProjectInvestigateList(TProjectInvestigate tProjectInvestigate)
    {
        return tProjectInvestigateMapper.selectTProjectInvestigateList(tProjectInvestigate);
    }

    /**
     * 新增尽调关联
     * 
     * @param tProjectInvestigate 尽调关联
     * @return 结果
     */
    @Override
    public int insertTProjectInvestigate(TProjectInvestigate tProjectInvestigate)
    {
        tProjectInvestigate.setCreateTime(DateUtils.getNowDate());
        return tProjectInvestigateMapper.insertTProjectInvestigate(tProjectInvestigate);
    }

    /**
     * 修改尽调关联
     * 
     * @param tProjectInvestigate 尽调关联
     * @return 结果
     */
    @Override
    public int updateTProjectInvestigate(TProjectInvestigate tProjectInvestigate)
    {
        tProjectInvestigate.setUpdateTime(DateUtils.getNowDate());
        return tProjectInvestigateMapper.updateTProjectInvestigate(tProjectInvestigate);
    }

    /**
     * 批量删除尽调关联
     * 
     * @param ids 需要删除的尽调关联主键
     * @return 结果
     */
    @Override
    public int deleteTProjectInvestigateByIds(String[] ids)
    {
        return tProjectInvestigateMapper.deleteTProjectInvestigateByIds(ids);
    }

    /**
     * 删除尽调关联信息
     * 
     * @param id 尽调关联主键
     * @return 结果
     */
    @Override
    public int deleteTProjectInvestigateById(String id)
    {
        return tProjectInvestigateMapper.deleteTProjectInvestigateById(id);
    }

    /**
     * 批量删除尽调关联
     * @param ids 需要删除的尽调关联主键
     * @return
     */
    @Override
    public int updateTProjectInvestigateByIds(String[] ids) {
        return tProjectInvestigateMapper.updateTProjectInvestigateByIds(ids);
    }

    /**
     * 根据项目ID获取尽调数据
     * @param projectPoolId
     * @return
     */
    @Override
    public List<TProjectInvestigate> listProjectPoolId(String projectPoolId) {
        return tProjectInvestigateMapper.listProjectPoolId(projectPoolId);
    }

    /**
     * 根据项目ID获取最新尽调数据
     * @param projectPoolId
     * @return
     */
    @Override
    public TProjectInvestigate listProjectPoolIdNew(String projectPoolId) {
        return tProjectInvestigateMapper.listProjectPoolIdNew(projectPoolId);
    }

    /**
     * 修改尽调完成
     * @param id
     * @return
     */
    @Override
    public int editStatus(String id) {
        return tProjectInvestigateMapper.editStatus(id);
    }

    @Override
    public List<TProjectInvestigateVo> getMyTaskList(String userId, TProjectInvestigateVo tProjectInvestigate) {
        return tProjectInvestigateMapper.getMyTaskList(userId,tProjectInvestigate);
    }

    @Override
    public List<TProjectInvestigateVo> getMyDoneTaskList(String userId, TProjectInvestigateVo tProjectInvestigate) {
        return tProjectInvestigateMapper.getMyDoneTaskList(userId,tProjectInvestigate);
    }

    @Override
    public List<TProjectInvestigateVo> getMyList(String userId, TProjectInvestigateVo tProjectInvestigate) {
        return tProjectInvestigateMapper.getMyList(userId,tProjectInvestigate);
    }

    @Override
    public AjaxResult start(TProjectInvestigate tProjectInvestigate) {
        // 根据key值获取最新的流程部署id
        String pDefId = null;
        ProcessInstance pInst = null;
        try {
            List<ProcessDefinition> list = repositoryService.createProcessDefinitionQuery()
                    .processDefinitionKey("dgt-due-workflow")
                    .orderByProcessDefinitionVersion().desc().list();
            if(list.isEmpty()){
                return AjaxResult.error("未找到该流程，无法开启流程！");
            }
            pDefId = list.get(0).getId();
            ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery().processDefinitionId(pDefId)
                    .latestVersion().singleResult();
            if (Objects.nonNull(processDefinition) && processDefinition.isSuspended()) {
                return AjaxResult.error("流程已被挂起,请先激活流程");
            }
            if(StringUtils.isNotBlank(pDefId)) {
                //设置参数
                Map<String, Object> formProperties = new HashMap<String, Object>();
                // 设置流程发起人Id到流程中
                SysUser sysUser = SecurityUtils.getLoginUser().getUser();
                identityService.setAuthenticatedUserId(sysUser.getUserId().toString());
                formProperties.put("auditPass",tProjectInvestigate.isFlag()?true:false);
                formProperties.put(ProcessConstants.PROCESS_INITIATOR, sysUser.getUserId());
                pInst = runtimeService.startProcessInstanceById(pDefId, formProperties);
                if(pInst!=null){
                    String nickName= SecurityUtils.getLoginUser().getUser().getNickName();
                    String userId=SecurityUtils.getLoginUser().getUserId().toString();
                    //保存信息
                    tProjectInvestigate.setId(IdUtils.fastSimpleUUID());
                    tProjectInvestigate.setProcInstId(pInst.getProcessInstanceId());
                    // todo 保存附件信息
                    tUnifyFileService.insertTUnifyFileList(tProjectInvestigate.getListFile(),
                            tProjectInvestigate.getProjectPoolId(),
                            tProjectInvestigate.getId(),//尽调ID
                            String.valueOf(FileType.INVESTIGATE.ordinal()),//文件类型:尽调
                            nickName);

                    // todo 增加尽调创建记录
                    tProjectCirculationService.insertTProjectCirculation(tProjectInvestigate.getProjectPoolId(),tProjectInvestigate.getInvestigateName()+"(尽职背调)",nickName);

                    // todo 更改尽调状态
                    tProjectPoolService.updateTProjectPoolByInvestigateFlag(tProjectInvestigate.getProjectPoolId(),"1");

                    //新增尽调数据
                    insertTProjectInvestigate(tProjectInvestigate);
                    FlowBaseInfo flowBaseInfo = new FlowBaseInfo();
                    flowBaseInfo.setCreateBy(userId);
                    flowBaseInfo.setId(UUIDGenerator.uuid());
                    flowBaseInfo.setFormProperties(flowInstanceService.getFormProperties(pInst));
                    flowBaseInfo.setProcDefId(pDefId);
                    flowBaseInfo.setProcInsId(pInst.getId());
                    flowBaseInfo.setTaskName("申请人");
                    flowBaseInfo.setFlag(true);
                    flowBaseInfo.setComment("[提交申请]");
                    flowBaseInfo.setStatus(FlowStatusEnum.STARTED.getName());

                    activitiBaseInfoService.addActivitiBaseInfo(flowBaseInfo);
                    // todo 短信提醒
                    /*if(StringUtils.isNotEmpty(tProjectInvestigate.getInvestigatePersonId())){
                        StringUtils.str2List(tProjectInvestigate.getInvestigatePersonId(),",",true,true).stream().forEach(str -> {
                            SysUser user = sysUserService.selectUserById(Long.valueOf(str));
                            String contents = "您好，"+user.getNickName()+"，" + tProjectInvestigate.getProjectName() + "已开启尽职背调。";
                            try {
                                SmsSenderUtils.sendSms(user.getPhonenumber(),contents);
                            } catch (IOException e) {
                                logger.error("短信发送失败"+e.getMessage());
                            }
                        });
                    }*/

                    //更新代办任务数量
                    sysFormService.updateToDoNumber();
                    return AjaxResult.success();

                }
                return AjaxResult.error();
            }
            return AjaxResult.error();
        }catch (Exception e){
            e.printStackTrace();
            return AjaxResult.error("msg", "流程定义id为空, 无法开启流程！");
        }
    }

    @Override
    public AjaxResult complete(TProjectInvestigate tProjectInvestigate, TProjectReview tProjectReview, FlowBaseInfo flow, HttpServletRequest request) {
        Task task=taskService.createTaskQuery().processInstanceId(tProjectInvestigate.getProcInstId()).singleResult();
        //Task task = taskService.createTaskQuery().taskId(taskVo.getId()).singleResult();
        if (Objects.isNull(task)) {
            return AjaxResult.error("任务不存在");
        }
        //当前你登录人
        SysUser userInfo=SecurityUtils.getLoginUser().getUser();
        Map<String, Object> rs = new HashMap<String, Object>();
        rs.put("status",true);
        Map<String, Object> formProperties = new HashMap<>();
        formProperties.put("auditPass", tProjectInvestigate.isFlag());
        //部门负责人
        String leader=sysDeptMapper.selectDeptLeader("投资部");
        SysUser sysUser=sysUserService.selectUserByUserName(leader);
        formProperties.put("MANAGER",sysUser.getUserId());
        //taskService.complete(task.getId(), formProperties);
        Map<String, Object> fpMap = flowService.getFormProperties(task.getProcessDefinitionId(), task.getId());
        try {
            rs = flowService.taskComplete( task.getId(), tProjectInvestigate.isFlag(), formProperties, userInfo.getUserId().toString());
        } catch (Exception e) {
            e.printStackTrace();
            rs.put("status", false);
            rs.put("msg", "流程审批失败");
        }
        boolean status = (boolean) rs.get("status");
        // 审核成功, 则记录审核信息
        if (status) {
            //软件工程院审批
            if ("softwareDept".equals(task.getTaskDefinitionKey())) {
            }

            //FlowBaseInfo flow = new FlowBaseInfo();
            if(flow==null){
                flow = new FlowBaseInfo();
            }
            flow.setId(UUIDGenerator.uuid());
            flow.setFormProperties(flowService.getFormProperties(fpMap, request.getParameterMap()));
            flow.setStatus(FlowStatusEnum.RUNNING.getName());
            flow.setProcDefId(task.getProcessDefinitionId());
            flow.setProcInsId(task.getProcessInstanceId());
            flow.setTaskDefKey(task.getTaskDefinitionKey());
            String isOk = tProjectInvestigate.isFlag() ? "[同意]" : "[驳回]";
            if ("modifyApply".equals(task.getTaskDefinitionKey())) {
                tProjectInvestigate.setStatus(tProjectInvestigate.isFlag() ? 1 : 4);
                isOk = tProjectInvestigate.isFlag() ? "[提交]" : "[关闭]";
            } else {
                tProjectInvestigate.setStatus(tProjectInvestigate.isFlag() ? 2 : 0);
            }
            if (null != flow.getComment()) {
                flow.setComment(isOk + flow.getComment());
            } else {
                flow.setComment(isOk);
            }
            flow.setTaskName(task.getName());
            flow.setCreateBy(SecurityUtils.getLoginUser().getUserId().toString());
            ProcessInstance processInstance = runtimeService.createProcessInstanceQuery().processInstanceId(task.getProcessInstanceId()).active().singleResult();
            // 表示流程已经审批结束了
            if (processInstance == null) {
                flow.setStatus(FlowStatusEnum.ENDED.getName());
                if (!"modifyApply".equals(task.getTaskDefinitionKey())) {
                    tProjectInvestigate.setStatus(3);
                }
            }
            tProjectInvestigate.setUpdateBy(userInfo.getNickName());

            updateTProjectInvestigate(tProjectInvestigate);
            activitiBaseInfoService.addActivitiBaseInfo(flow);
        }
        return AjaxResult.success();
    }
}
