package cn.iocoder.yudao.module.bpm.dal.mysql.task;

import cn.hutool.core.collection.CollUtil;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
import cn.iocoder.yudao.framework.mybatis.core.query.MPJLambdaWrapperX;
import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.task.*;
import cn.iocoder.yudao.module.bpm.dal.dataobject.task.BpmProcessInstanceExtDO;
import cn.iocoder.yudao.module.bpm.dal.dataobject.task.BpmTaskExtDO;
import cn.iocoder.yudao.module.bpm.enums.task.BpmConstants;
import cn.iocoder.yudao.module.bpm.enums.task.BpmProcessInstanceResultEnum;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import org.apache.commons.lang3.StringUtils;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;

import java.util.Arrays;
import java.util.Collection;
import java.util.List;

@Mapper
public interface BpmTaskExtMapper extends BaseMapperX<BpmTaskExtDO> {

    default void updateByTaskId(BpmTaskExtDO entity) {
        update(entity, new LambdaQueryWrapper<BpmTaskExtDO>().eq(BpmTaskExtDO::getTaskId, entity.getTaskId()));
    }

    default List<BpmTaskExtDO> selectListByTaskIds(Collection<String> taskIds) {
        return selectList(BpmTaskExtDO::getTaskId, taskIds);
    }

    // TODO @海：BpmProcessInstanceResultEnum.CAN_SUB_SIGN_STATUS_LIST) 应该作为条件，mapper 不要有业务
    default List<BpmTaskExtDO> selectProcessListByTaskIds(Collection<String> taskIds) {
        return selectList(new LambdaQueryWrapperX<BpmTaskExtDO>()
                .in(BpmTaskExtDO::getTaskId, taskIds)
                .in(BpmTaskExtDO::getResult, BpmProcessInstanceResultEnum.CAN_SUB_SIGN_STATUS_LIST));
    }

    default BpmTaskExtDO selectByTaskId(String taskId) {
        return selectOne(BpmTaskExtDO::getTaskId, taskId);
    }

    default void updateBatchByTaskIdList(List<String> taskIdList, BpmTaskExtDO updateObj) {
        update(updateObj, new LambdaQueryWrapper<BpmTaskExtDO>().in(BpmTaskExtDO::getTaskId, taskIdList));
    }

    default Long selectListCount(Long userId, String processInstanceId){

        return selectCount(new LambdaQueryWrapperX<BpmTaskExtDO>().eq(BpmTaskExtDO::getAssigneeUserId, userId)
                .eq(BpmTaskExtDO::getProcessInstanceId, processInstanceId)
                .eq(BpmTaskExtDO::getResult, BpmProcessInstanceResultEnum.APPROVE.getResult()));
    }

    default List<BpmTaskExtDO> selectTask(List<String> processInstanceId, Integer result) {

        return selectList(new LambdaQueryWrapperX<BpmTaskExtDO>()
                .inIfPresent(BpmTaskExtDO::getProcessInstanceId, processInstanceId)
                .eqIfPresent(BpmTaskExtDO::getResult, result)
                .orderByDesc(BpmTaskExtDO::getCreateTime));
    }

    IPage<BpmTaskTodoPageRespVO> selectTodoTaskPage(@Param("page") IPage<BpmTaskTodoPageRespVO> page,
                                                    @Param("reqVO") BpmTaskTodoPageReqVO reqVO,
                                                    @Param("userId") Long userId);

    List<Long> selectTodoTaskDept(@Param("reqVO") BpmTaskTodoPageReqVO pageVO,
                                  @Param("userId") Long userId);

    default PageResult<BpmTaskExtDO> selectCrmPage(Long userId, BpmCrmTaskPageReqVO pageReqVO) {

        List<Integer> approveOrReject = Arrays.asList(BpmProcessInstanceResultEnum.APPROVE.getResult(), BpmProcessInstanceResultEnum.REJECT.getResult());

        return selectPage(pageReqVO, new LambdaQueryWrapperX<BpmTaskExtDO>()
                .eq(BpmTaskExtDO::getAssigneeUserId, userId)
                .likeIfPresent(BpmTaskExtDO::getProcessDefinitionId, pageReqVO.getProcessDefinitionId())
                .eq(pageReqVO.getIsTodo(), BpmTaskExtDO::getResult, BpmProcessInstanceResultEnum.PROCESS.getResult())
                .in(!pageReqVO.getIsTodo(), BpmTaskExtDO::getResult, approveOrReject));
    }

    default PageResult<BpmTaskDonePageRespVO> selectDonePage(Long userId, BpmTaskDonePageReqVO pageVO, List<Long> userIds) {

        MPJLambdaWrapperX<BpmTaskExtDO> queryWrapperX = new MPJLambdaWrapperX<BpmTaskExtDO>();
        queryWrapperX.selectAs(BpmTaskExtDO::getTaskId, BpmTaskDonePageRespVO::getId);
        queryWrapperX.selectAs(BpmTaskExtDO::getName, BpmTaskDonePageRespVO::getName);
        queryWrapperX.selectAs(BpmTaskExtDO::getEndTime, BpmTaskDonePageRespVO::getEndTime);
        queryWrapperX.selectAs(BpmTaskExtDO::getReason, BpmTaskDonePageRespVO::getReason);
        queryWrapperX.selectAs(BpmTaskExtDO::getResult, BpmTaskDonePageRespVO::getResult);
        queryWrapperX.selectAs(BpmTaskExtDO::getCreateTime, BpmTaskDonePageRespVO::getCreateTime);
        queryWrapperX.selectAs(BpmTaskExtDO::getProcessInstanceId, BpmTaskDonePageRespVO::getProcessInstanceId);
        queryWrapperX.selectAs(BpmProcessInstanceExtDO::getName, BpmTaskDonePageRespVO::getProcessInstanceName);
        queryWrapperX.selectAs(BpmProcessInstanceExtDO::getStartUserId, BpmTaskDonePageRespVO::getStartUserId);
        queryWrapperX.selectAs(BpmProcessInstanceExtDO::getProcessDefinitionId, BpmTaskDonePageRespVO::getProcessDefinitionId);
        queryWrapperX.selectAs(BpmProcessInstanceExtDO::getCcids, BpmTaskDonePageRespVO::getCcUserIds);
        queryWrapperX.selectAs(BpmProcessInstanceExtDO::getStatus, BpmTaskDonePageRespVO::getStatus ) ;

        queryWrapperX.innerJoin(BpmProcessInstanceExtDO.class, on -> on
                .eq(BpmTaskExtDO::getProcessInstanceId, BpmProcessInstanceExtDO::getProcessInstanceId)
                .in(CollUtil.isNotEmpty(userIds), BpmProcessInstanceExtDO::getStartUserId, userIds)
                .eq(StringUtils.isNotEmpty(pageVO.getName()), BpmProcessInstanceExtDO::getName, pageVO.getName()));
        queryWrapperX.likeRight(BpmProcessInstanceExtDO::getProcessDefinitionId, "oa_");
        queryWrapperX.eq(BpmTaskExtDO::getAssigneeUserId, userId);
        queryWrapperX.ne(BpmTaskExtDO::getReason, BpmConstants.AUTO_APPRAVAL);
//        queryWrapperX.ne(BpmTaskExtDO::getResult,4); //还未开始审批，发起人主动撤销的流程，不显示
        if (pageVO.getResult() != null) {
            queryWrapperX.eq(BpmTaskExtDO::getResult,pageVO.getResult());
        }
        queryWrapperX.betweenIfPresent(BpmTaskExtDO::getCreateTime, pageVO.getCreateTime());
        queryWrapperX.orderByDesc(BpmTaskExtDO::getEndTime);

        return selectJoinPage(pageVO, BpmTaskDonePageRespVO.class, queryWrapperX);
    }
}
