//  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 { ref } from 'vue';

export const tooltipVisible = ref(false);
export const tooltipContent = ref('');
export const tooltipClass = ref('');
export const tooltipTriggerRef = ref({
  getBoundingClientRect() {
    return tooltipPosition.value;
  }
});

const tooltipPosition = ref({
  top: 0,
  left: 0,
  bottom: 0,
  right: 0
});

/**
 * 功能:给需要超出显示"..."的标签添加类名让其超出显示"...",并且添加tooltip提示信息
 * 注册一个全局自定义指令 `v-addTooltip`
 * 注意:
 * 1. 添加指令 v-addTooltip
 * 2. 添加类型修饰符,比如: v-addTooltip.elButton
 *    所有的修饰符:elButton(普通按钮)、elRadioButton(radio按钮)、elTag(tag标签)、perLine(单行文本)、td(el-table的展示元素td)
 * 3. perLine单行文本比较特殊,可以是span、div或者其他标签,需要在各自的vue文件中设置好最大宽度,
 * 4. 支持传内容,比如:v-addTooltip.elButton="{ tooltipClass: 'left-nav-tooltip' }"
 */
export function mouseEventDirective(app: any) {
  app.directive('addTooltip', {
    mounted(el: any, binding: any) {
      defaultAddTooltip(el, binding);
    }
  });
}

function defaultAddTooltip(el: any, binding: any) {
  Object.keys(binding.modifiers).forEach(key => {
    switch (key) {
      case 'elButton':
        elButtonAction(el, binding);
        break;
      case 'elRadioButton':
        elRadioButtonAction(el, binding);
        break;
      case 'elTag':
        elTagMousemoveAction(el, binding);
        break;
      case 'perLine':
        perLineMousemoveAction(el, binding);
        break;
      case 'td':
        tdAction(el, binding);
        break;
      default:
        tooltipVisible.value = false;
        break;
    }

    el.addEventListener('mouseleave', () => {
      // 隐藏tooltip以及清空tooltip上绑定的自定义类名
      tooltipVisible.value = false;
      tooltipClass.value = '';
    });
  });
}

// elButton
function elButtonAction(el: any, binding: any): any {
  const childDom: any = el?.children[0];
  childDom.classList.add('overflow-show-point-and-add-tooltip');

  el.addEventListener('mouseenter', (event: any) => {
    const w1 = el?.offsetWidth;
    const w2 = el?.children[0]?.scrollWidth;
    const content: string = el?.children[0]?.innerText;

    const paddingLeft = getDomAimStyle(el, 'padding-left') || 0;
    const paddingRight = getDomAimStyle(el, 'padding-right') || 0;

    updateTooltip({ w1, w2, paddingLeft, paddingRight, content, event, binding });
  });
}

// elRadioButton
function elRadioButtonAction(el: any, binding: any): any {
  const childDom: any = el?.children[1];
  childDom?.classList.add('overflow-show-point-and-add-tooltip');

  el.addEventListener('mouseenter', (event: any) => {
    const w1 = el?.offsetWidth;
    const w2 = el?.children[1]?.scrollWidth;
    const content: string = el?.children[1]?.innerText;

    const paddingLeft = getDomAimStyle(el, 'padding-left') || 0;
    const paddingRight = getDomAimStyle(el, 'padding-right') || 0;

    updateTooltip({ w1, w2, paddingLeft, paddingRight, content, event, binding });
  });
}

// elTag
function elTagMousemoveAction(el: any, binding: any): any {
  const childDom: any = el?.children[0];
  childDom.classList.add('overflow-show-point-and-add-tooltip');

  el.addEventListener('mouseenter', (event: any) => {
    const w1 = el?.offsetWidth;
    const w2 = el?.children[0]?.offsetWidth;
    const content: string = el?.children[0]?.innerText;

    const paddingLeft = getDomAimStyle(el, 'padding-left') || 0;
    const paddingRight = getDomAimStyle(el, 'padding-right') || 0;

    updateTooltip({ w1, w2, paddingLeft, paddingRight, content, event, binding });
  });
}

// 单行文本
function perLineMousemoveAction(el: any, binding: any): any {
  el.classList.add('overflow-show-point-and-add-tooltip');
  el.addEventListener('mouseenter', (event: any) => {
    const w1 = el.offsetWidth;
    const w2 = el.scrollWidth;
    const content: string = el?.innerText;

    if (w1 < w2 && content) {
      tooltipAddClass(binding);

      const x = event.clientX - event.offsetX + w1 / 2;
      const y = event.clientY - event.offsetY;
      tooltipContent.value = content;
      tooltipVisible.value = true;
      tooltipPosition.value = DOMRect.fromRect({
        width: 0,
        height: 0,
        x,
        y
      });
    }
  });
}

// el-table中展示数据的td标签
function tdAction(el: any, binding: any) {
  el.classList.add('overflow-show-point-and-add-tooltip');

  el.addEventListener('mouseenter', (event: any) => {
    const w1 = el.parentNode.offsetWidth;
    const w2 = el.offsetWidth;
    const content: string = el?.innerText;

    // 获取父盒子的padding
    const paddingLeft = getDomAimStyle(el.parentNode, 'padding-left') || 0;
    const paddingRight = getDomAimStyle(el.parentNode, 'padding-right') || 0;

    updateTooltip({ w1, w2, paddingLeft, paddingRight, content, event, binding });
  });

  el.addEventListener('mouseleave', () => {
    tooltipVisible.value = false;
  });
}

// 获取dom元素的样式属性
function getDomAimStyle(dom: any, key: string) {
  let style = null;
  // 火狐和谷歌的写法
  if (window.getComputedStyle) {
    style = window.getComputedStyle(dom, null);
  } else {
    // ie的写法
    style = dom.currentStyle;
  }

  if (style) {
    const res = style.getPropertyValue(key);
    if (res && res.indexOf('px') > 0) {
      return parseFloat(res);
    } else {
      return res;
    }
  } else {
    return undefined;
  }
}

// 更新tooltip的位置 和 内容
function updateTooltip(config: any) {
  const { w1, w2, paddingLeft, paddingRight, content, event, binding } = config;
  if (w1 < w2 + paddingLeft + paddingRight && content) {
    tooltipAddClass(binding);
    const x = event.clientX - event.offsetX + w1 / 2;
    const y = event.clientY - event.offsetY;
    tooltipContent.value = content;
    tooltipVisible.value = true;
    tooltipPosition.value = DOMRect.fromRect({
      width: 0,
      height: 0,
      x,
      y
    });
  }
}

// 判断是否需要绑定类名
function tooltipAddClass(binding: any) {
  if (binding.value?.tooltipClass) {
    tooltipClass.value = binding.value.tooltipClass;
  }
}