<!-- AdaptiveContainer.vue -->
<template>
  <div ref="containerRef" class="adaptive-container">
    <slot />
  </div>
</template>

<script lang="ts">
  import { defineComponent, ref, onMounted, onUnmounted } from 'vue';
  import { debounce } from 'lodash-es';
  import { useAppStore } from '/@/store/modules/app';
  import { computed } from 'vue';

  // 类型定义
  interface AdaptiveOptions {
    width?: number;
    height?: number;
    baseWidth?: number; // 设计稿基准宽度，用于REM计算
    minScale?: number; // 最小缩放比例
    maxScale?: number; // 最大缩放比例
    debounceTime?: number; // 防抖时间(ms)
  }

  interface ScaleInfo {
    widthScale: number;
    heightScale: number;
    scale: number;
  }

  export default defineComponent({
    name: 'AdaptiveContainer',
    props: {
      options: {
        type: Object as () => AdaptiveOptions,
        default: () => ({}),
      },
    },
    setup(props) {
      const appStore = useAppStore();
      const containerRef = ref<HTMLElement | null>(null);
      // const isReady = ref(false);

      // 默认配置
      const defaultOptions = ref<Required<AdaptiveOptions>>({
        width: 1920,
        height: 1080,
        baseWidth: 1920,
        minScale: 0.5,
        maxScale: 2,
        debounceTime: 100,
      });

      // 合并配置
      const config = computed(() => {
        return {
          ...defaultOptions.value,
          ...props.options,
        };
      });

      // 设计稿尺寸
      const designSize = computed(() => {
        return {
          width: config.value.width,
          height: config.value.height,
        };
      });

      /**
       * 设置REM基准值
       * @param baseSize 基准大小，默认16px
       */
      const setRem = (baseSize: number = 16): void => {
        try {
          const baseVal = baseSize / config.value.baseWidth;
          const vW = window.innerWidth;
          const rem = vW * baseVal;

          // 设置全局缩放比例（如果有需要）
          if (typeof window['$size'] !== 'number') {
            Object.defineProperty(window, '$size', {
              value: rem / 100,
              writable: true,
            });
          } else {
            window['$size'] = rem / 100;
          }

          // document.documentElement.style.fontSize = `${rem}px`;
        } catch (error) {
          console.error('设置REM失败:', error);
          // 回退方案：使用固定REM
          document.documentElement.style.fontSize = `${baseSize}px`;
        }
      };

      /**
       * 计算缩放比例
       */
      const calculateScale = (): ScaleInfo => {
        const { width: designWidth, height: designHeight } = designSize.value;
        const { innerWidth: currentWidth, innerHeight: currentHeight } = window;
        const { minScale, maxScale } = config.value;

        // 计算原始比例
        const rawWidthScale = currentWidth / designWidth;
        const rawHeightScale = currentHeight / designHeight;

        // 应用比例限制
        const widthScale = Math.max(minScale, Math.min(maxScale, rawWidthScale));
        const heightScale = Math.max(minScale, Math.min(maxScale, rawHeightScale));

        // 选择最小比例保持内容完整显示
        const scale = Math.min(widthScale, heightScale);

        return { widthScale, heightScale, scale };
      };

      /**
       * 应用缩放变换
       */
      const applyScale = (): void => {
        if (!containerRef.value) return;

        const container = containerRef.value;
        const { widthScale, heightScale } = calculateScale();

        // 应用缩放
        container.style.transform = `scale(${widthScale}, ${heightScale})`;
        container.style.transformOrigin = 'left top';

        // 更新store中的比例信息（如果需要）
        appStore.setWidthScale(widthScale);
        appStore.setHeightScale(heightScale);
      };

      /**
       * 处理窗口大小变化
       */
      const handleResize = debounce((): void => {
        // 更新缩放和REM
        applyScale();
        setRem();
      }, config.value.debounceTime);

      onMounted(async () => {
        // 生命周期
        try {
          if (!containerRef.value) {
            // if (!document.getElementById('app')) {
            throw new Error('容器元素未找到');
          }
          const container = containerRef.value;
          // const container = document.getElementById('app')!;
          defaultOptions.value.width = container.clientWidth;
          defaultOptions.value.height = container.clientHeight;

          const { width, height } = designSize.value;
          container.style.width = `${width}px`;
          container.style.height = `${height}px`;

          applyScale();
          setRem();
        } catch (error) {
          console.error('初始化自适应容器失败:', error);
        }

        window.addEventListener('resize', handleResize);
      });

      onUnmounted(() => {
        window.removeEventListener('resize', handleResize);
      });

      return {
        containerRef,
        // isReady,
      };
    },
  });
</script>

<style lang="less" scoped>
  .adaptive-container {
    // position: relative;
    // top: 0;
    // left: 0;
    overflow: hidden;
    height: 100%;
    width: 100%;
    // transform-origin: left top;
    // z-index: 0;
    // 防止缩放导致的模糊（开启GPU加速）
    backface-visibility: hidden;
    // -webkit-font-smoothing: antialiased;
  }
</style>
