import { PropType, Transition, defineComponent, ref } from 'vue';
import styles from './index.module.less';
import {
  ImageRenderToolbarProps,
  NButton,
  NCard,
  NImage,
  NModal,
  NSpace,
  NSpin,
  NTooltip,
  useMessage
} from 'naive-ui';
import iconImage from '@common/images/icon-image.png';
import iconVideo from '@common/images/icon-video.png';
import iconAudio from '@common/images/icon-audio.png';
import iconMusic from '@common/images/icon-music.png';
import iconPPT from '@common/images/icon-ppt.png';
import iconOther from '@common/images/icon-other.png';
import iconCollectDefault from '@common/images/icon-collect-default.png';
import iconCollectActive from '@common/images/icon-collect-active.png';
import iconDownload from '@common/images/icon-download.png';
import TheNoticeBar from '../TheNoticeBar';
import AudioPlayer from './audio-player';
import VideoPlayer from './video-player';
import { PageEnum } from '/src/enums/pageEnum';
import { api_musicSheetDetail } from '/src/api/user';
import JSZip, { file } from 'jszip';
import { saveAs } from 'file-saver';

// LISTEN:听音,RHYTHM：节奏,THEORY：乐理知识,MUSIC_WIKI:曲目 INSTRUMENT:乐器 MUSICIAN:音乐家）
type itemType = {
  id: string | number;
  type:
    | 'IMG'
    | 'VIDEO'
    | 'SONG'
    | 'MUSIC'
    | 'PPT'
    | 'LISTEN'
    | 'RHYTHM'
    | 'THEORY'
    | 'MUSIC_WIKI'
    | 'INSTRUMENT'
    | 'MUSICIAN';
  coverImg: string;
  content?: string;
  title: string;
  isCollect: boolean;
  audioPlayTypeArray?: string[];
  isSelected: boolean; // 精选
  exist?: boolean; // 是否已经选
};

export default defineComponent({
  name: 'card-type',
  props: {
    // 是否是选中状态
    isActive: {
      type: Boolean,
      default: false
    },
    /** 是否可以拖拽 */
    draggable: {
      type: Boolean,
      default: false
    },
    // 是否可以收藏
    isCollect: {
      type: Boolean,
      default: true
    },
    // 是否显示收藏
    isShowCollect: {
      type: Boolean,
      default: true
    },
    // 是否显示添加按钮
    isShowAdd: {
      type: Boolean,
      default: false
    },
    // 是否禁用添加按钮
    isShowAddDisabled: {
      type: Boolean,
      default: false
    },
    // 鼠标移动上面的时候是否自动播放，或者可以点击
    disabledMouseHover: {
      type: Boolean,
      default: true
    },
    // 是否预览
    isPreview: {
      type: Boolean,
      default: true
    },
    item: {
      type: Object as PropType<itemType>,
      default: () => ({})
    },
    /** 是否下架 */
    offShelf: {
      type: Boolean,
      default: false
    },
    /** 是否可以下载 */
    isDownload: {
      type: Boolean,
      default: false
    },
    audioPlayTypeSize: {
      type: String as PropType<'default' | 'small'>,
      deafult: 'default'
    }
  },
  /**
   * @type {string} click 点击事件
   * @type {string} collect 收藏
   * @type {string} add 添加
   * @type {string} offShelf 下架
   */
  emits: ['click', 'collect', 'add', 'offShelf'],
  setup(props, { emit }) {
    const message = useMessage();
    const isAnimation = ref(false);
    const downloadStatus = ref(false);
    const formatType = (type: string) => {
      let typeImg = iconOther;
      switch (type) {
        case 'IMG':
          typeImg = iconImage;
          break;
        case 'VIDEO':
          typeImg = iconVideo;
          break;
        case 'SONG':
          typeImg = iconAudio;
          break;
        case 'MUSIC':
          typeImg = iconMusic;
          break;
        case 'PPT':
          typeImg = iconPPT;
          break;
      }
      return typeImg;
    };

    // 获取文件blob格式
    const getFileBlob = (url: string) => {
      return new Promise((resolve, reject) => {
        const request = new XMLHttpRequest();
        request.open('GET', url, true);
        request.responseType = 'blob';
        request.onload = (res: any) => {
          if (res.target.status == 200) {
            resolve(res.target.response);
          } else {
            reject(res);
          }
        };
        request.send();
      });
    };

    // 多个文件下载
    const downLoadMultiFile = (files: any, filesName: string) => {
      const zip = new JSZip();
      const result = [];
      for (const i in files) {
        const promise = getFileBlob(files[i].url).then((res: any) => {
          zip.file(files[i].name, res, { binary: true });
        });
        result.push(promise);
      }
      Promise.all(result)
        .then(() => {
          zip.generateAsync({ type: 'blob' }).then(res => {
            saveAs(
              res,
              filesName
                ? filesName + Date.now() + '.zip'
                : `文件夹${Date.now()}.zip`
            );
          });
        })
        .catch(() => {
          message.error('下载失败');
        });

      downloadStatus.value = false;
    };

    const downloadFile = (filename: string, fileUrl: string) => {
      // 发起Fetch请求
      fetch(fileUrl)
        .then(response => response.blob())
        .then(blob => {
          saveAs(blob, filename);
          setTimeout(() => {
            downloadStatus.value = false;
          }, 100);
        })
        .catch(() => {
          message.error('下载失败');
        });

      downloadStatus.value = false;
    };

    const getFileName = (url: any) => {
      // 使用正则表达式获取文件名
      const tempUrl = url.split('?');
      const fileNameRegex = /\/([^\\/]+)$/; // 匹配最后一个斜杠后的内容
      const match = tempUrl[0].match(fileNameRegex);

      if (match) {
        return match[1];
      } else {
        return '';
      }
    };
    const onDownload = async (e: MouseEvent) => {
      e.stopPropagation();
      e.preventDefault();
      const item = props.item;
      if (!item.content) {
        message.error('下载失败');
        return;
      }
      if (downloadStatus.value) return false;
      downloadStatus.value = true;
      const suffix: any = item.content?.split('.');
      const fileName = item.title + '.' + suffix[suffix?.length - 1];
      if (item.type === 'MUSIC') {
        const { data } = await api_musicSheetDetail(item.content);
        const urls = [];
        if (data.xmlFileUrl) {
          urls.push({
            url: data.xmlFileUrl,
            name: getFileName(data.xmlFileUrl)
          });
        }
        if (data.background && data.background.length > 0) {
          data.background.forEach((item: any) => {
            urls.push({
              url: item.audioFileUrl,
              name: getFileName(item.audioFileUrl)
            });
          });
        }
        downLoadMultiFile(urls, item.title);

        // setTimeout(() => {
        //   downloadStatus.value = false;
        // }, 1000);
      } else {
        downloadFile(fileName, item.content);
      }
    };

    return () => (
      <div
        onClick={() => emit('click', props.item)}
        key={props.item.id}
        draggable={!props.draggable ? false : props.item.exist ? false : true}
        class={[
          styles['card-section'],
          'card-section-container',
          !props.draggable ? '' : props.item.exist ? '' : styles.cardDrag
        ]}
        onMouseenter={() => {
          isAnimation.value = true;
        }}
        onMouseleave={() => {
          isAnimation.value = false;
        }}
        onDragstart={(e: any) => {
          e.dataTransfer.setData('text', JSON.stringify(props.item));
        }}>
        {/* 判断是否下架 */}
        {props.offShelf && (
          <div class={styles.offShelfBg}>
            <p class={styles.offShelfTips}>该资源已被下架</p>
            <NButton
              type="primary"
              class={styles.offShelfBtn}
              onClick={(e: MouseEvent) => {
                e.stopPropagation();
                emit('offShelf');
              }}>
              确认
            </NButton>
          </div>
        )}
        <NCard
          class={[
            styles['card-section-content'],
            props.isShowAdd ? '' : styles.course,
            props.isActive ? styles.isActive : '',
            props.item.exist ? styles.showAddBtn : '' // 是否已添加
          ]}
          style={{ cursor: 'pointer' }}>
          {{
            cover: () => (
              <>
                {/* 图片 */}
                {props.item.type === 'IMG' && (
                  <NImage
                    class={[styles.cover, styles.image]}
                    lazy
                    previewDisabled={props.disabledMouseHover}
                    objectFit="cover"
                    src={props.item.coverImg}
                    previewSrc={props.item.content}
                    renderToolbar={({ nodes }: ImageRenderToolbarProps) => {
                      return [
                        nodes.prev,
                        nodes.next,
                        nodes.rotateCounterclockwise,
                        nodes.rotateClockwise,
                        nodes.resizeToOriginalSize,
                        nodes.zoomOut,
                        nodes.close
                      ];
                    }}
                  />
                )}
                {/* 乐谱 */}
                {props.item.type === 'MUSIC' && (
                  <>
                    <NImage
                      class={[styles.cover, styles.image]}
                      lazy
                      previewDisabled={true}
                      objectFit="contain"
                      src={props.item.coverImg}
                    />
                    <NSpace
                      class={[
                        styles.audioPlayTypeSection,
                        props.audioPlayTypeSize === 'small'
                          ? styles.audioPlayTypeSmall
                          : ''
                      ]}>
                      {props.item.audioPlayTypeArray?.includes('SING') && (
                        <NTooltip trigger="hover" showArrow={false}>
                          {{
                            trigger: () => (
                              <span
                                class={[
                                  styles.iconType,
                                  styles.iconSing
                                ]}></span>
                            ),
                            default: '演唱场景'
                          }}
                        </NTooltip>
                      )}

                      {props.item.audioPlayTypeArray?.includes('PLAY') && (
                        <NTooltip trigger="hover" showArrow={false}>
                          {{
                            trigger: () => (
                              <span
                                class={[
                                  styles.iconType,
                                  styles.iconPlay
                                ]}></span>
                            ),
                            default: '演奏场景'
                          }}
                        </NTooltip>
                      )}
                    </NSpace>
                  </>
                )}
                {/* 音频 */}
                {props.item.type === 'SONG' && (
                  <AudioPlayer
                    content={props.item.content}
                    cover={props.item.coverImg}
                    previewDisabled={props.disabledMouseHover}
                  />
                )}
                {/* 视频 */}
                {props.item.type === 'VIDEO' && (
                  <VideoPlayer
                    cover={props.item.coverImg}
                    content={props.item.content}
                    previewDisabled={props.disabledMouseHover}
                  />
                )}
                {/* ppt */}
                {props.item.type === 'PPT' && (
                  <NImage
                    class={[styles.cover, styles.image]}
                    lazy
                    previewDisabled={true}
                    objectFit="cover"
                    src={props.item.coverImg || PageEnum.PPT_DEFAULT_COVER}
                  />
                )}
                {/* 节奏练习 */}
                {props.item.type === 'RHYTHM' && (
                  <NImage
                    class={[styles.cover, styles.image]}
                    lazy
                    previewDisabled={true}
                    objectFit="cover"
                    src={props.item.coverImg || PageEnum.RHYTHM_DEFAULT_COVER}
                  />
                )}

                {/* 听音练习 */}
                {props.item.type === 'LISTEN' && (
                  <NImage
                    class={[styles.cover, styles.image]}
                    lazy
                    previewDisabled={true}
                    objectFit="cover"
                    src={props.item.coverImg}
                  />
                )}
                {/* 乐理 */}
                {props.item.type === 'THEORY' && (
                  <NImage
                    class={[styles.cover, styles.image]}
                    lazy
                    previewDisabled={true}
                    objectFit="cover"
                    src={props.item.coverImg || PageEnum.THEORY_DEFAULT_COVER}
                  />
                )}
                {/* 名曲 */}
                {props.item.type === 'MUSIC_WIKI' && (
                  <NImage
                    class={[styles.cover, styles.image]}
                    lazy
                    previewDisabled={true}
                    objectFit="cover"
                    src={props.item.coverImg || PageEnum.MUSIC_DEFAULT_COVER}
                  />
                )}
                {/* 乐器 */}
                {props.item.type === 'INSTRUMENT' && (
                  <NImage
                    class={[styles.cover, styles.image]}
                    lazy
                    previewDisabled={true}
                    objectFit="cover"
                    src={
                      props.item.coverImg || PageEnum.INSTRUMENT_DEFAULT_COVER
                    }
                  />
                )}
                {/* 音乐家 */}
                {props.item.type === 'MUSICIAN' && (
                  <NImage
                    class={[styles.cover, styles.image]}
                    lazy
                    previewDisabled={true}
                    objectFit="cover"
                    src={props.item.coverImg || PageEnum.MUSICIAN_DEFAULT_COVER}
                  />
                )}
              </>
            ),
            footer: () => (
              <div class={styles.footer}>
                <div class={[styles.title, 'footerTitle']}>
                  <NImage
                    class={[styles.titleType]}
                    src={formatType(props.item.type)}
                    objectFit="cover"
                  />
                  <span class={[styles.titleContent, 'titleContent']}>
                    <TheNoticeBar
                      isAnimation={isAnimation.value}
                      text={props.item.title}
                    />
                  </span>
                </div>
                {/* 收藏 */}
                <div class={styles.btnGroup}>
                  {props.isDownload && (
                    <div class={styles.btnItem} onClick={onDownload}>
                      <NSpin show={downloadStatus.value} size={'small'}>
                        <img
                          src={iconDownload}
                          key="3"
                          class={[styles.iconCollect]}
                        />
                      </NSpin>
                    </div>
                  )}
                  {props.isShowCollect && (
                    <div
                      class={[styles.iconCollect, styles.btnItem]}
                      onClick={(e: MouseEvent) => {
                        e.stopPropagation();
                        e.preventDefault();
                        // 判断是否可以收藏
                        if (props.isCollect) {
                          emit('collect', props.item);
                        }
                      }}>
                      <Transition name="favitor" mode="out-in">
                        {props.item.isCollect ? (
                          <img
                            src={iconCollectActive}
                            key="1"
                            class={[
                              styles.iconCollect,
                              props.isCollect ? styles.isCollect : ''
                            ]}
                          />
                        ) : (
                          <img
                            src={iconCollectDefault}
                            key="2"
                            class={[
                              styles.iconCollect,
                              props.isCollect ? styles.isCollect : ''
                            ]}
                          />
                        )}
                      </Transition>
                    </div>
                  )}
                </div>

                {/* 精选 */}
                {props.item.isSelected && (
                  <span class={styles.iconSelected}></span>
                )}

                {/* 添加按钮 */}
                {props.isShowAdd &&
                  (props.item.exist ? (
                    <NButton
                      type="primary"
                      class={[
                        styles.addBtn,
                        props.item.exist ? styles.addBtnDisabled : ''
                      ]}
                      disabled={props.item.exist || props.isShowAddDisabled}
                      onClick={(e: MouseEvent) => {
                        e.stopPropagation();
                        e.preventDefault();
                        emit('add', props.item);
                      }}>
                      {props.item.exist ? '已添加' : '添加'}
                    </NButton>
                  ) : (
                    !props.isShowAddDisabled && (
                      <NButton
                        type="primary"
                        class={[
                          styles.addBtn,
                          props.item.exist ? styles.addBtnDisabled : ''
                        ]}
                        disabled={props.item.exist || props.isShowAddDisabled}
                        onClick={(e: MouseEvent) => {
                          e.stopPropagation();
                          e.preventDefault();
                          emit('add', props.item);
                        }}>
                        {props.item.exist ? '已添加' : '添加'}
                      </NButton>
                    )
                  ))}
              </div>
            )
          }}
        </NCard>
      </div>
    );
  }
});
