package cn.iocoder.yudao.module.order.service.orderControlLog;

import java.util.*;
import java.util.concurrent.Future;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;

import cn.hutool.core.collection.CollectionUtil;
import cn.iocoder.yudao.framework.common.util.servlet.ServletUtils;
import cn.iocoder.yudao.framework.security.core.LoginUser;
import cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.AsyncResult;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;
import cn.iocoder.yudao.framework.mybatis.core.vo.PageVO;
import cn.iocoder.yudao.framework.mybatis.core.service.AbstractService;
import cn.iocoder.yudao.module.order.vo.orderControlLog.*;
import cn.iocoder.yudao.module.order.dal.dataobject.orderControlLog.OrderControlLogDO;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.module.order.convert.orderControlLog.OrderControlLogConvert;
import cn.iocoder.yudao.module.order.dal.mysql.orderControlLog.OrderControlLogMapper;

import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.module.order.enums.ErrorCodeConstants.ORDER_CONTROL_LOG_NOT_EXISTS;

/**
 * 订单控货日志 Service 实现类
 *
 * @author 江楠
 */
@Service
@Validated
@Slf4j
public class OrderControlLogServiceImpl extends AbstractService<OrderControlLogMapper, OrderControlLogDO> implements OrderControlLogService {

    @Resource
    private OrderControlLogMapper orderControlLogMapper;

    @Override
    @Async
    public Future<Boolean> createOrderControlLog(OrderControlLogCreateReqVO createReqVO) {
        boolean success = false;
        try {
            // 插入
            OrderControlLogDO orderControlLog = OrderControlLogConvert.INSTANCE.convert(createReqVO);
            orderControlLog.setCreateTime(new Date());
            orderControlLog.setUpdateTime(new Date());
            orderControlLogMapper.insert(orderControlLog);
        } catch (Throwable throwable) {
            // 仅仅打印日志，不对外抛出。原因是，还是要保留现场数据。
            log.error("[createOrderAsyncOperateLog][记录操作日志异常，日志为 ({})]", createReqVO, throwable);
        }
        // 返回
        return new AsyncResult<>(success);
    }

    @Override
    @Async
    public Future<Boolean> batchCreateOrderControlLogs(List<OrderControlLogCreateReqVO> createReqVOList) {
        boolean success = false;
        try {
            // 插入
            List<OrderControlLogDO> orderControlLogList = OrderControlLogConvert.INSTANCE.convertCreateList(createReqVOList);
            orderControlLogList.forEach(orderControlLog -> {
                orderControlLog.setCreateTime(new Date());
                orderControlLog.setUpdateTime(new Date());
            });
            log.info("日志记录：{}", orderControlLogList);
            orderControlLogMapper.insertBatch(orderControlLogList);
        } catch (Throwable throwable) {
            // 仅仅打印日志，不对外抛出。原因是，还是要保留现场数据。
            log.error("[createOrderAsyncOperateLog][记录操作日志异常，日志为 ({})]", createReqVOList, throwable);
        }
        // 返回
        return new AsyncResult<>(success);
    }

    @Override
    public void updateOrderControlLog(OrderControlLogUpdateReqVO updateReqVO) {
        // 校验存在
        this.validateOrderControlLogExists(updateReqVO.getId());
        // 更新
        OrderControlLogDO updateObj = OrderControlLogConvert.INSTANCE.convert(updateReqVO);
        orderControlLogMapper.updateById(updateObj);
    }

    @Override
    public void deleteOrderControlLog(Long id) {
        // 校验存在
        this.validateOrderControlLogExists(id);
        // 删除
        orderControlLogMapper.deleteById(id);
    }

    private void validateOrderControlLogExists(Long id) {
        if (orderControlLogMapper.selectById(id) == null) {
            throw exception(ORDER_CONTROL_LOG_NOT_EXISTS);
        }
    }

    @Override
    public OrderControlLogDO getOrderControlLog(Long id) {
        return orderControlLogMapper.selectById(id);
    }

    @Override
    public List<OrderControlLogDO> getOrderControlLogList(Collection<Long> ids) {
        return orderControlLogMapper.selectBatchIds(ids);
    }

    @Override
    public PageResult<OrderControlLogDO> getOrderControlLogPage(OrderControlLogQueryVO query, PageVO page) {
        return orderControlLogMapper.selectPage(page, query);
    }

    @Override
    public List<OrderControlLogDO> getOrderControlLogList(OrderControlLogQueryVO query) {
        return orderControlLogMapper.selectList(query);
    }

    @Override
    public List<OrderControlLogDO> getOrderControlLogListByOrderId(Long orderId, Collection<Integer> typeKeys) {
        return orderControlLogMapper.selectList(new LambdaQueryWrapper<OrderControlLogDO>()
                .eq(OrderControlLogDO::getOrderId, orderId)
                .in(CollectionUtil.isNotEmpty(typeKeys), OrderControlLogDO::getTypeKey, typeKeys)
                .orderByDesc(OrderControlLogDO::getCreateTime));
    }
}
