package com.fjhx.wms.utils;

import cn.hutool.core.convert.Convert;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.text.CharSequenceUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.extra.spring.SpringUtil;
import com.baomidou.mybatisplus.extension.service.IService;
import com.fjhx.wms.service.stock.impl.StockCheckServiceImpl;
import com.fjhx.wms.service.stock.impl.StockJournalServiceImpl;
import com.obs.services.internal.ServiceException;
import lombok.Getter;

import java.util.Date;
import java.util.Map;

@Getter
public enum CodeEnum {

    //盘点
    CHECK_CODE("SC", "-yyMM-", "code", 3, StockCheckServiceImpl.class),
    //出入库入库
    SIN_CODE("SI", "-yyMM-", "code", 3, StockJournalServiceImpl.class),
    //出入库出库
    SOUT_CODE("SO", "-yyMM-", "code", 3, StockJournalServiceImpl.class);

    CodeEnum(String prefix, String dateFormat, String codeFieldName, Integer length, Class<? extends IService<?>> serviceCls) {
        this.prefix = prefix;
        this.dateFormat = dateFormat;
        this.length = length;
        this.codeFieldName = codeFieldName;
        this.service = SpringUtil.getBean(serviceCls);
    }

    // 编码前缀
    private final String prefix;
    // 编码加日期规则
    private final String dateFormat;
    // 长度
    private final Integer length;
    // 编码字段名
    private final String codeFieldName;
    // service
    private final IService<?> service;

    /**
     * 获取键值对
     */
    public String getCode() {
        String itemPrefix;

        if (ObjectUtil.isNotEmpty(dateFormat)) {
            Date date = new Date();
            String format = DateUtil.format(date, dateFormat);
            itemPrefix = prefix + format;
        } else {
            itemPrefix = prefix;
        }

        Object obj = service.query()
                .likeRight(codeFieldName, itemPrefix)
                .orderByDesc(codeFieldName)
                .last("limit 1")
                .one();

        if (obj == null) {
            return itemPrefix + autoGenericCode(length, 0);
        }

        Map<String, Object> map = Convert.toMap(String.class, Object.class, obj);

        String code = Convert.toStr(map.get(CharSequenceUtil.toCamelCase(codeFieldName)));
        Integer codeNum = Convert.toInt(code.substring(itemPrefix.length()));
        if (ObjectUtil.isEmpty(codeNum)) {
            throw new ServiceException("自定义编码与系统编码生成规则冲突，暂时无法生成编码，请联系管理员");
        }

        return itemPrefix + autoGenericCode(length, codeNum);
    }

    /**
     * 获取键值对
     */
    public String getCode(String code) {
        if (ObjectUtil.isNotEmpty(code)) {
            Long count = service.query().eq(codeFieldName, code).count();
            if (count != 0) {
                throw new ServiceException("编码已存在");
            }
            return code;
        } else {
            return getCode();
        }
    }

    /**
     * 不够位数的在前面补0，保留num的长度位数字
     */
    private static String autoGenericCode(int length, Integer codeNum) {
        return String.format("%0" + length + "d", codeNum + 1);
    }

}
