import { DirectiveBinding } from 'vue';

// 焦点管理器模拟
class FocusManager {
    static IsFocusContinue = true;
    static SetFocus(element: HTMLElement) {
        element.focus();
    }
}

// 消息提示模拟
const showTip = (element: HTMLElement, message: string) => {
    console.log(`提示: ${message}`);
};

// 检查密码是否简单
const IsSimplepwd = (s: string, pwd: string[]): boolean => {
    const c = s.split('');

    // 密码长度小于等于3位不通过
    if (c.length <= 3) return true;

    // 密码每个字符都是一样的不通过
    const a = c[0];
    let clen = 0;
    for (let i = 0; i < c.length; i++) {
        if (c[i] === a) clen++;
    }
    if (clen === c.length) return true;

    // 每个字符的ascii码是升序不通过
    const asciiAsc = c.map(char => char.charCodeAt(0));
    clen = 0;
    for (let i = 0; i < asciiAsc.length; i++) {
        if (asciiAsc[0] + i === asciiAsc[i]) clen++;
    }
    if (clen === asciiAsc.length) return true;

    // 每个字符的ascii码是降序不通过
    const asciiDesc = c.map(char => char.charCodeAt(0));
    clen = 0;
    for (let i = 0; i < asciiDesc.length; i++) {
        if (asciiDesc[0] - i === asciiDesc[i]) clen++;
    }
    if (clen === asciiDesc.length) return true;

    // 密码和指定的任意一组字符串相同不通过
    for (let i = 0; i < pwd.length; i++) {
        if (pwd[i] === s) return true;
    }

    return false;
};

// 自定义指令
export const PasswordBoxHelper = {
    // 禁用粘贴
    forbidPaste: {
        mounted(el: HTMLInputElement) {
            el.addEventListener('paste', (e) => {
                e.preventDefault();
                showTip(el, '重复输入的要素不允许进行数据粘贴');
            });
        },
    },
    // 是否需要重复输入
    isRepeatInput: {
        mounted(el: HTMLInputElement, binding: DirectiveBinding<boolean>) {
            if (binding.value) {
                let firstInput = '';
                el.addEventListener('blur', () => {
                    if (!firstInput) {
                        firstInput = el.value.trim();
                        showTip(el, '请重新输入一遍，两次的数据必须完全相同');
                        el.value = '';
                        el.addEventListener('blur', () => {
                            if (firstInput !== el.value.trim()) {
                                showTip(el, '两次输入的数据不一致，请重新输入');
                                el.value = '';
                                firstInput = '';
                            }
                        }, { once: true });
                    }
                });
            }
        },
    },
    // 自动选择全部
    isAutoSelectedAll: {
        mounted(el: HTMLInputElement, binding: DirectiveBinding<boolean>) {
            if (binding.value) {
                el.addEventListener('focus', () => {
                    el.select();
                });
            }
        },
    },
    // 获得焦点时自动清空值
    isAutoClearVal: {
        mounted(el: HTMLInputElement, binding: DirectiveBinding<boolean>) {
            if (binding.value) {
                el.addEventListener('focus', () => {
                    el.value = '';
                });
            }
        },
    },
    // 密码最小长度检查
    minLength: {
        mounted(el: HTMLInputElement, binding: DirectiveBinding<number>) {
            el.addEventListener('blur', () => {
                const pwd = el.value.trim();
                const len = binding.value;
                if (len > pwd.length) {
                    showTip(el, `密码长度不足${len}位。`);
                    FocusManager.SetFocus(el);
                    FocusManager.IsFocusContinue = false;
                }
            });
        },
    },
    // 禁止使用简单密码
    breakSimplePassword: {
        mounted(el: HTMLInputElement, binding: DirectiveBinding<boolean>) {
            if (binding.value) {
                el.addEventListener('blur', () => {
                    const pwd = el.value;
                    if (IsSimplepwd(pwd, [])) {
                        showTip(el, '密码过于简单。');
                        FocusManager.SetFocus(el);
                        FocusManager.IsFocusContinue = false;
                    }
                });
            }
        },
    },
    // 只读
    isReadOnly: {
        mounted(el: HTMLInputElement, binding: DirectiveBinding<boolean>) {
            if (binding.value) {
                el.readOnly = true;
            }
        },
    },
};