package com.gingersoft.gsa.cloud.common.utils.inputFilter;

import android.content.Context;
import android.text.InputFilter;
import android.text.Spanned;
import android.text.TextUtils;
import android.util.Log;

import com.gingersoft.gsa.cloud.common.utils.other.TextUtil;
import com.gingersoft.gsa.cloud.common.utils.toast.ToastUtils;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

import me.jessyan.autosize.utils.LogUtils;

/**
 * @author 宇航.
 * User: admin
 * Date: 2020/11/25
 * Time: 17:30
 * Use:
 */
public class InputFilterUtils {
    /**
     * 只能輸入中英文和數字
     */
    public static final Pattern chAndEn = Pattern.compile("[a-zA-Z\u4E00-\u9FA5]+");
    /**
     * 只能輸入中英文和數字
     */
    public static final Pattern chAndEnAndNum = Pattern.compile("[a-zA-Z0-9\u4E00-\u9FA5]+");
    /**
     * 只能輸入英文和數字
     */
    public static final Pattern enAndNum = Pattern.compile("[a-zA-Z0-9]+");
    /**
     * 只能輸入中英文和數字還有一些標點符號
     * Punctuation
     */
    public static final Pattern chAndEnAndNumAndPt = Pattern.compile("[-a-zA-Z0-9\u4E00-\u9FA5/,.;，。；！!?？~…&'*（）()—+:＿@￣―#_]+");
    /**
     * 只能輸入中英文和數字還有/
     * Punctuation
     */
    public static final Pattern chAndEnAndNumAndSlash = Pattern.compile("[-a-zA-Z0-9\u4E00-\u9FA5/]+");

    /**
     * emoji过滤器
     */
    public static final Pattern emoji = Pattern.compile(
            "[\ud83c\udc00-\ud83c\udfff]|[\ud83d\udc00-\ud83d\udfff]|[\u2600-\u27ff]",
            Pattern.UNICODE_CASE | Pattern.CASE_INSENSITIVE);

    public static InputFilter getChAndEnAndNumAndPtInputFilter(Context mContext) {
        return InputFilterUtils.getTypeFilter(mContext, "請輸入正確的字符", chAndEnAndNumAndPt);
    }

    public static InputFilter getTypeFilter(Context mContext, Pattern p) {
        return InputFilterUtils.getTypeFilter(mContext, "不支持輸入此內容", p);
    }

    public static InputFilter getChAndEnAndNumInputFilter(Context mContext) {
        return InputFilterUtils.getTypeFilter(mContext, "請輸入中英文和數字", chAndEnAndNum);
    }

    public static InputFilter getEnAndNumInputFilter(Context mContext) {
        return InputFilterUtils.getTypeFilter(mContext, "請輸入英文和數字", enAndNum);
    }

    public static InputFilter getEnAndChInputFilter(Context mContext) {
        return InputFilterUtils.getTypeFilter(mContext, "只允許輸入中英文", chAndEn);
    }

    public static InputFilter getLengthFilter(Context mContext, int maxLength) {
        return InputFilterUtils.getMaxLengthFilter(mContext, "最多輸入" + maxLength + "個字", maxLength);
    }

    /**
     * source 新输入的字符串
     * start  新输入的字符串起始下标，一般为0
     * end    新输入的字符串终点下标，一般为source长度-1
     * dest   输入之前文本框内容
     * dstart 原内容起始坐标，一般为0
     * dend   原内容终点坐标，一般为dest长度-1
     *
     * @param p
     * @return
     */
    private static InputFilter getTypeFilter(Context context, String tipString, Pattern p) {
        return (source, start, end, dest, dstart, dend) -> {
            Matcher m = p.matcher(source.toString());
            if (!m.matches()) {
                if (TextUtil.isNotEmptyOrNullOrUndefined(source.toString()) &&
                        TextUtil.isNotEmptyOrNullOrUndefined(tipString)) {
                    ToastUtils.show(context, tipString);
                }
                return "";
            }
            return null;
        };
    }

    /**
     * source 新输入的字符串
     * start  新输入的字符串起始下标，一般为0
     * end    新输入的字符串终点下标，一般为source长度-1
     * dest   输入之前文本框内容
     * dstart 原内容起始坐标，一般为0
     * dend   原内容终点坐标，一般为dest长度-1
     *
     * @param p
     * @return
     */
    public static InputFilter getTypeFilter(Pattern p) {
        return (source, start, end, dest, dstart, dend) -> {
            Matcher m = p.matcher(source.toString());
            if (!m.matches()) {
                return "";
            }
            return null;
        };
    }

    /**
     * 輸入最大長度限制
     *
     * @param context
     * @param tipString 超過最大長度限制的提示
     * @param maxLength 最大長度
     * @return source 當前輸入內容
     * dest 輸入框中的內容
     */
    private static InputFilter getMaxLengthFilter(Context context, String tipString, int maxLength) {
        return (source, start, end, dest, dstart, dend) -> {
            if (TextUtils.isEmpty(source)) {
                return null;
            }
            LogUtils.e("source:" + source);
            LogUtils.e("dest:" + dest);
            int inputCount = 0;
            int destCount = 0;
            inputCount = getCurLength(source);
            LogUtils.e("inputCount:" + inputCount);
            if (dest.length() != 0) {
                destCount = getCurLength(dest);
            }
            LogUtils.e("destCount:" + destCount);
            if (destCount >= maxLength) {
                return "";
            } else {
                int count = inputCount + destCount;
                if (dest.length() == 0) {
                    if (count <= maxLength) {
                        return null;
                    } else {
                        return sub(source, maxLength);
                    }
                }
                LogUtils.e("count:" + count);
                if (count > maxLength) {
                    //int min = count - maxLength;
                    int maxSubLength = maxLength - destCount;
                    return sub(source, maxSubLength);
                }
            }
            return null;
        };
    }

    private static CharSequence sub(CharSequence sq, int subLength) {
        int needLength = 0;
        int length = 0;
        for (int i = 0; i < sq.length(); i++) {
            if (sq.charAt(i) < 128) {
                length += 1;
            } else {
                length += 2;
            }
            ++needLength;
            if (subLength <= length) {
                return sq.subSequence(0, needLength);
            }
        }
        return sq;
    }

    private static int getCurLength(CharSequence s) {
        int length = 0;
        if (s == null) {
            return length;
        } else {
            for (int i = 0; i < s.length(); i++) {
                if (s.charAt(i) < 128) {
                    length += 1;
                } else {
                    length += 2;
                }
            }
        }
        return length;
    }
}

