package com.njzscloud.common.sn.support;

import cn.hutool.core.lang.Assert;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.StrUtil;
import com.njzscloud.common.core.ex.Exceptions;
import com.njzscloud.common.core.ienum.Dict;
import com.njzscloud.common.sn.contant.PadMode;
import com.njzscloud.common.sn.contant.RollbackMode;
import com.njzscloud.common.sn.contant.SnSection;
import lombok.Getter;
import lombok.Setter;
import lombok.experimental.Accessors;

import java.util.Map;

@Getter
@Setter
@Accessors(chain = true)
public class IncSectionConfig implements SectionConfig {
    private final SnSection sectionName = SnSection.ZiZeng;
    /**
     * 编码段编号
     */
    private String code;
    /**
     * 步长
     */
    private Integer step;
    /**
     * 初始数值
     */
    private Integer initialVal;
    /**
     * 填充模式
     */
    private PadMode padMode;
    /**
     * 填充值
     */
    private String padVal;
    /**
     * 填充长度
     */
    private Integer padLen;
    /**
     * 回卷模式
     */
    private RollbackMode rollbackMode;
    /**
     * 是否允许溢出
     */
    private Boolean allowOverflow;

    @Override
    public String genExample() {
        return padMode == PadMode.Zuo ? StrUtil.padPre(initialVal.toString(), padLen, padVal) :
            padMode == PadMode.You ? StrUtil.padAfter(initialVal.toString(), padLen, padVal) :
                initialVal.toString();
    }

    @Override
    public ISnSection section() {
        return new IncSection(code, step, initialVal, padMode, padVal, padLen);
    }

    @Override
    public void resolve(Map<String, Object> config) {
        code = MapUtil.getStr(config, "code");
        step = MapUtil.getInt(config, "step");
        initialVal = MapUtil.getInt(config, "initialVal");
        rollbackMode = Dict.parse(MapUtil.getStr(config, "rollback"), RollbackMode.values());
        if (rollbackMode == null) rollbackMode = RollbackMode.Wu;
        allowOverflow = MapUtil.getBool(config, "allowOverflow", Boolean.TRUE);
        padMode = Dict.parse(MapUtil.getStr(config, "padMode"), PadMode.values());
        if (padMode == null) padMode = PadMode.Wu;
        padVal = MapUtil.getStr(config, "padVal");
        padLen = MapUtil.getInt(config, "padLen");
        Assert.notBlank(code, () -> Exceptions.clierr("递增编码配置错误，未设置字段 code"));
        Assert.notNull(step, () -> Exceptions.clierr("递增编码配置错误，未设置字段 step"));
        Assert.notNull(initialVal, () -> Exceptions.clierr("递增编码配置错误，未设置字段 initialVal"));
        if (padMode != PadMode.Wu) {
            Assert.notBlank(padVal, () -> Exceptions.clierr("递增编码配置错误，未设置字段 padVal"));
            Assert.notNull(padLen, () -> Exceptions.clierr("递增编码配置错误，未设置字段 padLen"));
        }
    }
}
