<template>
  <div ref="videoArea" class="video-preview" :style="[getAreaStyle(), getComponentStyle()]">
    <SerialNumberPosition v-if="isEnable(data.property.sn_display_mode)" :property="data.property" />

    <div v-if="'independent' === data.property.view_method" ref="videoAreaBox" class="main">
      <ul class="view-independent">
        <li v-for="(file, i) in data.file_list" :key="i" :style="getVideoItemStyle()">
          <VideoPlay
            view-size="small"
            view-method="independent"
            :file-id="file.file_id"
            :cur-video-index="curVideoIndex"
            @changeFile="changeFile"
          />
        </li>
      </ul>
    </div>
    <div v-else ref="videoAreaBox">
      <div class="view-list">
        <el-carousel
          ref="video_carousel"
          indicator-position="none"
          direction="vertical"
          :autoplay="false"
          :interval="0"
          :style="{ width: elementWidth - 248 - 32 + 'px', height: elementHeight <= 0 ? 169 : elementHeight + 'px' }"
        >
          <el-carousel-item v-for="(file, i) in data.file_list" :key="i">
            <VideoPlay
              view-size="big"
              :file-id="file.file_id"
              :cur-video-index="curVideoIndex"
              @changeFile="changeFile"
            />
          </el-carousel-item>
        </el-carousel>
        <div class="container-box" :style="{ height: elementHeight <= 0 ? 169 : elementHeight + 'px' }">
          <ul
            ref="container"
            class="view-list-bottom"
            :style="{ height: elementHeight + 'px', transform: `translateY(${translateY}px)` }"
          >
            <li v-for="(file, i) in data.file_list" :key="i" @click="handleAudioClick(i)">
              <VideoPlay view-size="small" :file-id="file.file_id" :audio-index="i" :cur-video-index="curVideoIndex" />
            </li>
          </ul>
          <button v-if="viewTopBottomBtn" class="arrow top" @click="scroll(1)">
            <i class="el-icon-arrow-up"></i>
          </button>
          <button v-if="viewTopBottomBtn" class="arrow bottom" @click="scroll(-1)">
            <i class="el-icon-arrow-down"></i>
          </button>
        </div>
      </div>
    </div>
  </div>
</template>

<script>
import { getVideoData } from '@/views/book/courseware/data/video';
import PreviewMixin from '../common/PreviewMixin';
import VideoPlay from '../common/VideoPlay.vue';
import { getRandomNumber } from '@/utils';

export default {
  name: 'VideoPreview',
  components: { VideoPlay },
  mixins: [PreviewMixin],
  inject: ['getDragStatus'],
  data() {
    return {
      data: getVideoData(),
      curVideoIndex: 0,
      elementWidth: 0,
      elementHeight: 0,
      viewTopBottomBtn: false,
      fileLen: 0,
      translateY: 0,
      elementID: '',
      isResizing: false,
      resizeObserver: null,
      isFirstLoad: true,
    };
  },
  watch: {
    data: {
      handler(val) {
        this.fileLen = val.file_list.length;
        if (this.fileLen === 0) return;
        if (this.data.property.view_method === 'list') {
          const ele = this.$refs.videoAreaBox;
          const sn_position = this.data.property.sn_position;
          // 序号在左和右补齐序号高度，去掉padding(8*2)
          if (sn_position.includes('left') || sn_position.includes('right')) {
            this.elementWidth = ele.clientWidth - 16;
            this.elementHeight = ele.clientHeight + 30;
          } else {
            this.elementWidth = ele.clientWidth;
            this.elementHeight = ele.clientHeight;
          }

          // if (ele.clientHeight <= 0) {
          //   this.elementHeight = this.data.min_height;
          // }

          const mainEle = this.$refs.videoArea;
          // 检查元素是否包含已知的类名
          mainEle.classList.forEach((className) => {
            // 排除已知的类名
            if (className !== 'audio-area') {
              // 打印另一个类名
              this.elementID = className;
            }
          });
        }

        if (this.data.property.view_method === 'independent') {
          const ele = this.$refs.videoAreaBox;
          const sn_position = this.data.property.sn_position;
          if (sn_position.includes('left') || sn_position.includes('right')) {
            this.elementWidth = ele.clientWidth - 16;
            this.elementHeight = ele.clientHeight + 30;
          } else {
            this.elementWidth = ele.clientWidth;
            this.elementHeight = ele.clientHeight;
          }

          // if (ele.clientHeight <= 0) {
          //   this.elementHeight = this.data.min_height;
          // }
        }

        this.elementHeight = Math.max(this.elementHeight, this.data.min_height);
        // this.$emit('handleHeightChange', this.id, this.elementHeight + 'px');
      },
      deep: true,
    },
    elementHeight() {
      this.isViewTopBottomBtn();
    },
    fileLen() {
      this.isViewTopBottomBtn();
    },
  },
  mounted() {
    this.$nextTick(() => {
      // const canvasElement = document.querySelector('.canvas');
      // if (!canvasElement) {
      const ele = this.$refs.videoAreaBox;
      const sn_position = this.data.property.sn_position;
      // 序号在左和右补齐序号高度，去掉padding(8*2)
      if (sn_position.includes('left') || sn_position.includes('right')) {
        this.elementWidth = ele.clientWidth - 16;
        this.elementHeight = ele.clientHeight + 30;
      } else {
        this.elementWidth = ele.clientWidth;
        this.elementHeight = ele.clientHeight;
      }

      if (ele.clientHeight <= 0) {
        this.elementHeight = this.data.min_height;
      }
      this.fileLen = this.data.file_list.length;

      // }

      this.resizeObserver = new ResizeObserver((entries) => {
        if (!this.getDragStatus() && !this.isFirstLoad) return;
        this.isResizing = true; // 标记为调整中
        const delay = this.isFirstLoad ? 500 : 0;
        setTimeout(() => {
          for (let entry of entries) {
            window.requestAnimationFrame(() => {
              const sn_position = this.data.property.sn_position;
              // 序号在上方和下方减去序号高度
              let w = entry.contentRect.width - 16;
              let h = entry.contentRect.height;
              if (sn_position.includes('top') || sn_position.includes('bottom')) {
                w = entry.contentRect.width;
                h = entry.contentRect.height - 30;
              }
              if (this.elementWidth === w) {
                this.elementHeight = h;
              } else {
                this.elementWidth = w;
              }
            });
          }
        }, delay);
        this.isFirstLoad = false;
        // 防抖：100ms 后恢复监听
        setTimeout(() => {
          this.isResizing = false;
        }, 500);
      });

      this.resizeObserver.observe(this.$el);
    });
  },
  beforeDestroy() {
    if (this.resizeObserver) {
      this.resizeObserver.disconnect();
    }
  },
  methods: {
    getVideoItemStyle() {
      if (this.data.property.view_method !== 'independent') {
        return {};
      }
      const height = this.elementHeight > 0 ? this.elementHeight : Number(this.data.min_height);
      const width = (height * 16) / 9;
      return {
        width: `${width}px`,
        height: `${height}px`,
        flexShrink: 0,
      };
    },
    handleAudioClick(index) {
      // 获取 Carousel 实例
      const carousel = this.$refs.video_carousel;
      // 切换到对应索引的文件
      carousel.setActiveItem(index);
      this.curVideoIndex = index;
    },
    changeFile(type) {
      // 获取 Carousel 实例
      const carousel = this.$refs.video_carousel;
      // 切换到对应索引的文件
      if (type === 'prev') {
        carousel.prev();
        this.curVideoIndex += -1;
      } else {
        carousel.next();
        this.curVideoIndex += 1;
      }
      if (this.curVideoIndex >= this.data.file_id_list.length) {
        this.curVideoIndex = 0;
      }
      if (this.curVideoIndex < 0) {
        this.curVideoIndex = this.data.file_id_list.length - 1;
      }
    },
    handleResize() {
      const width = this.$refs.videoAreaBox.clientWidth;
      if (width !== this.elementWidth) {
        this.elementWidth = width;
      }
    },
    // 是否显示上下箭头
    isViewTopBottomBtn() {
      // 计算右侧列表图片高度
      let listHeight = this.fileLen * this.data.min_height + 20 * (this.fileLen - 1);
      if (listHeight > this.elementHeight) {
        this.viewTopBottomBtn = true;
      } else {
        this.viewTopBottomBtn = false;
        this.translateY = 0;
      }
    },
    // 滚动图片列表
    scroll(direction) {
      const container = this.$refs.container;
      if (!container) return;

      // 获取实际的列表高度
      const listHeight = container.scrollHeight;
      const maxScroll = listHeight - this.elementHeight;
      // 计算每个item的实际高度（含间距）
      const itemHeight = this.fileLen > 1 ? (listHeight - 20) / (this.fileLen - 1) : listHeight;
      const step = itemHeight; // 每次滚动的距离

      // 计算滚动后的 translateY 值
      let newY = this.translateY + step * direction;
      // 检查是否超出上下边界
      if (newY > 0) {
        // 滚动到第一张图片时不再向上滚动
        this.translateY = 0;
      } else if (newY < -maxScroll) {
        // 滚动到最后一张图片时不再向下滚动
        this.translateY = -maxScroll;
      } else {
        // 在边界内时执行滚动
        this.translateY = newY;
      }
    },

    /**
     * 获取无文本内容的数据结构，用于保存为个人模板时的样式模板
     */
    getNoTextContentData() {
      let noTextContentData = JSON.parse(JSON.stringify(this.data));
      const resetFieldMap = {
        analysis_list: [],
        answer_list: [],
      };

      Object.assign(noTextContentData, resetFieldMap);

      if (noTextContentData.answer) {
        noTextContentData.answer.answer_list = [];
        noTextContentData.answer.reference_answer = '';
      }

      return noTextContentData;
    },
  },
};
</script>

<style lang="scss" scoped>
@use '@/styles/mixin.scss' as *;

.video-preview {
  @include preview-base;

  .alone-video-area {
    :deep .el-carousel {
      background-color: #d9d9d9;

      &__container {
        height: 100%;
      }
    }
  }

  .view-independent {
    display: flex;
    gap: 20px;
    width: fit-content;
    padding: 0;
    margin: 0;

    > li {
      flex-shrink: 0;
      list-style: none;

      :deep(.video-play) {
        width: 100%;
        height: 100%;
      }
    }
  }

  .main {
    position: relative;
    overflow: auto hidden !important;

    // Firefox 滚动条样式
    scrollbar-width: none; // 默认隐藏

    // 自定义滚动条样式 - 完全浮动
    &::-webkit-scrollbar {
      width: 0; // 默认宽度为 0
      height: 0;
      transition:
        width 0.3s ease,
        height 0.3s ease;
    }

    // 鼠标悬停时显示滚动条
    &:hover::-webkit-scrollbar {
      width: 8px;
      height: 8px;
    }

    &::-webkit-scrollbar-thumb {
      background-color: rgba(0, 0, 0, 50%);
      border-radius: 4px;
      transition: background-color 0.3s ease;

      &:hover {
        background-color: rgba(0, 0, 0, 70%);
      }
    }

    &::-webkit-scrollbar-track {
      background-color: transparent;
    }

    &:hover {
      scrollbar-width: thin; // 鼠标悬停时显示
      scrollbar-color: rgba(0, 0, 0, 50%) transparent;
    }
  }

  .view-list {
    display: flex;
    column-gap: 32px;

    :deep .el-carousel {
      background-color: #d9d9d9;

      &__container {
        height: 100%;
      }
    }

    .container-box {
      position: relative;
      overflow: hidden;

      .arrow {
        position: absolute;
        z-index: 10;
        width: 100%;
        height: 40px;
        text-align: center;
        background-color: rgba(0, 0, 0, 10%);
        border-radius: 0;
      }

      .arrow:hover {
        background-color: rgba(0, 0, 0, 30%);
      }

      .top {
        top: 0;
      }

      .bottom {
        bottom: 0;
      }

      .view-list-bottom {
        display: flex;
        flex-direction: column;
        row-gap: 20px;

        > li {
          width: 248px;
          height: calc(248px * 9 / 16);
        }
      }
    }
  }
}
</style>
