import {
  computed,
  defineComponent,
  reactive,
  watch,
  ref,
  PropType,
  onMounted
} from 'vue';
import styles from './index.module.less';
import { Cell, Icon, Image, Popup, Slider } from 'vant';
import musicBg from '../../images/music_bg.png';
import iconMenu from '../../images/icon-menu.png';
import iconPause from '../../images/icon-pause.png';
import iconPlay from '../../images/icon-play.png';
import songPrev from '../../images/song-prev.png';
import songDown from '../../images/song-down.png';
import songPause from '../../images/song-pause.png';
import songPlay from '../../images/song-play.png';
import { getSecondRPM } from '@/helpers/utils';
import { nextTick } from 'process';
import { usePageVisibility } from '@vant/use';

export default defineComponent({
  name: 'audio-player',
  props: {
    musicList: {
      type: Array as PropType<any>,
      default: () => []
    }
  },
  setup(props) {
    const pageVisibility = usePageVisibility();
    const state = reactive({
      songPopup: false,
      musicListenList: props.musicList || ([] as any),
      playState: 'pause',
      audioObj: {} as any,
      listActive: 0,
      dragStatus: false // 是否开始拖动
    });
    let timer = null as any;
    const audioData = reactive({
      isFirst: true,
      duration: 0.1,
      currentTime: 0
    });
    const audioRef = ref();
    /** 加载成功 */
    const onLoadedmetadata = () => {
      audioData.duration = audioRef.value.duration;
      if (audioData.isFirst) {
        audioData.isFirst = false;
        return;
      }
      if (state.playState === 'play') {
        audioRef.value.play();
      }
    };
    /** 改变时间 */
    const handleChangeTime = (val: number) => {
      audioRef.value.pause();
      audioData.currentTime = val;
      clearTimeout(timer);
      timer = setTimeout(() => {
        audioRef.value.currentTime = val;
        if (state.playState === 'play') {
          audioRef.value.play();
        }
        timer = null;
      }, 300);
    };
    const time = computed(() => {
      return `${getSecondRPM(audioData.currentTime)} / ${getSecondRPM(
        audioData.duration
      )}`;
    });

    /** 播放曲目 */
    const handlePlay = (item: any) => {
      const index = state.musicListenList.findIndex(
        (_item: any) => _item.id === item.id
      );
      if (index > -1) {
        if (state.listActive === index) {
          state.playState = state.playState === 'play' ? 'pause' : 'play';
        } else {
          state.playState = 'play';
        }
        state.listActive = index;
        state.audioObj = state.musicListenList[index];
      }
    };

    /** 音频控制 */
    const handleChangeAudio = (type: 'play' | 'pause' | 'pre' | 'next') => {
      if (type === 'play') {
        state.playState = 'play';
      } else if (type === 'pause') {
        state.playState = 'pause';
      } else if (type === 'pre') {
        if (state.musicListenList[state.listActive - 1]) {
          audioData.currentTime = 0;
          handlePlay(state.musicListenList[state.listActive - 1]);
        }
      } else if (type === 'next') {
        if (state.musicListenList[state.listActive + 1]) {
          audioData.currentTime = 0;
          handlePlay(state.musicListenList[state.listActive + 1]);
        }
      }
    };

    watch(
      () => pageVisibility.value,
      val => {
        if (val === 'hidden') {
          audioRef.value.pause();
          state.playState = 'pause';
        }
      }
    );
    watch(
      () => state.playState,
      val => {
        if (val === 'play') {
          audioRef.value.play();
        } else {
          audioRef.value.pause();
        }
      }
    );

    watch(
      () => props.musicList,
      () => {
        state.musicListenList = props.musicList;
        const musicList = props.musicList;
        if (musicList.length > 0) {
          state.audioObj = musicList[0];
        }
      }
    );

    onMounted(() => {
      nextTick(() => {
        const musicList = props.musicList;
        if (musicList.length > 0) {
          state.audioObj = musicList[0];
        }
      });
    });
    return () => (
      <div class={styles.audioPlayer}>
        <div class={styles.playerHeader}>
          <div class={styles.musicInfo}>
            <div
              class={[
                styles.cover,
                state.playState === 'pause' && styles.imgRotate
              ]}>
              <Image src={musicBg} class={styles.musicBg} />
            </div>
            <div class={styles.musicName}>{state.audioObj?.name || '--'}</div>
          </div>
          <div class={styles.controls}>
            <Icon
              name={songPrev}
              class={styles.icon}
              onClick={() => {
                handleChangeAudio('pre');
              }}
            />
            <Icon
              name={state.playState === 'play' ? iconPlay : iconPause}
              class={[styles.icon, styles.iconPlay]}
              onClick={() => {
                if (state.playState === 'pause') {
                  handleChangeAudio('play');
                } else {
                  handleChangeAudio('pause');
                }
              }}
            />
            <Icon
              name={songDown}
              class={styles.icon}
              onClick={() => {
                handleChangeAudio('next');
              }}
            />
            <Icon
              name={iconMenu}
              class={[styles.icon, styles.iconMenu]}
              onClick={() => {
                state.songPopup = true;
              }}
            />
          </div>
        </div>
        <div class={styles.playerFooter}>
          <Slider
            step={0.01}
            class={styles.timeProgress}
            v-model={audioData.currentTime}
            max={audioData.duration}
            onUpdate:modelValue={val => {
              handleChangeTime(val);
            }}
            onDragStart={() => {
              state.dragStatus = true;
            }}
            onDragEnd={() => {
              state.dragStatus = false;
            }}
          />
          <div class={styles.playerTimer}>{time.value}</div>

          <audio
            ref={audioRef}
            src={state.audioObj.url}
            onLoadedmetadata={onLoadedmetadata}
            onEnded={() => {
              handleChangeAudio('pause');
            }}
            onTimeupdate={() => {
              if (timer) return;
              // 开始拖动时也不能更新
              if (state.dragStatus) return;
              // 由于缓存加载，导致触发暂停之后，还在播放的问题
              if (state.playState === 'pause') {
                audioRef.value.pause();
              }
              audioData.currentTime = audioRef.value?.currentTime;
            }}></audio>
        </div>

        <Popup
          v-model:show={state.songPopup}
          round
          position="bottom"
          class={styles.songPopup}>
          <div class={styles.songContainer}>
            <div class={styles.songTitle}>代表作</div>

            <div class={styles.songCellGroup}>
              {state.musicListenList.map((item: any, index: number) => (
                <Cell
                  border={false}
                  class={[
                    styles.songCell,
                    index === state.listActive && styles.active
                  ]}
                  center
                  onClick={() => {
                    if (index === state.listActive) return;
                    state.audioObj = state.musicListenList[index];
                    state.listActive = index;
                    state.playState = 'play';
                  }}>
                  {{
                    icon: () => <Image src={musicBg} class={styles.songImg} />,
                    title: () => <div class={styles.songName}>{item.name}</div>
                    // value: () => (
                    //   <Icon
                    //     name={
                    //       index === state.listActive &&
                    //       state.playState === 'play'
                    //         ? songPlay
                    //         : songPause
                    //     }
                    //     class={[styles.iconSong]}
                    //   />
                    // )
                  }}
                </Cell>
              ))}
            </div>
          </div>
        </Popup>
      </div>
    );
  }
});
