package com.tykj.dev.misc.utils;

import com.tykj.dev.misc.exception.ApiException;
import org.springframework.http.ResponseEntity;

import java.math.BigInteger;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.Date;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

/**
 * @author dengdiyi
 * 装备序列号生成工具类
 */
public class DeviceSeqUtil {

    public static void main(String[] args) {
        List<String> list=new ArrayList<>();
//        list.add(null);
        list.add("30338343767");
        list.add("30338343768");
        list.add("30338343769");
        list.add("30338343770");
        list.add("30338343771");
        list.add("30338343772");
        list.add("生成1");
        list.add("");
        System.out.println(getContinuousSeqs(list));
        SimpleDateFormat sdf =  new SimpleDateFormat( "yyyy-MM-dd HH:mm:ss" );
        System.out.println(sdf.format(new Date()));
        System.out.println(System.currentTimeMillis());
    }

    /**
     * 根据一组序列号 组成区间
     * 先判断元素是字符+数字，还是存数字,还是其他
     *
     */
    public static String compositionInterval(List<String> seqList){
        StringBuffer stringBuffer=new StringBuffer();
        int i=0;
        String rext="^(\\w.*)(\\d.*)$";
        String rext1="^[0-9]*$";
        String rextOne = null;
        String rextTwo = null;
        String startPrefix=null;
        Integer startIndex=null;
        String prefix=null;
        Integer index=0;
        String rext1One="";
        Pattern pattern;
        Matcher matcher;
        seqList=seqList.stream().sorted(Comparator.comparing(String::toString)).collect(Collectors.toList());
        for (String seq:seqList){
            if (seq.matches(rext)){
                if (rextOne==null){
                    rextOne=seq;
                    rextTwo=seq;
                    index=toIndex(rext,seq);
                    prefix=toPrefix(rext,seq);
                    startIndex=index;
                    startPrefix=prefix;
                }else {
                    if (isSame(rext,seq,prefix,index)){
                        index++;
                        rextTwo=seq;
                    }else {
                        i=1;
                        if (index.equals(startIndex)) {
                            stringBuffer.append(",").append(rextOne);
                        }else {
                            stringBuffer.append(",").append(rextOne).append("-").append(rextTwo);
                        }
                        rextTwo=seq;
                        index=toIndex(rext,seq);
                        prefix=toPrefix(rext,seq);
                    }
                }
            }else if (seq.matches(rext1)){

            }
        }
        if (i==0){
            stringBuffer.append(",").append(rextOne).append("-").append(rextTwo);
        }
        System.out.println("-------:"+stringBuffer.toString());


        return "";
    }


    private static boolean isSame(String rext,String str,String prefix,int index){
        Pattern pattern = Pattern.compile(rext);
        Matcher matcher = pattern.matcher(str);
        if (matcher.find()){
            if (prefix.equals(matcher.group(1)) && Integer.parseInt(matcher.group(2))==index+1){
                return true;
            }else {
                return false;
            }

        }else {
            throw new ApiException(ResponseEntity.status(500).body("正则匹配失败 请查看"));
        }
    }

    private static Integer toIndex(String rext,String str){
        Pattern pattern = Pattern.compile(rext);
        Matcher matcher = pattern.matcher(str);
        if (matcher.find()){
            return Integer.parseInt(matcher.group(2));
        }else {
            throw new ApiException(ResponseEntity.status(500).body("正则匹配失败 请查看"));
        }
    }

    private static String toPrefix(String rext,String str){
        Pattern pattern = Pattern.compile(rext);
        Matcher matcher = pattern.matcher(str);
        if (matcher.find()){
            return matcher.group(1);
        }else {
            throw new ApiException(ResponseEntity.status(500).body("正则匹配失败 请查看"));
        }
    }



    /**
     * @param num 入库数量
     * @param s 序列号区间字符串
     * @return 生成的序列号列表
     * 根据序列号规则和区间字符串按顺序生成一段序列号
     */
    public static List<String> createDeviceSeqs(String s,Integer num){
        List<String> seqs = new ArrayList<>();
        if (s!=null&&s.length()>0) {
            //按,分隔多个区间
            String[] strings = s.split(",");
            if (strings.length==1){
                if (isSingle(strings[0])) {
                    String num1 = strings[0].replaceAll(".*[^\\d](?=(\\d+))", "");
                    BigInteger minSeq = new BigInteger(num1);
                    for (int i = 0; i < num; i++) {
                        StringBuffer stringBuffer = new StringBuffer();
                        //拼接数字之前的字符串
                        stringBuffer.append(s, 0, s.length() - num1.length());
                        //将数字按长度格式化，缺位补0
                        String codeFormat = "%0" + num1.length() + "d";
                        stringBuffer.append(String.format(codeFormat, minSeq));
                        seqs.add(stringBuffer.toString());
                        minSeq = minSeq.add(new BigInteger("1"));
                    }
                }
                else {
                    seqs.addAll(getIntervalSeqs(strings[0]));
                }
            }
            else {
                for (String str : strings) {
                    if (str.length() > 0) {
                        if (isSingle(str)) {
                            seqs.add(str);
                        } else {
                            seqs.addAll(getIntervalSeqs(str));
                        }
                    }
                }
            }
        }
        return seqs;
    }

    /**
     * @param s 序列号区间字符串
     * @return 查询的序列号列表
     * 根据序列号规则和区间字符串查询一段序列号
     */
    public static List<String> selectDeviceSeqs(String s){
        List<String> seqs = new ArrayList<>();
        if (s!=null&&s.length()>0) {
            //按,分隔多个区间
            String[] strings = s.split(",");
            if (strings.length==1){
                if (isSingle(strings[0])) {
                    String num1 = strings[0].replaceAll(".*[^\\d](?=(\\d+))", "");
                    BigInteger minSeq = new BigInteger(num1);
                    for (int i = 0; i < 1; i++) {
                        StringBuffer stringBuffer = new StringBuffer();
                        //拼接数字之前的字符串
                        stringBuffer.append(s, 0, s.length() - num1.length());
                        //将数字按长度格式化，缺位补0
                        String codeFormat = "%0" + num1.length() + "d";
                        stringBuffer.append(String.format(codeFormat, minSeq));
                        seqs.add(stringBuffer.toString());
                        minSeq = minSeq.add(new BigInteger("1"));
                    }
                }
                else {
                    seqs.addAll(getIntervalSeqs2(strings[0]));
                }
            }
            else {
                for (String str : strings) {
                    if (str.length() > 0) {
                        if (isSingle(str)) {
                            seqs.add(str);
                        } else {
                            seqs.addAll(getIntervalSeqs2(str));
                        }
                    }
                }
            }
        }
        return seqs;
    }

    /**
     * @param s 区间字符串
     * 判断是单个序列号还是序列号区间，若是单个序列号返回true，否则返回false
     */
    private static boolean isSingle(String s){
        return !s.contains("-");
    }

    /**
     * @param s 区间字符串
     * 根据区间字符串获取该区间序列号列表
     */
    public static List<String> getIntervalSeqs(String s){
        List<String> stringList = new ArrayList<>();
        //根据-分隔
        String[] strings = s.split("-");
        if(strings.length==2){
            //左区间字符串
            String s1 = strings[0];
            //右区间字符串
            String s2 = strings[1];
            if (s1.length()!=s2.length()){
                throw new ApiException("序列号区间前面字符位数不相同");
            }
            else {
                //获得左区间最后几位的数字
                String num1 = s1.replaceAll(".*[^\\d](?=(\\d+))", "");
                //获得右区间最后几位的数字
                String num2 = s2.replaceAll(".*[^\\d](?=(\\d+))", "");
                if (num1.length() != num2.length()){
                    throw new ApiException("序列号区间后面数字位数不相同");
                }
                else if(new BigInteger(num1).compareTo(new BigInteger(num2)) > 0){
                    throw new ApiException("序列号区间前数字大于后数字");
                }
                else {
                    BigInteger minSeq = new BigInteger(num1);
                    BigInteger maxSeq = new BigInteger(num2);
                    if (maxSeq.compareTo(minSeq) < 0){
                        throw new ApiException("前区间数字大于后区间");
                    }
                    else {
                        while (minSeq.compareTo(maxSeq)<=0){
                            StringBuffer stringBuffer = new StringBuffer();
                            //拼接数字之前的字符串
                            stringBuffer.append(s1, 0, s1.length()-num1.length());
                            //将数字按长度格式化，缺位补0
                            String codeFormat = "%0"+ num1.length() +"d";
                            stringBuffer.append(String.format(codeFormat,minSeq));
                            stringList.add(stringBuffer.toString());
                            minSeq = minSeq.add(new BigInteger("1"));
                        }
                    }
                }
            }
        }
        else {
            throw new ApiException("序列号区间包含多个-");
        }
        return stringList;
    }

    /**
     * @param s 区间字符串
     * 根据区间字符串获取该区间序列号列表(规则错误返空列表)
     */
    public static List<String> getIntervalSeqs2(String s){
        List<String> stringList = new ArrayList<>();
        //根据-分隔
        String[] strings = s.split("-");
        if(strings.length==2){
            //左区间字符串
            String s1 = strings[0];
            if (s1.equals("0")){
                s1 = s1+"0";
            }
            //右区间字符串
            String s2 = strings[1];
            if (s1.length()!=s2.length()){
//                stringList.add(String.join("-", Arrays.asList(strings)));
                return stringList;
            }
            else {
                //获得左区间最后几位的数字
                String num1 = s1.replaceAll(".*[^\\d](?=(\\d+))", "");
                //获得右区间最后几位的数字
                String num2 = s2.replaceAll(".*[^\\d](?=(\\d+))", "");
                if (num1.length() != num2.length() || new BigInteger(num1).compareTo(new BigInteger(num2))>0){
                    return stringList;
                }
                else {
                    BigInteger minSeq = new BigInteger(num1);
                    BigInteger maxSeq = new BigInteger(num2);
                    if (maxSeq.compareTo(minSeq)<0){
                        return stringList;
                    }
                    else {
                        while (minSeq.compareTo(maxSeq)<=0){
                            StringBuffer stringBuffer = new StringBuffer();
                            //拼接数字之前的字符串
                            stringBuffer.append(s1, 0, s1.length()-num1.length());
                            //将数字按长度格式化，缺位补0
                            String codeFormat = "%0"+ num1.length() +"d";
                            stringBuffer.append(String.format(codeFormat,minSeq));
                            stringList.add(stringBuffer.toString());
                            minSeq = minSeq.add(new BigInteger("1"));
                        }
                    }
                }
            }
        }
        else {
            return stringList;
        }
        return stringList;
    }


    /**
     * 将连续的序列号组合成一个字符串 为空的没有做判断
     * @param strings 序列号区间
     * @return 序列号连续组合的区间
     */
    public static List<String> getContinuousSeqs(List<String> strings){
        List<String> results = new ArrayList<>();
        if (strings.size()==1) {
            if (strings.get(0) != null && !"".equals(strings.get(0))){
                results.add(strings.get(0));
            }
        }
        else  {
            List<String> numSeqs = new ArrayList<>();
            List<String> strSeqs = new ArrayList<>();
            strings.forEach(s -> {
                if (s!=null&&!"".equals(s)) {
                    if (Character.isDigit(s.charAt(s.length() - 1))) {
                        numSeqs.add(s);
                    } else {
                        strSeqs.add(s);
                    }
                }
            });
            if (numSeqs.size()>0) {
                List<String> sortedString = numSeqs.stream().sorted(Comparator.nullsLast(String::compareTo)).collect(Collectors.toList());
                String lastSeq = sortedString.get(0);
                String first = null;
                for (int i = 1; i < sortedString.size(); i++) {
                    String index = sortedString.get(i);
                    if (getFirstString(lastSeq).equals(getFirstString(index))) {
                        BigInteger num1 = getLastNum(lastSeq);
                        BigInteger num2 = getLastNum(index);
                        if (num2.compareTo(num1.add(new BigInteger("1")))==0) {
                            if (first == null) {
                                first = lastSeq;
                            }
                            if (i == sortedString.size() - 1) {
                                StringBuffer stringBuffer = new StringBuffer();
                                stringBuffer.append(first).append("-").append(index);
                                results.add(stringBuffer.toString());
                                first = null;
                            }
                        } else {
                            if (first == null) {
                                results.add(lastSeq);
                            } else {
                                StringBuffer stringBuffer = new StringBuffer();
                                stringBuffer.append(first).append("-").append(lastSeq);
                                results.add(stringBuffer.toString());
                                first = null;
                            }
                            if (i == sortedString.size() - 1) {
                                results.add(index);
                            }
                        }
                    } else {
                        if (first == null) {
                            results.add(lastSeq);
                        } else {
                            StringBuffer stringBuffer = new StringBuffer();
                            stringBuffer.append(first).append("-").append(lastSeq);
                            results.add(stringBuffer.toString());
                            first = null;
                        }
                        if (i == sortedString.size() - 1) {
                            results.add(index);
                        }
                    }
                    lastSeq = index;
                }
            }
            if (strSeqs.size()>0){
                results.addAll(strSeqs);
            }
        }

        return results;
    }

    /**
     * 获取字符串最后的数字
     */
    private static BigInteger getLastNum(String s){
        return new BigInteger(s.replaceAll(".*[^\\d](?=(\\d+))", ""));
    }

    private static String getFirstString(String s){
        String s1 = s.replaceAll(".*[^\\d](?=(\\d+))", "");
        return s.substring(0, s.length()-s1.length());
    }

}
