package com.cm.common.utils;

/**
 * When you feel like quitting. Think about why you started
 * 当你想要放弃的时候，想想当初你为何开始
 *
 * @ClassName: SortCodeUtil
 * @Description: 排序编码工具
 * @Author: WangGeng
 * @Date: 2020/1/14 10:21 下午
 * @Version: 1.0
 **/
public class SortCodeUtil {

    /**
     * 获取排序Code
     *
     * @param lastCode      上一个编码，获取第一个值为null即可
     * @param separator     分隔符 默认"-"
     * @param sectionLength 片段长度 默认长度3
     * @return
     */
    public static String getNextSortCode(String lastCode, String separator, int sectionLength) {
        separator = (separator == null || separator.isEmpty()) ? "-" : separator;
        sectionLength = sectionLength <= 0 ? 3 : sectionLength;
        String carryFlag = String.format("%0" + sectionLength + "d", 0);
        if (lastCode == null || lastCode.isEmpty()) {
            return carryFlag;
        }
        // 获取分段数组
        String[] sectionArray = lastCode.split(separator);
        boolean hasCarry = true;
        String resultSortCode = "";
        for (int i = sectionArray.length - 1; i >= 0; i--) {
            String section = sectionArray[i];
            if (hasCarry) {
                String nextCode = nextCode(section, sectionLength);
                if (resultSortCode.isEmpty()) {
                    resultSortCode = nextCode;
                } else {
                    resultSortCode = nextCode + separator + resultSortCode;
                }
                if (carryFlag.equals(nextCode)) {
                    hasCarry = true;
                    continue;
                }
                hasCarry = false;
            } else {
                resultSortCode = section + separator + resultSortCode;
            }
        }
        return resultSortCode;
    }

    /**
     * 下一个编码，编码大小为 36^sectionLength，最小 0*sectionLength
     *
     * @param code          编码
     * @param sectionLength 长度
     * @return
     */
    public static String nextCode(String code, int sectionLength) {
        if (code == null || code.isEmpty()) {
            return String.format("%0" + sectionLength + "d", 0);
        }
        code = code.toUpperCase();
        char[] charArray = code.toCharArray();
        boolean hasCarry = true;
        String resultCode = "";
        for (int i = charArray.length - 1; i >= 0; i--) {
            char currentChar = charArray[i];
            if (hasCarry) {
                char nextChar = nextChar(currentChar);
                resultCode = nextChar + resultCode;
                if ('0' == nextChar) {
                    hasCarry = true;
                    continue;
                }
                hasCarry = false;
            } else {
                // 没有发生进位直接相加
                resultCode = currentChar + resultCode;
            }
        }
        return resultCode;
    }

    /**
     * 下一个字符
     *
     * @param currentChar
     * @return
     */
    private static char nextChar(char currentChar) {
        char nextChar = '0';
        if ('0' == currentChar) {
            nextChar = '1';
        } else if ('1' == currentChar) {
            nextChar = '2';
        } else if ('2' == currentChar) {
            nextChar = '3';
        } else if ('3' == currentChar) {
            nextChar = '4';
        } else if ('4' == currentChar) {
            nextChar = '5';
        } else if ('5' == currentChar) {
            nextChar = '6';
        } else if ('6' == currentChar) {
            nextChar = '7';
        } else if ('7' == currentChar) {
            nextChar = '8';
        } else if ('8' == currentChar) {
            nextChar = '9';
        } else if ('9' == currentChar) {
            nextChar = 'A';
        } else if ('A' == currentChar) {
            nextChar = 'B';
        } else if ('B' == currentChar) {
            nextChar = 'C';
        } else if ('C' == currentChar) {
            nextChar = 'D';
        } else if ('D' == currentChar) {
            nextChar = 'E';
        } else if ('E' == currentChar) {
            nextChar = 'F';
        } else if ('F' == currentChar) {
            nextChar = 'G';
        } else if ('G' == currentChar) {
            nextChar = 'H';
        } else if ('H' == currentChar) {
            nextChar = 'I';
        } else if ('I' == currentChar) {
            nextChar = 'J';
        } else if ('J' == currentChar) {
            nextChar = 'K';
        } else if ('K' == currentChar) {
            nextChar = 'L';
        } else if ('L' == currentChar) {
            nextChar = 'M';
        } else if ('M' == currentChar) {
            nextChar = 'N';
        } else if ('N' == currentChar) {
            nextChar = 'O';
        } else if ('O' == currentChar) {
            nextChar = 'P';
        } else if ('P' == currentChar) {
            nextChar = 'Q';
        } else if ('Q' == currentChar) {
            nextChar = 'R';
        } else if ('R' == currentChar) {
            nextChar = 'S';
        } else if ('S' == currentChar) {
            nextChar = 'T';
        } else if ('T' == currentChar) {
            nextChar = 'U';
        } else if ('U' == currentChar) {
            nextChar = 'V';
        } else if ('V' == currentChar) {
            nextChar = 'W';
        } else if ('W' == currentChar) {
            nextChar = 'X';
        } else if ('X' == currentChar) {
            nextChar = 'Y';
        } else if ('Y' == currentChar) {
            nextChar = 'Z';
        }
        return nextChar;
    }

    /**
     * 获取排序Code
     *
     * @param nextCode      下一个编码，获取最后一个值为null即可
     * @param separator     分隔符 默认"-"
     * @param sectionLength 片段长度 默认长度3
     * @return
     */
    public static String getPrevSortCode(String nextCode, String separator, int sectionLength) {
        separator = ((separator == null) || separator.isEmpty()) ? "-" : separator;
        sectionLength = sectionLength <= 0 ? 3 : sectionLength;
        String borrowFlag = String.format("%" + sectionLength + "s", "Z").replaceAll("\\s", "Z");
        if (nextCode == null || nextCode.isEmpty()) {
            return borrowFlag;
        }
        // 获取分段数组
        String[] sectionArray = nextCode.split(separator);
        boolean hasBorrow = true;
        String resultSortCode = "";
        for (int i = sectionArray.length - 1; i >= 0; i--) {
            String section = sectionArray[i];
            if (hasBorrow) {
                String prevCode = prevCode(section, sectionLength);
                if (resultSortCode.isEmpty()) {
                    resultSortCode = prevCode;
                } else {
                    resultSortCode = prevCode + separator + resultSortCode;
                }
                if (borrowFlag.equals(prevCode)) {
                    hasBorrow = true;
                    continue;
                }
                hasBorrow = false;
            } else {
                resultSortCode = section + separator + resultSortCode;
            }
        }
        return resultSortCode;
    }

    /**
     * 上一个编码，编码大小为 36^sectionLength，最大 Z*sectionLength
     *
     * @param code          编码
     * @param sectionLength 长度
     * @return
     */
    public static String prevCode(String code, int sectionLength) {
        if (code == null || code.isEmpty()) {
            return String.format("%" + sectionLength + "s", "Z").replaceAll("\\s", "Z");
        }
        code = code.toUpperCase();
        char[] charArray = code.toCharArray();
        boolean hasBorrow = true;
        String resultCode = "";
        for (int i = charArray.length - 1; i >= 0; i--) {
            char currentChar = charArray[i];
            if (hasBorrow) {
                char prevChar = prevChar(currentChar);
                resultCode = prevChar + resultCode;
                if ('Z' == prevChar) {
                    hasBorrow = true;
                    continue;
                }
                hasBorrow = false;
            } else {
                // 没有发生借位直接
                resultCode = currentChar + resultCode;
            }
        }
        return resultCode;
    }

    /**
     * 上一个字符
     *
     * @param currentChar
     * @return
     */
    private static char prevChar(char currentChar) {
        char prevChar = 'Z';
        if ('1' == currentChar) {
            prevChar = '0';
        } else if ('2' == currentChar) {
            prevChar = '1';
        } else if ('3' == currentChar) {
            prevChar = '2';
        } else if ('4' == currentChar) {
            prevChar = '3';
        } else if ('5' == currentChar) {
            prevChar = '4';
        } else if ('6' == currentChar) {
            prevChar = '5';
        } else if ('7' == currentChar) {
            prevChar = '6';
        } else if ('8' == currentChar) {
            prevChar = '7';
        } else if ('9' == currentChar) {
            prevChar = '8';
        } else if ('A' == currentChar) {
            prevChar = '9';
        } else if ('B' == currentChar) {
            prevChar = 'A';
        } else if ('C' == currentChar) {
            prevChar = 'B';
        } else if ('D' == currentChar) {
            prevChar = 'C';
        } else if ('E' == currentChar) {
            prevChar = 'D';
        } else if ('F' == currentChar) {
            prevChar = 'E';
        } else if ('G' == currentChar) {
            prevChar = 'F';
        } else if ('H' == currentChar) {
            prevChar = 'G';
        } else if ('I' == currentChar) {
            prevChar = 'H';
        } else if ('J' == currentChar) {
            prevChar = 'I';
        } else if ('K' == currentChar) {
            prevChar = 'J';
        } else if ('L' == currentChar) {
            prevChar = 'K';
        } else if ('M' == currentChar) {
            prevChar = 'L';
        } else if ('N' == currentChar) {
            prevChar = 'M';
        } else if ('O' == currentChar) {
            prevChar = 'N';
        } else if ('P' == currentChar) {
            prevChar = 'O';
        } else if ('Q' == currentChar) {
            prevChar = 'P';
        } else if ('R' == currentChar) {
            prevChar = 'Q';
        } else if ('S' == currentChar) {
            prevChar = 'R';
        } else if ('T' == currentChar) {
            prevChar = 'S';
        } else if ('U' == currentChar) {
            prevChar = 'T';
        } else if ('V' == currentChar) {
            prevChar = 'U';
        } else if ('W' == currentChar) {
            prevChar = 'V';
        } else if ('X' == currentChar) {
            prevChar = 'W';
        } else if ('Y' == currentChar) {
            prevChar = 'X';
        } else if ('Z' == currentChar) {
            prevChar = 'Y';
        }
        return prevChar;
    }

}
