//  Copyright (c) 2024 Huawei Technologies Co., Ltd.
//  openUBMC is licensed under Mulan PSL v2.
//  You can use this software according to the terms and conditions of the Mulan PSL v2.
//  You may obtain a copy of Mulan PSL v2 at:
//        #  http://license.coscl.org.cn/MulanPSL2
//  THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
//  EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
//  MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
//  See the Mulan PSL v2 for more details.
import { findAimClassDom } from '@/utils/utils';

/**
 * 注册一个全局自定义指令 `v-clearable`
 * 注意：必要三属性：
 * 1. v-clearable
 * 2. clearable   因为自定义的那个清空图标没有办法传点击事件，所以需要使用自带的那个清空按钮来实现点击事件，
 *    只不过把其样式设置为透明了,自定义的那个组件的鼠标事件移除了
 * 3. 使用后缀图标插槽#suffix将清空按钮组件和报错图标组件引入和使用
 *
 * 如果是表单校验，不需要做什么（因为校验失败的时候el-form-item上会自动加上is-error类名），
 * 如果不是表单，需要在el-input的外层标签根据错误情况加上is-error类名,错误的时候加
 */
export function clearDirective(app: any) {
  app.directive('clearable', {
    mounted(el: any, binding: any) {
      mountedAction(el, binding);
    },
    unmounted(el: any, binding: any) {
      if (binding.value !== false) {
        el.removeEventListener('mouseenter', mouseenterCallBack);
        el.removeEventListener('mouseleave', mouseleaveCallBack);

        const inputDom = findAimClassDom(el, 'el-input__inner');
        if (inputDom) {
          inputDom.removeEventListener('input', inputCallBack);
          inputDom.removeEventListener('focus', focusCallBack);
          inputDom.removeEventListener('blur', blurCallBack);
        }

        const suffixBox = findAimClassDom(el, 'el-input__suffix');
        if (suffixBox) {
          const innerBox = findAimClassDom(suffixBox, 'el-input__suffix-inner');
          if (innerBox) {
            innerBox.removeEventListener('click', inputCallBack);
          }
        }
      }
    },
  });
}

function mountedAction(el: any, binding: any) {
  // 默认binding.value是undefined，即v-clearable没有传参数的时候, 如果清空是可以配置的，即通过v-clearable='布尔值', 为false的时候就不进行事件绑定
  if (binding.value !== false) {
    inputCallBack(el);
    changeClassList(el, 3);

    el.addEventListener('mouseenter', () => {
      return mouseenterCallBack(el);
    });

    el.addEventListener('mouseleave', () => {
      return mouseleaveCallBack(el);
    });

    // 输入框
    const inputDom = findAimClassDom(el, 'el-input__inner');
    if (inputDom) {
      inputDom.addEventListener('input', () => {
        return inputCallBack(el);
      });

      inputDom.addEventListener('focus', () => {
        return focusCallBack(el);
      });

      inputDom.addEventListener('blur', () => {
        return blurCallBack(el);
      });
    }

    const suffixBox = findAimClassDom(el, 'el-input__suffix');
    if (suffixBox) {
      const innerBox = findAimClassDom(suffixBox, 'el-input__suffix-inner');
      if (innerBox) {
        innerBox.addEventListener('click', () => {
          return inputCallBack(el);
        });
      }
    }
  }
}

// input事件回调函数
function inputCallBack(el: any) {
  const inputDom = findAimClassDom(el, 'el-input__inner');
  if (inputDom && !inputDom.value) {
    changeClassList(el, 2);
  } else {
    changeClassList(el, 1);
  }
}

// focus事件回调函数
function focusCallBack(el: any) {
  const inputDom = findAimClassDom(el, 'el-input__inner');
  if (inputDom === document.activeElement && inputDom.value) {
    changeClassList(el, 1);
  } else {
    changeClassList(el, 2);
  }
}

// blur事件回调函数
function blurCallBack(el: any) {
  changeClassList(el, 2);
}

// mouseenter事件回调函数
function mouseenterCallBack(el: any) {
  const inputDom = findAimClassDom(el, 'el-input__inner');
  if (inputDom?.value) {
    changeClassList(el, 1);
  } else {
    changeClassList(el, 3);
  }
}

// mouseleave事件回调函数
function mouseleaveCallBack(el: any) {
  const inputDom = findAimClassDom(el, 'el-input__inner');
  if (inputDom !== document.activeElement) {
    changeClassList(el, 2);
  }
}

/**
 * 添加和移除类名
 * @param el 输入框的父div盒子
 * @param type 类型，1的时候展示清空图标，2的时候展示报错图标, 3的时候什么图标都没有
 */
function changeClassList(el: any, type: number) {
  if (type === 1) {
    el.classList.remove('show-err-icon-input');
    el.classList.add('show-clear-icon-input');
  } else if (type === 2) {
    el.classList.add('show-err-icon-input');
    el.classList.remove('show-clear-icon-input');
  } else {
    el.classList.remove('show-err-icon-input');
    el.classList.remove('show-clear-icon-input');
  }
}
