package com.ruoyi.system.service.impl;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.ruoyi.system.domain.SysSequence;
import com.ruoyi.system.enums.SequencePrefixEnum;
import com.ruoyi.system.mapper.SysSequenceMapper;
import com.ruoyi.system.service.ISysSequenceService;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

/**
 * 序号表 服务层实现
 *
 * @author 16
 */
@RequiredArgsConstructor
@Service
public class SysSequenceServiceImpl implements ISysSequenceService {

    private final SysSequenceMapper sequenceMapper;

    @Override
    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRES_NEW)
    public String generateSequence(String prefix, String fixedVal, int length) {
        // 存在中间固定值和不存在中间固定值
        if(StrUtil.isNotEmpty(fixedVal)){
            SysSequence sequence = this.selectSequence(prefix, fixedVal, length);
            Integer currentVal = sequence.getCurrentVal();
            Integer currentLength = sequence.getCurrentLength();
            String val = String.format("%0"+currentLength+"d", currentVal);
            return prefix + fixedVal + val;
        } else {
            SysSequence sequence = this.selectSequence(prefix, length);
            Integer currentVal = sequence.getCurrentVal();
            Integer currentLength = sequence.getCurrentLength();
            String val = String.format("%0"+currentLength+"d", currentVal);
            return prefix + val;
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRES_NEW)
    public String generateSequence(SequencePrefixEnum prefixEnum, String fixedVal, int length) {
        String prefix = prefixEnum.getCode();
        return this.generateSequence(prefix, fixedVal, length);
    }

    /**
     * 查询序号表信息
     *
     * @param prefix 序号前缀
     * @return 序号表信息
     */
    public SysSequence selectSequence(String prefix) {
        SysSequence sequence = sequenceMapper.selectOne(new LambdaQueryWrapper<SysSequence>()
            .eq(SysSequence::getSeqPrefix, prefix)
            .last(" limit 1 for update")
        );
        return sequence;
    }

    /**
     * 查询序号表信息
     * @param prefix 序号前缀
     * @param fixedVal 中间固定值
     * @return
     */
    public SysSequence selectSequence(String prefix, String fixedVal, int length){
        SysSequence sequence = this.selectSequence(prefix);
        if(ObjectUtil.isNotEmpty(sequence)){
            // 存在当前前缀的序号

            String fixedValOld = sequence.getFixedVal();
            // 判断当前固定值是否一致
            //  不一致：改变固定值，并将当前值改为1
            //  一致：当前值+1,
            if(!fixedValOld.equals(fixedVal)){
                sequence.setFixedVal(fixedVal);
                sequence.setCurrentLength(length);
                sequence.setCurrentVal(1);
            } else {
                int valueNew = sequence.getCurrentVal() + 1;
                sequence.setCurrentVal(valueNew);
                // 判断当前值的长度是否超过设定的长度，超过了将他调整为实际长度
                int lengthNew = String.valueOf(valueNew).length();
                if(lengthNew>length){
                    sequence.setCurrentLength(lengthNew);
                }
            }
            sequenceMapper.updateById(sequence);
            return sequence;
        } else {
            // 不存在当前前缀的序号
            SysSequence sequenceNew = SysSequence.builder()
                .seqPrefix(prefix)
                .fixedVal(fixedVal)
                .currentLength(length)
                .currentVal(1)
                .build();
            sequenceMapper.insert(sequenceNew);
            return sequenceNew;
        }
    }

    /**
     * 查询序号表信息
     * @param prefix 序号前缀
     * @return
     */
    public SysSequence selectSequence(String prefix, int length){
        SysSequence sequence = this.selectSequence(prefix);
        if(ObjectUtil.isNotEmpty(sequence)){
            int valueNew = sequence.getCurrentVal() + 1;
            sequence.setCurrentVal(valueNew);
            int lengthNew = String.valueOf(valueNew).length();
            if(lengthNew>length){
                sequence.setCurrentLength(lengthNew);
            }
            sequenceMapper.updateById(sequence);
            return sequence;
        } else {
            SysSequence sequenceNew = SysSequence.builder()
                .seqPrefix(prefix)
                .currentLength(length)
                .currentVal(1)
                .build();
            sequenceMapper.insert(sequenceNew);
            return sequenceNew;
        }
    }

}
