<template>
  <div ref="baseLoadPageRef" class="base-load-page" :style="loadPageStyle">
    <div v-if="$slots.head" class="head-fixed-box" :style="{ padding: newPadding, paddingBottom: '0px' }">
      <slot name="head"></slot>
    </div>
    <div v-loading="loadState === true" element-loading-background="rgba(255,255,255,0)" class="base-load-page-subject">
      <base-empty
        v-if="typeof loadState === 'string'"
        :style="{ padding: newPadding, background }"
        style="display: flex; flex-direction: column; align-items: center; justify-content: center; width: 100%; height: 100%"
        :description="description || ''"
        :imageSize="imageSize"
        :loadState="loadState"
        :pageLoadButton="loadState === 'null' ? [] : pageLoadButton"
      ></base-empty>
      <div
        v-else
        style="display: flex; width: 100%; height: 100%"
        :style="{ padding: newPadding, paddingTop: $slots.head ? '0px' : newPadding, paddingBottom: $slots.foot ? '0px' : newPadding }"
      >
        <slot></slot>
      </div>
    </div>
    <div v-if="$slots.foot" class="foot-fixed-box" :style="{ padding: newPadding, paddingTop: '0px' }">
      <slot name="foot"></slot>
    </div>
  </div>
</template>

<script setup lang="ts">
  import { computed, ref } from 'vue';

  const props = defineProps({
    /** 当前状态 */
    loadState: { type: [String, Boolean] as PropType<$LoadState>, default: 'null' }, // true 加载中, false 加载完成, 其他代表加载失败
    /** 组件的内边距 */
    padding: { type: Number, default: 0 },
    /** 当前状态 */
    margin: { type: Number, default: 0 },
    /** 当前状态 */
    width: { type: [String, Number] as PropType<number | string | undefined>, default: undefined },
    /** 组件的高度 */
    height: { type: [String, Number] as PropType<number | string | undefined>, default: undefined },
    /** 背景颜色 */
    background: { type: String, default: 'var(--el-bg-color)' },
    /** 异常状态下的提示文字 */
    description: { type: String, default: '' },
    /** 异常状态下的提示图标的大小 */
    imageSize: { type: Number, default: 280 },
    /** 异常状态下的自定义操作按钮 */
    pageLoadButton: { type: Array as PropType<$PageLoadButton[]>, default: () => [] },
  });
  defineSlots<{
    /** 主体内容 */
    default: () => any;
    /** 头部 */
    head?: () => any;
    /** 底部 */
    foot?: () => any;
  }>();
  const newPadding = computed(() => `${props.padding}px`);

  /** 样式 */
  const loadPageStyle = computed(() => {
    const stye = {
      'background': props.background,
      'width':
        typeof props.width === 'number' && props.width > 0 ? `${props.width}px` : typeof props.width === 'string' && props.width !== '' ? props.width : `100vw`,
      'height':
        typeof props.height === 'number' && props.height > 0
          ? `${props.height}px`
          : typeof props.height === 'string' && props.height !== ''
            ? props.height
            : '100vh',
      'margin': `${props.margin}px`,
    };
    return stye;
  });

  const baseLoadPageRef = ref<HTMLDivElement | null>(null);

  /**
   * 得到宽度
   */
  function getWidth() {
    return baseLoadPageRef.value?.clientWidth;
  }

  /**
   * 得到高度 (注意是减去padding的高度)
   */
  function getHeight() {
    return (baseLoadPageRef.value?.clientHeight || 1000) - props.padding * 2;
  }
  defineExpose({ getWidth, getHeight });
</script>

<style scoped lang="scss">
  .base-load-page {
    @include flex(column, nowrap, flex-start, flex-start, flex-start);
    box-sizing: border-box;
    overflow: hidden;
    background: $c-bg-block;
    border-radius: 8px;

    .head-fixed-box {
      width: 100%;
    }

    .base-load-page-subject {
      box-sizing: border-box;
      display: flex;
      flex: 1;
      flex-direction: column;
      justify-content: space-between;
      width: 100%;
      height: 100%;
      max-height: 100%;
      overflow: hidden;
    }

    .foot-fixed-box {
      position: relative;
      width: 100%;
    }
  }
</style>
