package com.trade.service.serialNum.service.impl;

import cn.hutool.core.util.StrUtil;
import com.trade.common.utils.ConstantUtil;
import com.trade.common.utils.DateUtils;
import com.trade.service.trade.salesorder.constant.SaleOrderConstant;
import com.trade.service.serialNum.domain.SystemSerialNum;
import com.trade.service.serialNum.service.SerialNumberGenerator;
import com.trade.service.serialNum.service.SystemSerialNumService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Service
public class SerialNumberGeneratorImpl implements SerialNumberGenerator {

    @Autowired
    private SystemSerialNumService sysSerialNumService;

    @Override
    @Transactional
    public String nextValue(String prefixType) {
        // 获取前置字符
        String prefix = getCurrentPrefix(prefixType);
        // 获取当前数据库中对应SystemSerialNum
        SystemSerialNum sysSerialNum = sysSerialNumService.getByName(prefix);
        if (null == sysSerialNum && StrUtil.isNotEmpty(prefixType)) {
            switch (prefixType) {
                case ConstantUtil.ACCEPTANCE_SHEET_CODE:
                    sysSerialNum = sysSerialNumService.add(createInitialNo(prefix, "验收单编号"));
                    break;
                case ConstantUtil.BILL_CODE:
                    sysSerialNum = sysSerialNumService.add(createInitialNo(prefix, "结算单编号"));
                    break;
                case ConstantUtil.UNDERLYING_CODE:
                    sysSerialNum = sysSerialNumService.add(createInitialNo(prefix, "底层编号"));
                    break;
                case ConstantUtil.TRADE_PLATFORM:
                    sysSerialNum = sysSerialNumService.add(createInitialNo(prefix, "贸易平台编号"));
                    break;
                case ConstantUtil.IMPORTER_CODE:
                    sysSerialNum = sysSerialNumService.add(createInitialNo(prefix, "进口商编号"));
                    break;
                case ConstantUtil.PURCHASE_CONTRACT_CODE:
                    sysSerialNum = sysSerialNumService.add(createInitialNo(prefix, "采购合同编号"));
                    break;
                case ConstantUtil.SALES_CONTRACT_NO_PREFIX:
                    sysSerialNum = sysSerialNumService.add(createInitialNo(prefix, "销售合同编号"));
                    break;
                case ConstantUtil.PURCHASE_ORDER_NO_PREFIX:
                    sysSerialNum = sysSerialNumService.add(createInitialNo(prefix, "采购订单编号"));
                    break;
                case SaleOrderConstant.ORDER_INVOICE_NO_PREFIX:
                    sysSerialNum = sysSerialNumService.add(createInitialNo(prefix, "形式发票编号"));
                    break;
            }
        }
        if (null != sysSerialNum) {
            String curNum = "";
            switch (prefixType) {
                case ConstantUtil.ACCEPTANCE_SHEET_CODE:
                case SaleOrderConstant.ORDER_INVOICE_NO_PREFIX:
                    curNum = getCurNum(sysSerialNum, 4);
                    break;
                case ConstantUtil.BILL_CODE:
                case ConstantUtil.UNDERLYING_CODE:
                    curNum = getCurNum(sysSerialNum, 6);
                    break;
                case ConstantUtil.TRADE_PLATFORM:
                    curNum = getCurNum(sysSerialNum, 5);
                    break;
                case ConstantUtil.IMPORTER_CODE:
                    curNum = getCurNum(sysSerialNum, 3);
                    break;
                case ConstantUtil.PURCHASE_CONTRACT_CODE:
                case ConstantUtil.SALES_CONTRACT_NO_PREFIX:
                case ConstantUtil.PURCHASE_ORDER_NO_PREFIX:
                    curNum = getCurNum(sysSerialNum, 2);
                    break;
            }
            if (StrUtil.isNotEmpty(curNum)) {
                return prefix + curNum;
            }
        }
        return null;
    }

    @Override
    public String nextValue(String prefixType, String extend) {
        String prefix = prefixType + extend;
        SystemSerialNum sysSerialNum = sysSerialNumService.getByName(prefix);
        if (null == sysSerialNum && StrUtil.isNotEmpty(prefixType)) {
            switch (prefixType) {
                case ConstantUtil.PURCHASE_ORDER_NO_PREFIX:
                    sysSerialNum = sysSerialNumService.add(createInitialNo(prefix, "采购订单编号"));
                    break;
            }
        }
        if (null != sysSerialNum) {
            String curNum = "";
            switch (prefixType) {
                case ConstantUtil.PURCHASE_ORDER_NO_PREFIX:
                    curNum = getCurNum(sysSerialNum);
                    break;
            }
            if (StrUtil.isNotEmpty(curNum)) {
                return prefix + curNum;
            }
        }
        return null;
    }

    private String getCurNum(SystemSerialNum sysSerialNum, int suffixLength) {
        sysSerialNum.setCurNum(sysSerialNum.getCurNum() + sysSerialNum.getStep());
        sysSerialNumService.update(sysSerialNum);
        String curNum = String.valueOf(sysSerialNum.getCurNum());
        if (StrUtil.isNotEmpty(curNum) && curNum.length() > suffixLength) {
            curNum = curNum.substring(1, suffixLength);// 目前仅支持日增9999条记录，如何设计更可扩展的编号，待设计……
        } else {
            curNum = StrUtil.fillBefore(curNum, '0', suffixLength);
        }
        return curNum;
    }

    private String getCurNum(SystemSerialNum sysSerialNum) {
        sysSerialNum.setCurNum(sysSerialNum.getCurNum() + sysSerialNum.getStep());
        sysSerialNumService.update(sysSerialNum);
        return String.valueOf(sysSerialNum.getCurNum());
    }

    /**
     * 初始化编号
     *
     * @param prefix 编号名称（标识、编码）
     * @param remark 编号备注说明
     * @return
     */
    private SystemSerialNum createInitialNo(String prefix, String remark) {
        return new SystemSerialNum(prefix, 0L, 1, remark);
    }

    /**
     * 获取当前日期的编号名称
     *
     * @param prefixType
     * @return
     */
    private String getCurrentPrefix(String prefixType) {
        if (StrUtil.isNotEmpty(prefixType)) {
            switch (prefixType) {
                case ConstantUtil.PURCHASE_ORDER_NO_PREFIX:
                    return prefixType + DateUtils.dateTimeNow(DateUtils.YYYYMMDDHHMMSS);
                case ConstantUtil.SALES_CONTRACT_NO_PREFIX:
                case ConstantUtil.PURCHASE_CONTRACT_CODE:
                    return prefixType + DateUtils.dateTimeNow(DateUtils.YYYYMMDDHHMM);
                case SaleOrderConstant.ORDER_INVOICE_NO_PREFIX:
                    return prefixType + DateUtils.dateTimeNow(DateUtils.YYYY);
                default:
                    return prefixType;
            }
        }
        return "";
    }
}
