<template>
  <RenderButtonGroup />
</template>

<script setup lang="tsx" name="ButtonGroup">
import { ref, watch, computed, nextTick, onMounted, onUnmounted, onDeactivated, onActivated } from "vue";
import type { BreakPoint } from "@/components/Grid/interface/index";
import mittBus from "@/utils/mittBus";
import { MittEnum } from "@/enums/mittEnum";
import { cloneDeep, pick, get, omit, defaultsDeep } from "lodash-es";
import { More, ArrowDown, ArrowRight } from "@element-plus/icons-vue";
import { isArray, isFunction, isObject } from "@/utils/is";

type Props = {
  /**
   * @description 父组件id值
   */
  target?: any;
  buttons: any;
  assemblySize: string;
  data: any;
  update: any;
};

const props = withDefaults(defineProps<Props>(), {
  assemblySize: ""
});

/**
 * @description 按钮默认宽度px
 */
const itemWidth = 80;
const innerwidth = ref(0);

const skeletonItemSize = computed(() => {
  let _size = "";
  switch (props.assemblySize) {
    case "large":
      _size = "width: 90px; height: 40px";
      break;

    case "small":
      _size = "width: 64px; height: 24px";
      break;

    default:
      _size = "width: 80px; height: 32px";
      break;
  }
  return _size;
});

/**
 * 排除多余属性，仅展示需要的属性继承
 * @param data Object
 */
const omitAttr = (data: any) => {
  return omit(data, ["label", "power", "clickFunc", "slotName", "render", "disabledTextCallBack"]);
};

/**
 * @description 监听框架属性变化
 */
mittBus.on(MittEnum.FoldLayoutChange, layout => {
  console.log("ittBus.on(MittEnum.FoldLayoutChang :>> ", layout);
  nextTick(() => {
    resize({ target: { innerWidth: window.innerWidth } } as unknown as UIEvent);
  });
});

// 监听屏幕变化
const resize = (e: UIEvent) => {
  nextTick(() => {
    let width = (e.target as Window).innerWidth;
    if (props.target) {
      let _target = document.getElementById(props.target) as HTMLElement;

      _target && (width = _target.offsetWidth);
    }
    console.log("resize bg width :>> ", width);
    innerwidth.value = width;
  });
};

/**
 * @description 过滤出合法操作的按钮
 * @param data buttongroup [[],{}]
 */
const getNotLimited = (data: any) => {
  let arr = data.map((item: any) => {
    if (isArray(item)) {
      return item.filter(itm => {
        if (isFunction(itm?.limited)) {
          return !itm?.limited();
        } else {
          return !itm?.limited;
        }
      });
    } else if (isObject(item)) {
      if (isFunction(item?.limited)) {
        return !item?.limited() && item;
      } else {
        return !item?.limited && item;
      }
    }
  });
  return arr.filter((item: any) => item);
};

const getIconSlot = (item: any) => {
  // console.log("item , item.icon, typeof item.icon :>> ", JSON.stringify(item), item.icon, typeof item.icon);
  let iconRender = {};
  switch (typeof item.icon) {
    case "function":
      iconRender = { icon: () => item.icon() };
      break;
    case "string":
      iconRender = {
        icon: () => {
          return <i class={["iconfont", item.icon]} />;
        }
      };
      // delete item.icon;
      break;
    default:
      break;
  }
  return iconRender;
};

/**
 * @description el-skeleton loading
 */
const isLoading = computed(() => {
  if (typeof props.data == "undefined") {
    return false;
  } else {
    return Object.keys(props.data).length == 0;
  }
});

/**
 * @description 按钮组渲染
 */
const buttonItemRender = (item: any) => {
  // console.log("buttonItemRender item :>> ", item);
  if (!item) return;
  let iconRender = getIconSlot(item);
  let _item = cloneDeep(item);
  typeof _item.icon == "string" && delete _item.icon;

  // let btnDisabledTxt: any = computed(() => {
  //   return props.data && item.disabledTextCallBack && item.disabledTextCallBack(props.data);
  // });
  let btnDisabledTxt = props.data && item.disabledTextCallBack ? item.disabledTextCallBack(props.data) : "";
  let _loading = isFunction(item.loading) ? item.loading() : false;

  // 排除多余属性，仅展示需要的属性继承
  let btnAttr = omitAttr(_item);

  const childrenSlot = {
    template: () => {
      return <el-skeleton-item variant="button" class="mr-4" style={skeletonItemSize} />;
    },
    default: () => {
      if (item.render) {
        return item.render(item);
      } else if (item.hasOwnProperty("disabledTextCallBack")) {
        let disabled = Boolean(btnDisabledTxt);
        return (
          <el-tooltip
            class="box-item"
            disabled={!disabled}
            effect="dark"
            content={btnDisabledTxt}
            placement="top"
            enterable={false}
            hide-after={0}
          >
            <el-button
              {...btnAttr}
              class={{ "is-disabled": disabled }}
              disabled={disabled}
              loading={_loading}
              onClick={item.clickFunc}
              v-slots={iconRender}
              size={props.assemblySize}
            >
              {item.label}
            </el-button>
          </el-tooltip>
        );
      } else {
        return (
          <el-button
            size={props.assemblySize}
            {...btnAttr}
            disabled={_loading}
            loading={_loading}
            onClick={item.clickFunc}
            v-slots={iconRender}
          >
            {item.label}
          </el-button>
        );
      }
    }
  };

  return <el-skeleton animated={true} loading={isLoading.value} class="mr-12" v-slots={childrenSlot}></el-skeleton>;
};

/**
 * @description 折叠后，按钮组渲染
 */
const buttonsMenuRender = (item: any) => {
  if (!item) return;
  // console.log("buttonsMenuRender item :>> ", item);
  let iconRender = getIconSlot(item);
  let _item = cloneDeep(item);
  typeof _item.icon == "string" && delete _item.icon;

  let btnDisabledTxt = props.data && item.disabledTextCallBack ? item.disabledTextCallBack(props.data) : "";
  // console.log("btnDisabledTxt :>> ", btnDisabledTxt.value);

  // 排除多余属性，仅展示需要的属性继承
  let btnAttr = omitAttr(_item);
  let _loading = isFunction(item?.loading) ? item.loading() : false;

  if (item.render) {
    // return item.render(item);
    return <el-dropdown-item>{item.render(item)}</el-dropdown-item>;
  } else if (item.hasOwnProperty("disabledTextCallBack")) {
    let disabled = Boolean(btnDisabledTxt);
    return (
      <el-dropdown-item {...btnAttr}>
        <el-tooltip
          class="box-item"
          disabled={!disabled}
          effect="dark"
          content={btnDisabledTxt}
          placement="right"
          enterable={false}
          hide-after={0}
        >
          <el-text
            text
            {...btnAttr}
            class={{ "is-disabled": disabled, "flx-1": true }}
            disabled={disabled || _loading}
            loading={_loading}
            onClick={item.clickFunc}
            v-slots={iconRender}
          >
            {item.label}
          </el-text>
        </el-tooltip>
      </el-dropdown-item>
    );
  } else {
    return (
      <el-dropdown-item {...btnAttr} disabled={_loading} loading={_loading} onClick={item.clickFunc} class="flx-1">
        {item.label}
      </el-dropdown-item>
    );
  }
};

const buttonGroupInnderRender = (item: any, ifMenu: boolean, placement: string) => {
  return (
    <div class="flx-center">
      <span class="flx-1">{item.label}</span>
      {!ifMenu && <el-icon>{placement == "bottom" ? <ArrowDown /> : <ArrowRight />}</el-icon>}
    </div>
  );
};

/**
 * @description 按钮组，下拉菜单渲染器
 * @param item
 * @param placement el-dropdown 菜单弹出位置
 */
const bottonDropdownRender = (item: any, placement?: string) => {
  if (!item) return;
  let _item = cloneDeep(item[0]);
  let iconRender = getIconSlot(item[0]);
  let _placement = placement ?? "bottom";
  /**
   * @description 判断是否为菜单按钮
   */
  let ifMenu = !_item.hasOwnProperty("clickFunc");
  let idx = ifMenu ? 1 : 0; // 若是菜单按钮，下拉菜单跳过第一个
  let _buttonsRd = item.map((itm: any, index: number) => {
    return index >= idx && buttonsMenuRender(itm);
  });
  _buttonsRd = _buttonsRd.filter((itm: any) => itm);

  console.log("_buttonsRd menu :>> ", _buttonsRd);
  let _dropdown = {
    dropdown: () => {
      return (
        <>
          <el-dropdown-menu>{_buttonsRd}</el-dropdown-menu>
        </>
      );
    }
  };

  typeof _item.icon == "string" && delete _item.icon;
  let _btnAttr = omitAttr(_item);
  let btnDisabledTxt = props.data && _item.disabledTextCallBack ? _item.disabledTextCallBack(props.data) : "";
  let disabled = Boolean(btnDisabledTxt);
  let _loading = isFunction(_item.loading) ? _item.loading() : false;

  const childrenSlot = {
    template: () => {
      return <el-skeleton-item variant="button" class="mr-4" style={skeletonItemSize} />;
    },
    default: () => {
      return (
        <el-dropdown v-slots={_dropdown} placement={_placement} popper-class="button-group__menu">
          {_placement == "bottom" ? (
            <span>
              <el-tooltip
                class="box-item"
                disabled={!disabled}
                effect="dark"
                content={btnDisabledTxt}
                placement="top"
                enterable={false}
                hide-after={0}
              >
                <el-button
                  {..._btnAttr}
                  class={{ "is-disabled": disabled }}
                  disabled={disabled || _loading}
                  loading={_loading}
                  size={props.assemblySize}
                  onClick={_item.clickFunc}
                  v-slots={iconRender}
                  style={{ cursor: ifMenu ? "default" : "pointer" }}
                >
                  {buttonGroupInnderRender(_item, ifMenu, _placement)}
                </el-button>
              </el-tooltip>
            </span>
          ) : (
            <span>
              <el-tooltip
                class="box-item"
                disabled={!disabled}
                effect="dark"
                content={btnDisabledTxt}
                placement="top"
                enterable={false}
                hide-after={0}
              >
                <el-text
                  {..._btnAttr}
                  class={{ "is-disabled": disabled, "menu-more__text": true }}
                  disabled={disabled || _loading}
                  loading={_loading}
                  onClick={_item.clickFunc}
                  v-slots={iconRender}
                >
                  {buttonGroupInnderRender(_item, ifMenu, _placement)}
                </el-text>
              </el-tooltip>
            </span>
          )}
        </el-dropdown>
      );
    }
  };

  return <el-skeleton animated={true} loading={isLoading.value} v-slots={childrenSlot}></el-skeleton>;
};

const RenderButtonGroup = () => {
  let btnListRender: any = [];
  let menuListRender: any = [];
  // console.log("rProp.buttons :>> ", props.buttons);

  let butttons = [];

  if (props.buttons?.length) {
    // console.log("innerwidth.value :>> ", innerwidth.value);
    let keyIndex = Math.floor(innerwidth.value / itemWidth) - 1;
    // butttons = props.buttons.filter((item: any) => !item?.limited);
    butttons = getNotLimited(props.buttons);

    // console.log("keyIndex :>> ", keyIndex, butttons.length, innerwidth.value, butttons);
    btnListRender = butttons.map((item: any, index: number) => {
      console.log("index, keyIndex, item :>> ", index, keyIndex, item);
      if (index + 1 > keyIndex) return;

      if (isArray(item)) {
        if (item.length > 1) {
          return bottonDropdownRender(item);
        } else {
          return buttonItemRender(item[0]);
        }
      } else {
        return buttonItemRender(item);
      }
    });
    btnListRender = btnListRender.filter((item: any) => item);
    // console.log("RenderButtonGroup btnListRender :>> ", btnListRender, butttons);

    let curButtons = butttons?.filter(item => !Array.isArray(item) || item.length > 0);
    if (btnListRender.length < curButtons?.length) {
      let dropdownRender = butttons.map((item: any, index: number) => {
        if (index + 1 <= keyIndex) return;

        if (isArray(item)) {
          let _menuRender = null;
          if (item.length > 1) {
            _menuRender = bottonDropdownRender(item, "right-start");
          } else {
            _menuRender = buttonsMenuRender(item[0]);
          }

          return _menuRender;
        } else {
          return buttonsMenuRender(item);
        }
      });
      dropdownRender = dropdownRender.filter((item: any) => item);

      console.log("dropdownRender :>> ", dropdownRender);
      let _buttonsRdMenu = dropdownRender.map((itm: any) => {
        return (
          <>
            <el-dropdown-item>{itm}</el-dropdown-item>
          </>
        );
      });

      let dropdowmSlot = {
        dropdown: () => {
          return (
            <>
              <el-dropdown-menu>{_buttonsRdMenu}</el-dropdown-menu>
            </>
          );
        }
      };

      let childrenSlot = {
        template: () => {
          return <el-skeleton-item variant="button" style={skeletonItemSize} />;
        },
        default: () => {
          return (
            <>
              <el-dropdown popper-class="button-group__menu-more" v-slots={dropdowmSlot} trigger="click">
                <el-button text circle icon={More}></el-button>
              </el-dropdown>
            </>
          );
        }
      };

      menuListRender.push(<el-skeleton animated loading={isLoading.value} class="mr-12" v-slots={childrenSlot}></el-skeleton>);
    }
  }

  // console.log("btnListRender :>> ", btnListRender);
  // console.log("RenderButtonGroup menuListRender :>> ", menuListRender);
  return (
    <>
      <el-button-group class="detail-menu__btn-group">{btnListRender}</el-button-group>
      {menuListRender.length > 0 && menuListRender}
    </>
  );
};

watch(
  () => props.update,
  () => {
    nextTick(() => {
      resize({ target: { innerWidth: window.innerWidth } } as unknown as UIEvent);
    });
  }
);

onMounted(() => {
  resize({ target: { innerWidth: window.innerWidth } } as unknown as UIEvent);
  window.addEventListener("resize", resize);
});
onActivated(() => {
  resize({ target: { innerWidth: window.innerWidth } } as unknown as UIEvent);
  window.addEventListener("resize", resize);
});
onUnmounted(() => {
  window.removeEventListener("resize", resize);
});
onDeactivated(() => {
  window.removeEventListener("resize", resize);
});
</script>

<style lang="scss">
.button-group__menu {
  .el-dropdown-menu__item {
    min-width: 60px;
  }
}
.button-group__menu-more {
  .el-dropdown-menu.el-dropdown-menu--default > .el-dropdown-menu__item {
    padding: 0 !important;
  }
  .menu-more__text {
    display: block;
    padding: 5px 16px;
    line-height: $space-a3;
  }
}
.detail-menu__btn-group {
  display: inline-flex;
  & > * {
    border: none;

    .el-button {
      border: none;
    }
  }
  & > .el-dropdown *:focus-visible {
    outline: unset;
  }
}
</style>
