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

    <div ref="audioAreaBox" class="main">
      <div v-if="'independent' === data.property.view_method">
        <ul v-if="data.property.style_mode == 'big'" class="view-list">
          <li v-for="(file, i) in data.file_list" :key="i">
            <AudioPlay
              :view-size="data.property.style_mode"
              :view-method="data.property.view_method"
              :file-id="file.file_id"
              :file-name-display="data.property.file_name_display_mode"
              :file-name="file.file_name.slice(0, file.file_name.lastIndexOf('.'))"
              :audio-index="i"
              :topic-color="data.unified_attrib?.topic_color"
            />
          </li>
        </ul>
        <ul v-else class="view-independent">
          <li v-for="(file, i) in data.file_list" :key="i">
            <AudioPlay
              :view-size="data.property.style_mode"
              :view-method="data.property.view_method"
              :file-id="file.file_id"
              :file-name-display="data.property.file_name_display_mode"
              :file-name="file.file_name.slice(0, file.file_name.lastIndexOf('.'))"
              :audio-index="i"
              :topic-color="data.unified_attrib?.topic_color"
            />
          </li>
        </ul>
      </div>
      <ul v-else-if="'icon' === data.property.view_method" class="view-icon">
        <li v-for="(file, i) in data.file_list" :key="i">
          <AudioPlay
            view-size="small"
            :file-id="file.file_id"
            :audio-index="i"
            :topic-color="data.unified_attrib?.topic_color"
          />
        </li>
      </ul>
      <div v-else class="view-list">
        <el-carousel
          ref="audio_carousel"
          indicator-position="none"
          direction="vertical"
          :autoplay="false"
          :interval="0"
          :style="{ '--carousel-height': data.property.file_name_display_mode === 'true' ? '128px' : '80px' }"
        >
          <el-carousel-item v-for="(file, i) in data.file_list" :key="i">
            <AudioPlay
              view-size="big"
              :view-method="data.property.view_method"
              :file-id="file.file_id"
              :file-name-display="data.property.file_name_display_mode"
              :file-name="file.file_name.slice(0, file.file_name.lastIndexOf('.'))"
              :show-slider="true"
              :cur-audio-index="curAudioIndex"
              :topic-color="data.unified_attrib?.topic_color"
              @changeFile="changeFile"
            />
          </el-carousel-item>
        </el-carousel>
        <div :style="{ height: elementHeight - 140 + 'px', overflowY: viewScroll }">
          <ul class="view-list-bottom">
            <li v-for="(file, i) in data.file_list" :key="i" @click="handleAudioClick(i, file.file_id)">
              <AudioPlay
                :ref="file.file_id"
                view-size="list"
                :file-id="file.file_id"
                :file-name="file.file_name.slice(0, file.file_name.lastIndexOf('.'))"
                :show-slider="false"
                :audio-index="i"
                :cur-audio-index="curAudioIndex"
                :topic-color="data.unified_attrib?.topic_color"
                :assist-color="data.unified_attrib?.assist_color"
              />
            </li>
          </ul>
        </div>
      </div>
    </div>
  </div>
</template>

<script>
import { getAudioData } from '@/views/book/courseware/data/audio';

import PreviewMixin from '../common/PreviewMixin';
import AudioPlay from '../common/AudioPlay.vue';
import { getRandomNumber } from '@/utils';

export default {
  name: 'AudioPreview',
  components: { AudioPlay },
  mixins: [PreviewMixin],
  inject: ['getDragStatus'],
  data() {
    return {
      carouselHeight: 138,
      data: getAudioData(),
      curAudioIndex: 0,
      elementWidth: 0,
      elementHeight: 0,
      fileLen: 0,
      viewScroll: 'hidden',
      elementID: '',
      audioObserversMap: {},
    };
  },
  watch: {
    data: {
      handler(val) {
        this.fileLen = val.file_list.length;
        if (this.fileLen > 0 && this.data.property.view_method === 'list') {
          const ele = this.$refs.audioAreaBox;
          // this.elementWidth = ele.clientWidth;
          // this.elementHeight = ele.clientHeight;

          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;
          }

          const mainEle = this.$refs.audioArea;
          // 检查元素是否包含已知的类名
          mainEle.classList.forEach((className) => {
            // 排除已知的类名
            if (className !== 'audio-area') {
              // 打印另一个类名
              this.elementID = className;
            }
          });
        }
      },
      deep: true,
    },
    elementWidth(newWidth) {
      if (this.data.property.view_method === 'list') this.elementWidth = newWidth;
    },
    elementHeight(newHeight) {
      if (this.data.property.view_method === 'list') {
        this.elementHeight = newHeight;
        this.isViewScroll();
      }
    },
  },
  mounted() {
    this.$nextTick(() => {
      const canvasElement = document.querySelector('.canvas');
      if (!canvasElement) return;
      const instanceName = `observer_${this.elementID}`;
      this.audioObserversMap[instanceName] = new ResizeObserver((entries) => {
        if (!this.getDragStatus()) return;
        for (let entry of entries) {
          window.requestAnimationFrame(() => {
            const sn_position = this.data.property.sn_position;
            // 序号在上方和下方减去序号高度，在左右去掉padding(8*2)
            if (sn_position.includes('top') || sn_position.includes('bottom')) {
              this.elementWidth = entry.contentRect.width;
              this.elementHeight = entry.contentRect.height - 30;
            } else {
              this.elementWidth = entry.contentRect.width - 16;
              this.elementHeight = entry.contentRect.height;
            }
          });
        }
      });
      this.audioObserversMap[instanceName].observe(this.$el);
    });
  },
  beforeDestroy() {
    Object.values(this.audioObserversMap).forEach((observer) => {
      observer.disconnect();
    });
  },
  methods: {
    handleAudioClick(index, id) {
      // 获取 Carousel 实例
      const carousel = this.$refs.audio_carousel;
      // 切换到对应索引的文件
      carousel.setActiveItem(index);
      this.curAudioIndex = index;
      if (this.$refs[id] && this.$refs[id][0]) this.$refs[id][0].changeAudio(id);
    },
    changeFile(type) {
      // 获取 Carousel 实例
      const carousel = this.$refs.audio_carousel;
      // 切换到对应索引的文件
      if (type === 'prev') {
        carousel.prev();
        this.curAudioIndex += -1;
      } else {
        carousel.next();
        this.curAudioIndex += 1;
      }
      if (this.curAudioIndex >= this.data.file_id_list.length) {
        this.curAudioIndex = 0;
      }
      if (this.curAudioIndex < 0) {
        this.curAudioIndex = this.data.file_id_list.length - 1;
      }
    },
    isViewScroll() {
      const ulHeight = this.fileLen * 44;
      if (ulHeight > this.elementHeight - 140) {
        this.viewScroll = 'scroll';
      } else {
        this.viewScroll = 'hidden';
      }
    },

    /**
     * 获取无文本内容的数据结构，用于保存为个人模板时的样式模板
     */
    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 *;

.audio-preview {
  @include preview-base;

  .view-independent {
    display: flex;
    flex-wrap: wrap;
    gap: 16px;

    > li {
      min-width: 280px;
    }
  }

  .view-icon {
    display: flex;
    flex-wrap: wrap;
    gap: 16px 50px;
  }

  .view-list {
    display: flex;
    flex-direction: column;

    :deep .el-carousel {
      flex: 1;
      background-color: #f8f8f8;
      border-radius: 4px;

      &__container {
        height: var(--carousel-height, 128px);
      }

      &__item {
        transition: none !important;
      }
    }

    .view-list-bottom {
      display: flex;
      flex-direction: column;

      li {
        border-top: 1px solid #ccc;
      }
    }
  }
}
</style>
