<template>
  <div
    style="width: 100%"
    :class="[
      isParallel ? 'Parallel-header' : 'flex',
      $slots.toolbar ? 'hasCustomToolbar' : 'noCustomToolbar',
    ]"
  >
    <div v-if="$slots.headerTop" style="margin: 5px">
      <slot name="headerTop"></slot>
    </div>
    <slot name="tableTitle" v-if="$slots.tableTitle"></slot>
    <TableTitle
      :helpMessage="titleHelpMessage"
      :title="title"
      v-if="!$slots.tableTitle && showTitle && title"
    />
    <div
      v-if="isAdvancedQuery || getBindValues.useSearchForm"
      class="items-center justify-between table-header relative flex-1"
    >
      <!-- <div :class="[advanceRight ? 'w-full' : '']"> -->
      <!-- 是否配置高级搜索 -->

      <AdvancedQuery
        v-if="isAdvancedQuery"
        :querySelectOption="querySelectOption"
        :objectId="objectId"
        @submit="handleSearchInfoChange"
      />
      <template v-else>
        <BasicForm
          ref="formRef"
          submitOnReset
          v-bind="{
            ...getFormProps,
            tableWidth,
            // formWidth,
            isSearch: true,
            // labelWidth,
            searchWidth,
          }"
          v-if="getBindValues.useSearchForm"
          :class="[advanceRight ? 'w-full !absolute top-0 left-0 z-50' : '']"
          :tableAction="tableAction"
          @register="registerForm"
          @submit="handleSearchInfoChange"
          @advanced-change="() => {}"
          :slots="formSlots"
        >
          <template #[replaceFormSlotKey(item)]="data" v-for="item in Object.keys(formSlots)">
            <slot :name="item" v-bind="data || {}"></slot>
          </template>
        </BasicForm>
      </template>
      <!-- </div> -->
    </div>
    <div
      ref="toolbarBox"
      v-if="$slots.toolbar || showTableSetting"
      :class="`${prefixCls}__toolbar float-right ${
        getBindValues.useSearchForm && !isAdvancedQuery
          ? '!flex-none'
          : isAdvancedQuery && itemLenArr?.length == 1
          ? 'flex-1'
          : ''
      }`"
    >
      <Divider
        type="vertical"
        v-if="needDivider"
        class="!h-6 !mr-4 !ml-0"
        style="border-left: 1px solid #ddd"
      />
      <div v-if="$slots.toolbar" ref="toolbarButtonBox" class="text-right flex-1"
        ><slot name="toolbar"></slot
      ></div>

      <div v-show="btnExpand" class="supshowbox" ref="supshowbox"><slot name="toolbar"></slot></div>
      <a-button class="w-30px !p-0" v-show="showBtnExpand" @click="handleExpand"
        ><BasicArrow :expand="!btnExpand" up />
      </a-button>

      <TableSetting
        ref="settingbox"
        :setting="tableSetting"
        :listPageMode="listPageMode"
        :hasLeftTree="hasLeftTree"
        :leftTreeShow="leftTreeShow"
        v-if="showTableSetting"
        @columns-change="handleColumnChange"
        @panel-show-change="handlePanelShowChange"
        @tree-show-change="handleTreeChange"
        @redo="handleRedo"
      />
    </div>
    <div v-if="$slots.headerContent">
      <slot name="headerContent"></slot>
    </div>
  </div>
</template>
<script lang="ts">
  import type { TableSetting, ColumnChangeParam, TableActionType } from '../types/table';
  import type { PropType } from 'vue';
  import {
    defineComponent,
    ref,
    computed,
    defineAsyncComponent,
    watch,
    unref,
    nextTick,
    onMounted,
    onUnmounted,
  } from 'vue';
  import { Divider } from 'ant-design-vue';
  import TableSettingComponent from './settings/index.vue';
  import TableTitle from './TableTitle.vue';
  import { useDesign } from '/@/hooks/web/useDesign';
  import { BasicArrow } from '/@/components/Basic';
  import { useRouter } from 'vue-router';
  const BasicForm = defineAsyncComponent(() => import('/@/components/Form/src/BasicForm.vue'));
  const AdvancedQuery = defineAsyncComponent(() => import('./advancedQuery/Index.vue'));
  export default defineComponent({
    name: 'BasicTableHeader',
    components: {
      Divider,
      TableTitle,
      TableSetting: TableSettingComponent,
      BasicForm,
      AdvancedQuery,
      BasicArrow,
    },
    props: {
      title: {
        type: [Function, String] as PropType<string | ((data: Recordable) => string)>,
      },
      tableSetting: {
        type: Object as PropType<TableSetting>,
      },
      showTableSetting: {
        type: Boolean,
      },
      listPageMode: {
        type: String,
      },
      hasLeftTree: Boolean,
      leftTreeShow: Boolean,
      showTitle: {
        type: Boolean,
      },
      needDivider: {
        type: Boolean,
      },
      objectId: {
        //系统表单formId,自定义表单releaseId的id值
        type: String,
        default: '',
      },
      isAdvancedQuery: {
        //是否高级查询
        type: Boolean,
        default: false,
      },
      querySelectOption: {
        //查询所有配置
        type: String,
        default: '',
      },
      titleHelpMessage: {
        type: [String, Array] as PropType<string | string[]>,
        default: '',
      },
      // toolbarWth: {
      //   type: Number,
      //   default: 0,
      // },
      tableWidth: {
        type: Number,
        default: 0,
      },
      getFormProps: {
        type: Object,
        default: () => {},
      },
      getBindValues: {
        type: Object,
        default: () => {},
      },
      tableAction: {
        type: Object as PropType<TableActionType>,
        default: () => {},
      },
      handleSearchInfoChange: {
        type: Function,
        default: () => {},
      },
      redoHeight: {
        type: Function,
        default: () => {},
      },
      getFormSlotKeys: {
        type: [String],
      },
      replaceFormSlotKey: {
        type: Function,
        default: () => {},
      },
      registerForm: {
        type: Function,
        default: () => {},
      },
      slots: Object,
    },
    emits: ['columns-change', 'panelShowChange', 'treeShowChange', 'redo'],
    setup(props, { emit }) {
      const { prefixCls } = useDesign('basic-table-header');
      const formRef = ref();
      let isParallel = ref<boolean>(false);
      const labelWidth = ref<number>(100);
      const schemas = ref([]);
      const toolbarButtonBox = ref();
      const toolbarBox = ref();
      const settingbox = ref();
      const btnExpand = ref(false);
      const showBtnExpand = ref(false);
      const btnShowIndex = ref<Array<boolean>>([]);
      const itemLenArr = ref<Array<number>>([]);
      const supshowbox = ref();
      const btnShowWidth = ref<number>(0);
      const searchWidth = ref<number>(0);
      const settingWidth = ref<number>(0);
      const { currentRoute } = useRouter();
      const randomkey = ref(unref(currentRoute).path);
      const formLenArr = ref<Array<number>>([]);

      watch(
        () => unref(currentRoute).path,
        async (val) => {
          if (val == randomkey.value) {
            if (props.isAdvancedQuery) {
              isParallel.value = false;
            } else {
              await nextTick();
              setTimeout(() => {
                const bar = unref(toolbarButtonBox);
                const btns = bar?.querySelectorAll('.ant-btn');
                computateWidth(btns);
              }, 500);
            }
          }
        },
      );
      watch(
        () => props.isAdvancedQuery,
        async (val) => {
          if (val) {
            isParallel.value = false;
            await nextTick();
            if (settingbox.value) {
              let setArr = 0;
              for (let key in settingbox.value.getSetting) {
                if (settingbox.value.getSetting[key]) {
                  setArr += 1;
                }
              }
              settingWidth.value = setArr * 46 + 16;
            }
            const bar = unref(toolbarButtonBox);
            const btns = bar?.querySelectorAll('.ant-btn');
            itemLenArr.value = [];
            let but = 0;
            btns.forEach((el) => {
              but += el.clientWidth + 18;
              itemLenArr.value.push(but);
            });
            btnShowWidth.value = props.tableWidth - 448 - 10 - settingWidth.value;
            handleResize(btns);
          }
        },
      );
      async function handleExpand() {
        btnExpand.value = !btnExpand.value;
        await nextTick();
        if (showBtnExpand.value && btnExpand.value) {
          const btns = unref(supshowbox).querySelectorAll('.ant-btn');

          btns.forEach((el, idx) => {
            if (btnShowIndex.value[idx]) {
              el.style.display = 'none';
            }
          });
        }
      }

      watch(
        () => props.getFormProps?.schemas,
        async (val) => {
          if (val && Object.keys(val).length) {
            await nextTick();
            let itemWidthTotal = 0;
            formLenArr.value = [];
            for (let index = 0; index < val.length; index++) {
              const schema = val[index];
              const labelW =
                String(schema.label).length * 15 > 120 ? 120 : String(schema.label).length * 15;
              itemWidthTotal +=
                labelW +
                10 +
                16 +
                (['RangePicker', 'Input'].includes(schema.component)
                  ? 200
                  : ['InputNumber'].includes(schema.component)
                  ? 182
                  : 180);
              formLenArr.value.push(itemWidthTotal);
            }
          }
        },
        {
          deep: true,
        },
      );
      watch(
        () => formLenArr.value,
        async (val) => {
          if (val.length > 0 && !props.isAdvancedQuery) {
            if (settingbox.value) {
              let setArr = 0;
              for (let key in settingbox.value.getSetting) {
                if (settingbox.value.getSetting[key]) {
                  setArr += 1;
                }
              }
              settingWidth.value = setArr * 46 + 16;
            }
            itemLenArr.value = [];
            btnShowIndex.value = [];
            let but = 0;
            const bar = unref(toolbarButtonBox);
            if (bar) {
              const btns = bar.querySelectorAll('.ant-btn');
              btns.forEach((el) => {
                el.style.display = 'inline-block';
                btnShowIndex.value.push(true);
                but += el.clientWidth + 18;
                itemLenArr.value.push(but);
              });
              computateWidth(btns);
            } else {
              computateWidth();
            }
          }
        },
        {
          deep: true,
        },
      );

      // watch(
      //   () => props.tableWidth,
      //   async (val) => {
      //     await nextTick();
      //     setTimeout(() => {
      //       const bar = unref(toolbarButtonBox);
      //       const btns = bar.querySelectorAll('.ant-btn');
      //       computateWidth(btns);
      //     }, 500);
      //   },
      // );

      const advanceRight = computed(() => {
        if (!formRef.value) return false;
        let advanceState = formRef.value!.advanceState;
        if (advanceState.isAdvanced && !advanceState.hideAdvanceBtn) {
          return true;
        } else {
          return false;
        }
      });
      onMounted(async () => {
        window.addEventListener('resize', resizeFunc);
        isParallel.value = false;
        await nextTick();
        setTimeout(() => {
          if (props.isAdvancedQuery) {
            if (settingbox.value) {
              let setArr = 0;
              for (let key in settingbox.value.getSetting) {
                if (settingbox.value.getSetting[key]) {
                  setArr += 1;
                }
              }
              settingWidth.value = setArr * 46 + 16;
            }
            const bar = unref(toolbarButtonBox);
            const btns = bar?.querySelectorAll('.ant-btn');
            itemLenArr.value = [];
            let but = 0;
            btns.forEach((el) => {
              but += el.clientWidth + 18;
              itemLenArr.value.push(but);
            });
            btnShowWidth.value = props.tableWidth - 448 - 10 - settingWidth.value;
            handleResize(btns);
          }
        }, 300);
      });
      onUnmounted(() => {
        window.removeEventListener('resize', resizeFunc);
      });
      function resizeFunc() {
        setTimeout(() => {
          const bar = unref(toolbarButtonBox);
          const btns = bar?.querySelectorAll('.ant-btn');
          if (props.isAdvancedQuery) {
            btnShowWidth.value = props.tableWidth - 448 - 10 - settingWidth.value;
            handleResize(btns);
          } else {
            computateWidth(btns);
          }
        }, 300);
      }
      async function computateWidth(btns?) {
        btnShowWidth.value = 0;
        let newSetW = settingWidth.value + 10;
        let itm =
          settingWidth.value +
          (props.needDivider ? 17 : 0) +
          (itemLenArr.value.length > 0
            ? itemLenArr.value[0] + 10 + (itemLenArr.value.length > 1 ? 46 : 0)
            : 0);
        let searchBtnW =
          96 +
          (props.getFormProps.showResetButton === undefined ||
          props.getFormProps.showResetButton === true
            ? 79
            : 0);
        //searchBtnW是搜索按钮区域的宽度
        let titleW = props.showTitle && props.title ? 200 : 0;
        if (itemLenArr.value.length <= 0) {
          isParallel.value = false;
          searchWidth.value = props.tableWidth - itm;
          return;
        }

        if (formLenArr.value.length == 1) {
          if (formLenArr.value[0] + searchBtnW + itm + titleW <= props.tableWidth) {
            isParallel.value = false;
            searchWidth.value = formLenArr.value[0] + searchBtnW;
            btnShowWidth.value =
              props.tableWidth - formLenArr.value[0] - searchBtnW - newSetW - titleW;
          } else {
            isParallel.value = true;
            searchWidth.value = props.tableWidth;
            btnShowWidth.value = props.tableWidth - settingWidth.value;
          }
        } else if (formLenArr.value.length == 2) {
          if (formLenArr.value[1] + searchBtnW + itm + titleW <= props.tableWidth) {
            isParallel.value = false;
            searchWidth.value = formLenArr.value[1] + searchBtnW;
            btnShowWidth.value =
              props.tableWidth - formLenArr.value[1] - searchBtnW - newSetW - titleW;
          }
          // else if (formLenArr.value[0] + 144 + itm <= props.tableWidth) {
          //   isParallel.value = false;
          //   searchWidth.value = formLenArr.value[0] + 144;
          //   btnShowWidth.value = props.tableWidth - formLenArr.value[0] - 144 - newSetW;
          // }
          else {
            isParallel.value = true;
            searchWidth.value = props.tableWidth;
            btnShowWidth.value = props.tableWidth - settingWidth.value;
          }
        } else if (formLenArr.value.length >= 3) {
          for (let x = formLenArr.value.length - 1; x >= 0; x--) {
            if (x == formLenArr.value.length - 1) {
              if (formLenArr.value[x] + searchBtnW + itm + titleW <= props.tableWidth) {
                isParallel.value = false;
                searchWidth.value = formLenArr.value[x] + searchBtnW;
                btnShowWidth.value =
                  props.tableWidth - formLenArr.value[x] - searchBtnW - newSetW - titleW;
                break;
              }
            } else if (x < formLenArr.value.length - 1 && x > 1) {
              if (formLenArr.value[x] + searchBtnW + 48 + itm + titleW <= props.tableWidth) {
                isParallel.value = false;
                searchWidth.value = formLenArr.value[x] + searchBtnW + 48;
                btnShowWidth.value =
                  props.tableWidth - formLenArr.value[x] - searchBtnW - 48 - newSetW - titleW;
                break;
              }
            } else {
              isParallel.value = true;
              searchWidth.value = props.tableWidth;
              btnShowWidth.value = props.tableWidth - settingWidth.value;
            }
          }
        }
        if (btns) handleResize(btns);
      }
      function handleResize(btns) {
        showBtnExpand.value = false;
        btnExpand.value = false;
        if (btns.length == 1) {
          return;
        }
        let showIdx = 0;
        for (let x = btns.length - 1; x >= 0; x--) {
          if (x == btns.length - 1) {
            if (itemLenArr.value[x] < btnShowWidth.value) {
              showIdx = x;
              break;
            }
          } else if (x < btns.length - 1 && x >= 1) {
            if (itemLenArr.value[x] + 46 < btnShowWidth.value) {
              showIdx = x;
              break;
            }
          } else {
            showIdx = x;
            break;
          }
        }
        for (let x = 0; x <= btns.length - 1; x++) {
          if (x <= showIdx) {
            btnShowIndex.value[x] = true;
            btns[x].style.display = 'inline-block';
            showBtnExpand.value = false;
          } else {
            btnShowIndex.value[x] = false;
            btns[x].style.display = 'none';
            showBtnExpand.value = true;
          }
        }
      }

      function handleColumnChange(
        data: ColumnChangeParam[],
        checkIndex: boolean,
        checkSelect: boolean,
      ) {
        emit('columns-change', data, checkIndex, checkSelect);
      }
      function handlePanelShowChange(val) {
        emit('panelShowChange', val);
      }
      function handleTreeChange(val) {
        emit('treeShowChange', val);
      }
      function handleRedo() {
        emit('redo');
      }
      const formSlots = {};
      Object.keys(props.slots).forEach((key) => {
        if (key.startsWith('form-')) {
          formSlots[key] = props.slots[key];
        }
      });

      return {
        prefixCls,
        handleColumnChange,
        advanceRight,
        formRef,
        labelWidth,
        formSlots,
        schemas,
        isParallel,
        toolbarButtonBox,
        toolbarBox,
        settingbox,
        btnExpand,
        showBtnExpand,
        btnShowIndex,
        supshowbox,
        searchWidth,
        handleExpand,
        randomkey,
        handlePanelShowChange,
        handleTreeChange,
        handleRedo,
        itemLenArr,
      };
    },
  });
</script>
<style lang="less" scoped>
  @prefix-table: ~'@{namespace}-basic-table';
  @prefix-cls: ~'@{namespace}-basic-table-header';
  @prefix-form: ~'@{namespace}-basic-form';

  .@{prefix-table} {
    .Parallel-header {
      .@{prefix-cls}__toolbar {
        width: 100%;
      }

      .table-header {
        margin-right: 0;
        margin-bottom: 0;
      }

      .supshowbox {
        top: 124px;
      }
    }
  }
  :deep(.@{prefix-cls}) {
    &__toolbar {
      display: flex;
      align-items: center;
      justify-content: flex-end;

      .ant-btn {
        border-radius: 4px;
        margin-left: 16px;
        margin-right: 0;
      }
    }
  }

  :deep(.@{prefix-form}) {
    &--compact {
      .ant-form-item {
        margin-bottom: 0 !important;

        &-control-input-content {
          display: flex;
          align-items: center;

          > div,
          .input-content-box {
            width: 100%;
          }
        }
      }

      .suspensionRow .ant-form-item {
        margin-bottom: 8px !important;
      }

      > div {
        flex-wrap: nowrap;
      }
    }
  }

  .table-header {
    :deep(.ant-form) {
      .normalRow {
        .advanceRow .ant-col,
        .basicRow .ant-col {
          flex: none;
          max-width: none;
          width: auto !important;
          padding: 0 !important;

          &.ant-form-item-label {
            width: auto !important;
            max-width: 120px;
          }

          &.ant-form-item-control {
            .ant-input-box,
            .ant-select {
              width: 180px !important;
            }

            .ant-picker-range {
              width: 200px !important;
            }
          }

          .ant-form-item-control:first-child:not([class^='ant-col-'], [class*=' ant-col-']) {
            padding-left: 16px !important;
          }
        }
      }
    }
  }

  .hasCustomToolbar {
    .table-header {
      background: #fff;
      height: 52px;
      margin-bottom: 10px;
      border-radius: 16px;
      margin-right: 10px;
    }
    .@{prefix-cls}__toolbar {
      background: #fff;
      height: 52px;
      margin-bottom: 10px;
      border-radius: 16px;
    }
  }

  .noCustomToolbar {
    background: #fff;
    height: 52px;
    margin-bottom: 10px;
    border-radius: 16px;

    .table-settings {
      margin-left: 0;
    }
  }

  :deep(.ant-popover-inner) {
    border-radius: 16px;
  }

  .supshowbox {
    max-width: 600px;
    position: absolute;
    background: #fff;
    border-radius: 16px;
    top: 60px;
    right: 108px;
    z-index: 50;
    padding: 16px 0 0 16px;
    box-shadow: 0 0 9px 0 rgb(0 0 0 / 15%);

    :deep(.ant-btn) {
      margin: 0 16px 16px 0;
    }
  }
</style>
