package yangtz.cs.liu.campus.service.impl.auditorium;

import com.aliyun.dingtalkworkflow_1_0.models.StartProcessInstanceRequest;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.StringUtils;
import org.activiti.engine.HistoryService;
import org.activiti.engine.IdentityService;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.history.HistoricProcessInstance;
import org.activiti.engine.history.HistoricTaskInstance;
import org.activiti.engine.impl.persistence.entity.TaskEntityImpl;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Task;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import yangtz.cs.liu.activiti.service.IProcessService;
import yangtz.cs.liu.campus.domain.auditorium.SchoolAuditorium;
import yangtz.cs.liu.campus.mapper.auditorium.SchoolAuditoriumMapper;
import yangtz.cs.liu.campus.mapper.teacher.SchoolTeacherMapper;
import yangtz.cs.liu.campus.service.auditorium.ISchoolAuditoriumService;
import yangtz.cs.liu.campus.vo.auditorium.SchoolAuditoriumVo;
import yangtz.cs.liu.dingding.utils.DingProcessInstanceUtils;
import yangtz.cs.liu.dingding.vo.DingProcessInstanceVo;

import javax.annotation.Resource;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

import static com.core.constant.ProcessCommon.PENDING;
import static com.core.constant.ProcessCommon.SUSPENDSTATE_PENDING;
import static com.core.constant.ProcessVariables.LEADERSHIPID;

/**
 * 学校礼堂预约Service业务层处理
 *
 * @author ruoyi
 * @date 2023-06-14
 */
@Service
public class SchoolAuditoriumServiceImpl extends ServiceImpl<SchoolAuditoriumMapper,SchoolAuditorium> implements ISchoolAuditoriumService
{
    @Autowired
    private SchoolAuditoriumMapper schoolAuditoriumMapper;
    @Resource
    private IdentityService identityService;
    @Autowired
    private RuntimeService runtimeService;
    @Autowired
    private IProcessService processService;
    @Autowired
    private HistoryService historyService;
    @Autowired
    private DingProcessInstanceUtils instanceUtils;
    @Autowired
    private SchoolTeacherMapper schoolTeacherMapper;

    /**
     * 查询学校礼堂预约
     *
     * @param id 学校礼堂预约主键
     * @return 学校礼堂预约
     */
    @Override
    public SchoolAuditoriumVo selectSchoolAuditoriumById(Long id)
    {
        SchoolAuditoriumVo schoolAuditoriumVo = schoolAuditoriumMapper.selectSchoolAuditoriumById(id);
        return schoolAuditoriumVo;
    }

    /**
     * 查询全部学校礼堂预约列表
     *
     * @param schoolAuditorium 学校礼堂预约
     * @return 学校礼堂预约
     */
    @Override
    public List<SchoolAuditoriumVo> selectSchoolAuditoriumList(SchoolAuditoriumVo schoolAuditorium)
    {
        List<SchoolAuditoriumVo> list = schoolAuditoriumMapper.selectSchoolAuditoriumList(schoolAuditorium);
        return list;
    }

    /**
     * 查询个人学校礼堂预约列表
     * @param schoolAuditorium
     * @return
     */
    @Override
    public List<SchoolAuditoriumVo> selectSchoolAuditoriumListGr(SchoolAuditoriumVo schoolAuditorium) {
        SysUser user = SecurityUtils.getLoginUser().getUser();
        schoolAuditorium.setCreateById(user.getUserId());
        List<SchoolAuditoriumVo> list = schoolAuditoriumMapper.selectSchoolAuditoriumListGr(schoolAuditorium);
        return list;
    }

    /**
     * 新增学校礼堂预约
     *
     * @param schoolAuditorium 学校礼堂预约
     * @return 结果
     */
    @Override
    @Transactional
    public int insertSchoolAuditorium(SchoolAuditorium schoolAuditorium)
    {
        //获取当前登录用户
        SysUser user = SecurityUtils.getLoginUser().getUser();
        //设置申请人id
        schoolAuditorium.setApplyId(user.getUserId());
        //设置申请部门id
        schoolAuditorium.setApplyDeptId(user.getDeptId());
        //设置申请时间
        schoolAuditorium.setApplyTime(DateUtils.getNowDate());
        //设置状态为未提交
        schoolAuditorium.setState("0");
        //设置创建人id
        schoolAuditorium.setCreateById(user.getUserId());
        //设置创建时间
        schoolAuditorium.setCreateTime(DateUtils.getNowDate());
        return schoolAuditoriumMapper.insertSchoolAuditorium(schoolAuditorium);
    }

    /**
     * 修改学校礼堂预约
     *
     * @param schoolAuditorium 学校礼堂预约
     * @return 结果
     */
    @Override
    @Transactional
    public int updateSchoolAuditorium(SchoolAuditorium schoolAuditorium)
    {
        //获取当前登录用户
        SysUser user = SecurityUtils.getLoginUser().getUser();
        schoolAuditorium.setUpdateById(user.getUserId());
        schoolAuditorium.setUpdateTime(DateUtils.getNowDate());
        return schoolAuditoriumMapper.updateSchoolAuditorium(schoolAuditorium);
    }

    /**
     * 批量删除学校礼堂预约
     *
     * @param ids 需要删除的学校礼堂预约主键
     * @return 结果
     */
    @Override
    @Transactional
    public int deleteSchoolAuditoriumByIds(Long[] ids)
    {
        return schoolAuditoriumMapper.deleteSchoolAuditoriumByIds(ids);
    }

    /**
     * 删除学校礼堂预约信息
     *
     * @param id 学校礼堂预约主键
     * @return 结果
     */
    @Override
    @Transactional
    public int deleteSchoolAuditoriumById(Long id)
    {
        return schoolAuditoriumMapper.deleteSchoolAuditoriumById(id);
    }

    /**
     *
     * @param schoolAuditorium   业务实体
     * @param username           提交申请人 记录到底是哪个人提交了申请
     * @param key                流程标识 用于指定到底启动的是哪个流程(请假流程 办公流程 会议流程等) 这里启动的是 礼堂预约申请流程
     * @param variables          变量集合 流程中指定一些变量,这里我们主要用于动态指定审批人
     *
     *                           启动流程
     *                           1. 设置流程申请人.
     *                           2. 设置审批人.审批人因为是动态的,所以放在variables集合里面
     *                           3. 启动流程
     */
    @Override
    public int submitApply(SchoolAuditorium schoolAuditorium, String username, String key, Map<String, Object> variables) {
        String businessKey = schoolAuditorium.getId().toString();
        identityService.setAuthenticatedUserId(username);


        //分管领导
        variables.put(LEADERSHIPID,schoolAuditorium.getLeadershipId());

        ProcessInstance processInstance = runtimeService.startProcessInstanceByKey(key, businessKey, variables);
        String instanceId = processInstance.getId();

        //与我们的业务表开始建立关系
        schoolAuditorium.setInstanceId(instanceId);
        //审批中
        schoolAuditorium.setState("1");
        return schoolAuditoriumMapper.updateSchoolAuditorium(schoolAuditorium);
    }

    /**
     * 待办列表
     * @param key
     * @param entity
     * @param userId
     * @return
     */
    @Override
    public List<SchoolAuditoriumVo> findTodoTasks(String key, SchoolAuditorium entity, String userId) {
        List<SchoolAuditoriumVo> list = new ArrayList<>();
        //当前登录人待办任务集合
        List<Task> taskList = processService.findAssigneeTasks(userId, key);
        for (Task task : taskList) {
            TaskEntityImpl taskImpl = (TaskEntityImpl) task;
            //拿到当前任务id
            String processInstanceId = taskImpl.getProcessInstanceId();
            //拿到流程定义对象
            ProcessInstance processInstance = runtimeService.createProcessInstanceQuery().processInstanceId(processInstanceId).singleResult();
            //业务id(我们当时新增的时候指定了businessKey为id)
            String businessKey = processInstance.getBusinessKey();
            //通过id查询出我们业务对象
            SchoolAuditoriumVo schoolAuditorium = schoolAuditoriumMapper.selectSchoolAuditoriumById(new Long(businessKey));
            if (StringUtils.isNull(schoolAuditorium)) {
                continue;
            }
            //转vo
            SchoolAuditoriumVo schoolAuditoriumVo = new SchoolAuditoriumVo();
            BeanUtils.copyProperties(schoolAuditorium, schoolAuditoriumVo);

            schoolAuditoriumVo.setTaskId(taskImpl.getId());

            if (SUSPENDSTATE_PENDING.equals(taskImpl.getSuspensionState())) {
                //挂起
                schoolAuditoriumVo.setTaskName(PENDING);
            } else {
                schoolAuditoriumVo.setTaskName(taskImpl.getName());
            }
            list.add(schoolAuditoriumVo);

        }
        List<SchoolAuditoriumVo> resList = list.stream().sorted(Comparator.comparing(SchoolAuditoriumVo::getApplyTime).reversed()).collect(Collectors.toList());
        return resList;
    }

    /**
     * 已办列表
     * @param key
     * @param entity
     * @param userId
     * @return
     */
    @Override
    public List<SchoolAuditoriumVo> findDoneTasks(String key, SchoolAuditorium entity, String userId) {
        List<SchoolAuditoriumVo> list = new ArrayList<>();
        //当前登录人完成的历史集合
        List<HistoricTaskInstance> hisList = processService.findDoneTasks(userId, key);
        for (HistoricTaskInstance instance : hisList) {
            //流程实例key
            String processInstanceId = instance.getProcessInstanceId();
            HistoricProcessInstance processInstance = historyService.createHistoricProcessInstanceQuery()
                    .processInstanceId(processInstanceId)
                    .singleResult();
            //业务id
            String businessKey = processInstance.getBusinessKey();
            //通过id查询出我们业务对象
            SchoolAuditorium schoolAuditorium = schoolAuditoriumMapper.selectById(new Long(businessKey));
            if (StringUtils.isNull(schoolAuditorium)) {
                continue;
            }
            //转vo
            SchoolAuditoriumVo schoolAuditoriumVo = new SchoolAuditoriumVo();
            BeanUtils.copyProperties(schoolAuditorium, schoolAuditoriumVo);
            list.add(schoolAuditoriumVo);
        }
        List<SchoolAuditoriumVo> resList = list.stream().sorted(Comparator.comparing(SchoolAuditoriumVo::getApplyTime).reversed()).collect(Collectors.toList());
        return resList;
    }

    /**
     * 发送钉钉审批实例
     * @param schoolAuditorium
     * @return
     */
    @Override
    public String sendDdInstance(SchoolAuditorium schoolAuditorium) {
        //转换时间
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm");
        Date time = schoolAuditorium.getActivityTime();
        String activityTime = format.format(time);

        //获取钉钉用户id
        String ddUserIdByUserId = schoolTeacherMapper.getDdUserIdByUserId(schoolAuditorium.getApplyId());

        DingProcessInstanceVo dingProcessInstanceVo = new DingProcessInstanceVo();
        dingProcessInstanceVo.setOriginatorUserId(ddUserIdByUserId);
        dingProcessInstanceVo.setDeptId(896846044L);
        dingProcessInstanceVo.setProcessCode("PROC-DB0E3FEC-562B-4023-AA4A-CC33963D3537");
        dingProcessInstanceVo.setCcList(Arrays.asList(ddUserIdByUserId));
        dingProcessInstanceVo.setCcPosition("START");
        StartProcessInstanceRequest.StartProcessInstanceRequestTargetSelectActioners targetSelectActioners = new StartProcessInstanceRequest.StartProcessInstanceRequestTargetSelectActioners();
        targetSelectActioners.setActionerKey("manual_1918_5cd3_6444_06af");
        targetSelectActioners.setActionerUserIds(Arrays.asList(ddUserIdByUserId));
        dingProcessInstanceVo.setTargetSelectActioners(Arrays.asList(targetSelectActioners));
        StartProcessInstanceRequest.StartProcessInstanceRequestFormComponentValues componentValues1 = new StartProcessInstanceRequest.StartProcessInstanceRequestFormComponentValues();
        componentValues1.setName("活动名称");
        componentValues1.setValue(schoolAuditorium.getActivityName());
        componentValues1.setComponentType("TextField");
        StartProcessInstanceRequest.StartProcessInstanceRequestFormComponentValues componentValues2 = new StartProcessInstanceRequest.StartProcessInstanceRequestFormComponentValues();
        componentValues2.setName("活动场地");
        componentValues2.setValue(schoolAuditorium.getActivityArea());
        componentValues2.setComponentType("TextField");
        StartProcessInstanceRequest.StartProcessInstanceRequestFormComponentValues componentValues3 = new StartProcessInstanceRequest.StartProcessInstanceRequestFormComponentValues();
        componentValues3.setName("活动时间");
        componentValues3.setValue(activityTime);
        componentValues3.setComponentType("DDDateField");
        StartProcessInstanceRequest.StartProcessInstanceRequestFormComponentValues componentValues4 = new StartProcessInstanceRequest.StartProcessInstanceRequestFormComponentValues();
        componentValues4.setName("具体负责人");
        componentValues4.setValue(schoolAuditorium.getSpecificUserName());
        componentValues4.setComponentType("TextField");
        StartProcessInstanceRequest.StartProcessInstanceRequestFormComponentValues componentValues5 = new StartProcessInstanceRequest.StartProcessInstanceRequestFormComponentValues();
        componentValues5.setName("活动人数");
        componentValues5.setValue(schoolAuditorium.getActivityNumber().toString());
        componentValues5.setComponentType("NumberField");
        StartProcessInstanceRequest.StartProcessInstanceRequestFormComponentValues componentValues6 = new StartProcessInstanceRequest.StartProcessInstanceRequestFormComponentValues();
        componentValues6.setName("预计时长");
        componentValues6.setValue(schoolAuditorium.getDuration());
        componentValues6.setComponentType("TextField");
        StartProcessInstanceRequest.StartProcessInstanceRequestFormComponentValues componentValues7 = new StartProcessInstanceRequest.StartProcessInstanceRequestFormComponentValues();
        componentValues7.setName("是否彩排");
        if(schoolAuditorium.getIsRehearsal().equals("1")){
            componentValues7.setValue("是");
        }else {
            componentValues7.setValue("否");
        }
        componentValues7.setComponentType("DDSelectField");
        StartProcessInstanceRequest.StartProcessInstanceRequestFormComponentValues componentValues8 = new StartProcessInstanceRequest.StartProcessInstanceRequestFormComponentValues();
        componentValues8.setName("是否录像");
        if(schoolAuditorium.getIsVideo().equals("1")){
            componentValues8.setValue("是");
        }else {
            componentValues8.setValue("否");
        }
        componentValues8.setComponentType("DDSelectField");
        StartProcessInstanceRequest.StartProcessInstanceRequestFormComponentValues componentValues9 = new StartProcessInstanceRequest.StartProcessInstanceRequestFormComponentValues();
        componentValues9.setName("是否直播");
        if(schoolAuditorium.getIsLive().equals("1")){
            componentValues9.setValue("是");
        }else {
            componentValues9.setValue("否");
        }
        componentValues9.setComponentType("DDSelectField");
        StartProcessInstanceRequest.StartProcessInstanceRequestFormComponentValues componentValues10 = new StartProcessInstanceRequest.StartProcessInstanceRequestFormComponentValues();
        componentValues10.setName("是否需要大屏");
        if(schoolAuditorium.getIsBigScreen().equals("1")){
            componentValues10.setValue("是");
        }else {
            componentValues10.setValue("否");
        }
        componentValues10.setComponentType("DDSelectField");
        StartProcessInstanceRequest.StartProcessInstanceRequestFormComponentValues componentValues11 = new StartProcessInstanceRequest.StartProcessInstanceRequestFormComponentValues();
        componentValues11.setName("其他要求");
        componentValues11.setValue(schoolAuditorium.getOtherRequirements());
        componentValues11.setComponentType("TextField");
        dingProcessInstanceVo.setFormComponentValues(Arrays.asList(componentValues1,componentValues2,componentValues3,componentValues4,componentValues5,componentValues6,componentValues7,componentValues8,componentValues9,componentValues10,componentValues11));
        return instanceUtils.sendProcessInstance(dingProcessInstanceVo);
    }
}
















