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

import cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;
import cn.iocoder.yudao.framework.mybatis.core.service.AbstractService;
import cn.iocoder.yudao.module.order.dal.dataobject.orderNumberLog.OrderNumberLogDO;
import cn.iocoder.yudao.module.order.dal.mysql.orderNumberLog.OrderNumberLogMapper;

import javax.annotation.Resource;
import java.util.Date;
import java.util.Objects;

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

/**
 * 最新编号记录 Service 实现类
 *
 * @author 郑屹
 */
@Service
@Validated
public class OrderNumberLogServiceImpl extends AbstractService<OrderNumberLogMapper, OrderNumberLogDO> implements OrderNumberLogService {

    @Resource
    private OrderNumberLogMapper orderNumberLogMapper;


    @Override
    @Cacheable(cacheNames = "jiedao:number", key = "#key + ':' + #type")
    public OrderNumberLogDO newNumberInfo(String key, Integer type) {
        return orderNumberLogMapper.selectOne(new LambdaQueryWrapper<OrderNumberLogDO>()
                .eq(OrderNumberLogDO::getNumberKey, key)
                .eq(OrderNumberLogDO::getType, type));
    }

    @Override
    @CacheEvict(cacheNames = "jiedao:number", key = "#key + ':' + #type")
    public void saveOrUpdateNewNumber(OrderNumberLogDO orderNumberLogDO, String key, Integer type, String number) {
        Date now = new Date();
        String creator = String.valueOf(SecurityFrameworkUtils.getLoginUserId());
        if (Objects.isNull(orderNumberLogDO) || Objects.isNull(orderNumberLogDO.getId())) {
            OrderNumberLogDO numberLogDO = orderNumberLogMapper.selectOne(new LambdaQueryWrapper<OrderNumberLogDO>()
                    .eq(OrderNumberLogDO::getNumberKey, key)
                    .eq(OrderNumberLogDO::getType, type));
            if (Objects.nonNull(numberLogDO)) {
                throw exception(NUMBER_CONFLICT);
            }
            orderNumberLogDO = new OrderNumberLogDO();
            orderNumberLogDO.setNumberKey(key);
            orderNumberLogDO.setType(type);
            orderNumberLogDO.setNumber(number);
            orderNumberLogDO.setCreateTime(now);
            orderNumberLogDO.setCreator(creator);
            orderNumberLogMapper.insert(orderNumberLogDO);
        } else {
            try {
                // 加乐观锁的更新
                boolean flag = this.update(new LambdaUpdateWrapper<OrderNumberLogDO>()
                        .set(OrderNumberLogDO::getNumber, number)
                        .set(OrderNumberLogDO::getVersion, orderNumberLogDO.getVersion() + 1)
                        .eq(OrderNumberLogDO::getId, orderNumberLogDO.getId())
                        .eq(OrderNumberLogDO::getVersion, orderNumberLogDO.getVersion())
                        .eq(OrderNumberLogDO::getNumberKey, key)
                        .eq(OrderNumberLogDO::getType, type)
                );
                if (!flag) {
                    throw exception(NUMBER_CONFLICT);
                }
            } catch (Exception e) {
                throw exception(NUMBER_CONFLICT);
            }

        }
    }
}
