package cn.iocoder.yudao.module.system.service.log;

import cn.hutool.core.util.ObjectUtil;
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
import cn.iocoder.yudao.module.system.controller.admin.log.vo.RobotTaskDetailActionLogPageReqVO;
import cn.iocoder.yudao.module.system.controller.admin.log.vo.RobotTaskDetailActionLogSaveReqVO;
import cn.iocoder.yudao.module.system.dal.dataobject.log.RobotTaskDetailActionLogDO;
import cn.iocoder.yudao.module.system.dal.mysql.log.RobotTaskDetailActionLogMapper;
import cn.iocoder.yudao.module.system.enums.robot.actionlog.ActionStatusEnum;
import cn.iocoder.yudao.module.system.enums.robot.actionlog.CommandIdEnum;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import org.springframework.validation.annotation.Validated;

import java.time.LocalDateTime;
import java.util.*;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;


import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.TASK_DETAIL_ACTION_LOG_NOT_EXISTS;

/**
 * 车辆动作记录 Service 实现类
 *
 * @author 陈宾顺
 */
@Service
@Validated
public class RobotTaskDetailActionLogServiceImpl implements RobotTaskDetailActionLogService {

    @Resource
    private RobotTaskDetailActionLogMapper taskDetailActionLogMapper;


    @Override
    public Long createTaskDetailActionLog(RobotTaskDetailActionLogSaveReqVO createReqVO) {
        // 插入
        RobotTaskDetailActionLogDO taskDetailActionLog = BeanUtils.toBean(createReqVO, RobotTaskDetailActionLogDO.class);
        taskDetailActionLogMapper.insert(taskDetailActionLog);
        // 返回
        return taskDetailActionLog.getId();
    }

    @Override
    public void updateTaskDetailActionLog(RobotTaskDetailActionLogSaveReqVO updateReqVO) {
        // 校验存在
        validateTaskDetailActionLogExists(updateReqVO.getId());
        // 更新
        RobotTaskDetailActionLogDO updateObj = BeanUtils.toBean(updateReqVO, RobotTaskDetailActionLogDO.class);
        taskDetailActionLogMapper.updateById(updateObj);
    }

    @Override
    public void deleteTaskDetailActionLog(Long id) {
        // 校验存在
        validateTaskDetailActionLogExists(id);
        // 删除
        taskDetailActionLogMapper.deleteById(id);
    }

    private void validateTaskDetailActionLogExists(Long id) {
        if (taskDetailActionLogMapper.selectById(id) == null) {
            throw exception(TASK_DETAIL_ACTION_LOG_NOT_EXISTS);
        }
    }

    @Override
    public RobotTaskDetailActionLogDO getTaskDetailActionLog(Long id) {
        return taskDetailActionLogMapper.selectById(id);
    }

    @Override
    public PageResult<RobotTaskDetailActionLogDO> getTaskDetailActionLogPage(RobotTaskDetailActionLogPageReqVO pageReqVO) {
        return taskDetailActionLogMapper.selectPage(pageReqVO);
    }


    @Override
    public RobotTaskDetailActionLogDO setPreviousTaskDoneByOrderId(Long orderId) {
        List<RobotTaskDetailActionLogDO> lastLogs = taskDetailActionLogMapper.selectList(new LambdaQueryWrapperX<RobotTaskDetailActionLogDO>()
                .eq(RobotTaskDetailActionLogDO::getTaskDetailId, orderId)
                .isNull(RobotTaskDetailActionLogDO::getCommandId)
                .isNull(RobotTaskDetailActionLogDO::getEndTime));
        if (ObjectUtil.isNotEmpty(lastLogs)) {
            for (RobotTaskDetailActionLogDO lastLog : lastLogs) {
                lastLog.setEndTime(LocalDateTime.now());
                lastLog.setActionStatus(ActionStatusEnum.DONE.getType());
            }
            taskDetailActionLogMapper.updateById(lastLogs);
            return lastLogs.get(0);
        }

        return taskDetailActionLogMapper.selectOne(new LambdaQueryWrapperX<RobotTaskDetailActionLogDO>()
                .eq(RobotTaskDetailActionLogDO::getTaskDetailId, orderId)
                .orderByDesc(RobotTaskDetailActionLogDO::getCreateTime)
                .last("limit 1"));
    }

    @Override
    public RobotTaskDetailActionLogDO getLastTaskByRobotNo(String robotNo, Integer commandId) {
        return taskDetailActionLogMapper.selectOne(new LambdaQueryWrapperX<RobotTaskDetailActionLogDO>()
                .eq(RobotTaskDetailActionLogDO::getRobotNo, robotNo)
                .eqIfPresent(RobotTaskDetailActionLogDO::getCommandId, commandId)
                .orderByDesc(RobotTaskDetailActionLogDO::getCreateTime)
                .last("limit 1"));
    }

    @Override
    public List<RobotTaskDetailActionLogDO> getTaskDetailActionLogByDetailId(Long taskDetailId) {
        return taskDetailActionLogMapper.selectList(new LambdaQueryWrapperX<RobotTaskDetailActionLogDO>()
                .eq(RobotTaskDetailActionLogDO::getTaskDetailId, taskDetailId));
    }

    @Override
    public void updateTaskDetailActionLogs(List<RobotTaskDetailActionLogDO> taskDetailActionLog) {
        taskDetailActionLogMapper.updateById(taskDetailActionLog);
    }

    /**
     * 获取未统计过的任务操作日志
     * @return
     */
    @Override
    public List<RobotTaskDetailActionLogDO> getUnStatisticsDurationLog() {
        return taskDetailActionLogMapper.getUnStatisticsDurationLog();
    }

    /**
     * 查这台车最后一次分配的任务
     * @param robotNo
     * @return
     */
    @Override
    public RobotTaskDetailActionLogDO getOriginalLastTaskByRobotNo(String robotNo) {
        return taskDetailActionLogMapper.selectOne(new LambdaQueryWrapperX<RobotTaskDetailActionLogDO>()
                .eq(RobotTaskDetailActionLogDO::getOriginalRobotNo, robotNo)
                .eq(RobotTaskDetailActionLogDO::getCommandId, CommandIdEnum.TASK.getType())
                .orderByDesc(RobotTaskDetailActionLogDO::getCreateTime)
                .last("limit 1"));
    }

    @Override
    public void alreadyCounted(List<Long> logIds) {
        taskDetailActionLogMapper.alreadyCounted(logIds);
    }

    @Override
    public RobotTaskDetailActionLogDO getLastActionLogByDetailId(Long taskDetailId) {
        return taskDetailActionLogMapper.selectOne(new LambdaQueryWrapperX<RobotTaskDetailActionLogDO>()
                .eq(RobotTaskDetailActionLogDO::getTaskDetailId, taskDetailId)
                .eq(RobotTaskDetailActionLogDO::getCommandId, CommandIdEnum.TASK.getType())
                .orderByDesc(RobotTaskDetailActionLogDO::getCreateTime)
                .last("limit 1"));
    }

}