import {
  defineComponent,
  onMounted,
  onUnmounted,
  reactive,
  ref,
  watch,
  nextTick
} from 'vue';
// import WaveSurfer from 'wavesurfer.js';
// import Regions from 'wavesurfer.js/dist/plugins/regions.js';
import styles from './index.module.less';
import { Cell, Image, List, Popup, Sticky, TextEllipsis, NoticeBar } from 'vant';
import iconMember from './images/icon-member.png';
import iconZan from './images/icon-zan.png';
import iconZanActive from './images/icon-zan-active.png';
import logoImg from './images/logo.png';
import logo1Img from './images/logo1.png';
import iconUpward from './images/upward.png';
import iconPlay from './images/icon-play.png';
import iconPause from './images/icon-pause.png';
import audioPan from './images/audio-pan.png';
import audioLabel from './share-model/images/audioLabel.png';
import videoLabel from './share-model/images/videoLabel.png';
import musicBg from './share-model/images/music-bg.png';
import playImg from './images/play.png';
import { browser, getGradeCh, getSecondRPM, vaildMusicScoreUrl } from '@/helpers/utils';
import { onBeforeRouteUpdate, useRoute, useRouter, onBeforeRouteLeave } from 'vue-router';
import {
  api_openUserMusicDetail,
  api_openUserMusicPage,
  api_userMusicStar,
  api_verification
} from './api';
import MEmpty from '@/components/m-empty';
import MVideo from '@/components/m-video';
import LoginModel from './login-model';
import { removeAuth } from '../student-register/layout/utils';
import { setLogout } from '@/state';
import { storage } from '@/helpers/storage';
import { ACCESS_TOKEN } from '@/store/mutation-types';
import MWxTip from '@/components/m-wx-tip';
import { usePageVisibility, useEventListener, useWindowSize } from '@vant/use';
import LoginChangeModel from './login-change-model';
import MSticky from '@/components/m-sticky';
import "plyr/dist/plyr.css";
import Plyr from "plyr";
import { Vue3Lottie } from "vue3-lottie";
import audioBga from "./images/audioBga.json";
import audioBga1 from "./images/leftCloud.json";
import audioBga2 from "./images/rightCloud.json";
import videobg from "./images/videobg.png";
import btnImg from './images/btn.png';
import audioVisualDraw from "./audioVisualDraw"
import playProgressData from "./playCreation/playProgress"
import Loading from './loading';

export default defineComponent({
  name: 'creation-detail',
  setup() {
    const route = useRoute();
    const router = useRouter();
    const isScreenScroll = ref(false)
    const creationHeight = ref(0)
    const state = reactive({
      id: route.query.id,
      isEmpty:false,
      loginTag: false, // 是否登录标识
      loginStatus: false,
      loginChangeState: false, // 切换账号
      credential: {} as any,
      playType: '' as 'Audio' | 'Video' | '', // 播放类型
      musicDetail: {} as any,
      isClick: false,
      list: [] as any,
      listState: {
        dataShow: true, // 判断是否有数据
        loading: false,
        finished: false
      },
      params: {
        page: 1,
        rows: 4
      },
      messageStatus: false,
      message: '',
      _plrl: null as any,
      heightV:0,
      heightB:0
    });
    const plyrState = reactive({
      duration: 0,
      currentTime: 0,
      mediaTimeShow: false,
      playIngShow: true,
      loaded:false
    })
    // 谱面
    const staffState = reactive({
      staffSrc: "",
      isShow: false,
      height:"initial",
      speedRate:1,
      musicRenderType:"staff",
      partIndex:0
    })
    const staffDom= ref<HTMLIFrameElement>()
    const {playStaff, pauseStaff, updateProgressStaff} = staffMoveInstance()
    let isInitAudioVisualDraw =false
    // 点赞
    const onStarChange = async () => {
      await checkLogin();
      // 是否登录
      if (!state.loginTag) {
        state.loginStatus = true;
        return;
      }
      try {
        await api_userMusicStar({
          userMusicId: state.id,
          star: !state.musicDetail.starFlag
        });

        state.musicDetail.starFlag = !state.musicDetail.starFlag;
        if (state.musicDetail.starFlag) {
          state.musicDetail.likeNum += 1;
        } else {
          state.musicDetail.likeNum -= 1;
        }
      } catch {
        //
      }
    };

    // 获取列表
    const getList = async () => {
      try {
        if (state.isClick) return;
        state.isClick = true;
        const res = await api_openUserMusicPage({
          type: 'FORMAL',
          exclusionId: state.id,
          sort: 1,
          ...state.params
        });
        state.listState.loading = false;
        const result = res.data || {};
        // 处理重复请求数据
        // if (state.list.length > 0 && result.current === 1) {
        //   return;
        // }
        state.list = result.rows || [];
        state.listState.finished = result.current >= result.pages;
        state.params.page = result.current + 1;
        state.listState.dataShow = state.list.length > 0;
        state.isClick = false;
      } catch {
        state.listState.dataShow = false;
        state.listState.finished = true;
        state.isClick = false;
      }
    };
    function handleChangeList() {
      if(state.listState.finished){
        state.listState.finished = false
        state.params.page = 1;
        getList()
      }else{
        getList()
      }
    }
    const onDetail = (item: any) => {
      playProgressData.playProgress = 0
      playProgressData.playState = false
      router.push({
        path: '/shareCreation',
        query: {
          id: item.id
        }
      });
    };
    // 初始化 媒体播放
    function initMediaPlay(){
      const id = state.playType === "Audio" ? "#audioMediaSrc" : "#videoMediaSrc";
      state._plrl = new Plyr(id, {
        controls: ["progress"],
        fullscreen: {
          enabled: false,
          fallback: false
        }
      });
      const player = state._plrl
      // 在微信中运行的时候，微信没有开放自动加载资源的权限，所以要等播放之后才显示播放控制器
      player.on('loadedmetadata', () => {
        plyrState.loaded = true
        player.currentTime = playProgressData.playProgress
      });
      player.on("timeupdate", ()=>{
        plyrState.currentTime = player.currentTime
      })
      player.on('play', () => {
        plyrState.playIngShow = false
        playStaff()
      });
      player.on('pause', () => {
        plyrState.playIngShow = true
        pauseStaff()
      });
      player.on('ended', () => {
        player.currentTime = 0
        if(!player.playing){
          setTimeout(() => {
            updateProgressStaff(player.currentTime)
          }, 100);
        }
      });
      // 处理按压事件
      const handleStart = () => {
        plyrState.duration = player.duration
        plyrState.mediaTimeShow = true
      };
      // 处理松开事件
      const handleEnd = () => {
        plyrState.mediaTimeShow = false
        // 暂停的时候调用
        if(!player.playing){
          updateProgressStaff(player.currentTime)
        }
      };
      const progressDom = document.querySelector("#playMediaSection .plyr__controls .plyr__progress__container") as HTMLElement
      progressDom.addEventListener('mousedown', handleStart);
      progressDom.addEventListener('touchstart', handleStart);
      progressDom.addEventListener('mouseup', handleEnd);
      progressDom.addEventListener('touchend', handleEnd);
    }
    //点击改变播放状态
    function handlerClickPlay(){
      const player = state._plrl;
      // 由于ios低版本必须在用户操作之后才能初始化 createMediaElementSource 所以必须在用户操作之后初始化
      if(!isInitAudioVisualDraw && state.playType === "Audio"){
        isInitAudioVisualDraw = true
        // 创建音波数据
        const audioDom = document.querySelector("#audioMediaSrc") as HTMLAudioElement
        const canvasDom = document.querySelector("#audioVisualizer") as HTMLCanvasElement
        const { pauseVisualDraw, playVisualDraw } = audioVisualDraw(audioDom, canvasDom)
        player.on('play', () => {
          playVisualDraw()
        });
        player.on('pause', () => {
          pauseVisualDraw()
        });
      }
      if (player.playing) {
        player.pause();
      } else {
        player.play();
      }
    }
    function handlerLandscapeScreen(event:any){
      event.stopPropagation()
      playProgressData.playState = !!state._plrl?.playing
      playProgressData.playProgress = state._plrl?.currentTime || 0
      router.push({
        path:"/playCreation",
        query:{
          resourceUrl:encodeURIComponent(state.musicDetail?.videoUrl),
          videoBgUrl:encodeURIComponent(state.musicDetail?.videoImg || ""),
          musicSheetName:encodeURIComponent(state.musicDetail?.musicSheetName),
          username:encodeURIComponent(state.musicDetail?.username),
          musicSheetId:encodeURIComponent(state.musicDetail?.musicSheetId),
          speedRate:encodeURIComponent(staffState.speedRate),
          musicRenderType:encodeURIComponent(staffState.musicRenderType),
          partIndex:encodeURIComponent(staffState.partIndex),
        }
      })
    }
    const checkLogin = async () => {
      try {
        // 判断是否登录
        const Authorization = storage.get(ACCESS_TOKEN) || '';
        if (Authorization) {
          const res = await api_verification({
            token: Authorization
          });
          console.log(res.data, 'res.data');
          state.loginTag = res.data;
          if (!res.data) {
            removeAuth();
            setLogout();
          }
        }
      } catch (err) {
        //
        storage.remove(ACCESS_TOKEN);
        removeAuth();
        setLogout();
        state.loginTag = false;
      }
    };
    const __init = async () => {
      await checkLogin();
      try {
        const res = await api_openUserMusicDetail(state.id);
        if (res.code === 999) {
          // 没有的时候显示缺省页
          state.isEmpty = true
          staffState.isShow = true
          return;
        } else {
          state.musicDetail = res.data;
          try{
            const jsonConfig = JSON.parse(res.data.jsonConfig)
            jsonConfig.speedRate && (staffState.speedRate = jsonConfig.speedRate)
            jsonConfig.musicRenderType && (staffState.musicRenderType = jsonConfig.musicRenderType)
            jsonConfig.partIndex && (staffState.partIndex = jsonConfig.partIndex)
          }catch{
          }
          // 五线谱
          initStaff()
          getList();
          // 判断是视频还是音频
          if (res.data.videoUrl.lastIndexOf('mp4') !== -1) {
            state.playType = 'Video';
          } else {
            state.playType = 'Audio';
          }
          // 初始化
          nextTick(() => {
            initMediaPlay();
          });
        }
      } catch (err:any) {
        // 没有的时候显示缺省页
        state.message = err;
        state.messageStatus = true;
      }
    };
    // 滚动事件
    const cleanScrollEvent = useEventListener('scroll', () => {
      // 作品已删除不让滚动变色
      if(state.isEmpty) return
      const height =
        window.scrollY ||
        document.documentElement.scrollTop
        // 防止多次调用
        if(height > 0 && isScreenScroll.value === false){
          isScreenScroll.value = true
        }
        if(height <= 0){
          isScreenScroll.value = false
        }
    })
    function handlerDownLoad(){
      router.push({
        path:"/transfer"
      })
    }
    const pageVisibility = usePageVisibility();
    watch(pageVisibility, value => {
      if (value === 'hidden') {
        state._plrl?.pause();
      }
    });
    // 初始化五线谱
    function initStaff(){
      const src = `${vaildMusicScoreUrl()}/instrument/#/simple-detail?id=${state.musicDetail.musicSheetId}&musicRenderType=${staffState.musicRenderType}&part-index=${staffState.partIndex}`;
      //const src = `http://192.168.3.122:3000/instrument.html#/simple-detail?id=${state.musicDetail.musicSheetId}&musicRenderType=${staffState.musicRenderType}&part-index=${staffState.partIndex}`;
      staffState.staffSrc = src
      window.addEventListener('message', (event) => {
        const { api, height } = event.data;
        if (api === 'api_musicPage') {
          staffState.isShow = true
          staffState.height = height + "px"
          // 如果是播放中自动开始播放  不是播放 自动跳转到当前位置
          if(playProgressData.playState){
            handlerClickPlay()
          }else{
            updateProgressStaff(state._plrl.currentTime)
          }
        }
      });
    }
    function staffMoveInstance(){
      let isPause = true
      const requestAnimationFrameFun = () => {
        requestAnimationFrame(() => {
          staffDom.value?.contentWindow?.postMessage(
            {
              api: 'api_playProgress',
              content: {
                currentTime: state._plrl.currentTime * staffState.speedRate
              }
            },
            "*"
          )
          if (!isPause) {
            requestAnimationFrameFun()
          }
        })
      }
      const playStaff = () => {
        // 没渲染不执行
        if(!staffState.isShow) return
        isPause = false
        staffDom.value?.contentWindow?.postMessage(
          {
            api: 'api_play'
          },
          "*"
        )
        requestAnimationFrameFun()
      }
      const pauseStaff = () => {
        // 没渲染不执行
        if(!staffState.isShow) return
        isPause = true
        staffDom.value?.contentWindow?.postMessage(
          {
            api: 'api_paused'
          },
          "*"
        )
      }
      const updateProgressStaff = (currentTime: number) => {
        // 没渲染不执行
        if(!staffState.isShow) return
        staffDom.value?.contentWindow?.postMessage(
          {
            api: 'api_updateProgress',
            content: {
              currentTime: currentTime * staffState.speedRate
            }
          },
          "*"
        )
      }
      return {
        playStaff,
        pauseStaff,
        updateProgressStaff
      }
    }
    function setFullHeight(){
      creationHeight.value = window.innerHeight
    }
    onMounted(async () => {
      __init();
      window.addEventListener('resize', setFullHeight)
    });

    onUnmounted(() => {
      cleanScrollEvent()
      window.removeEventListener('resize', setFullHeight)
      state._plrl?.destroy()
    });

    onBeforeRouteUpdate((to: any) => {
      state.id = to.query.id;
      state.playType = '';
      state.params.page = 1;
      state.list = [];
      isInitAudioVisualDraw = false
      if(state._plrl){
        state._plrl.destroy()
      }
      plyrState.playIngShow = true
      staffState.staffSrc = ""
      staffState.isShow = false
      staffState.height = "initial"
      __init();
    });
    onBeforeRouteLeave((to, from, next)=>{
      if(to.path !== "/playCreation"){
        playProgressData.playProgress = 0
        playProgressData.playState = false
      }
      next()
    })
    return () => (
      <div
        style={
          {
            '--barheight':state.heightV + "px",
            "--creationHeight":creationHeight.value ? creationHeight.value+"px" : "100vh"
          }
        }
        class={[
          styles.creation,
          browser().isTablet ? styles.creationTablet : '',
          isScreenScroll.value && styles.isShareScreenScroll
        ]}>
        <div class={styles.creationBg}></div>
        <MSticky position="top"
          onBarHeight={(height: any) => {
            console.log(height, 'height', height)
            state.heightV = height
          }}
        >
            <div class={styles.logoDownload}>
              <img src={isScreenScroll.value ? logo1Img : logoImg} class={styles.logoImg}></img>
              <div class={styles.logTit} onClick={handlerDownLoad}>下载App</div>
            </div>
        </MSticky>
        {
          state.isEmpty ?
          <div class={styles.isEmpty}>
            <MEmpty image={"empty2"} description="作品已删除～" />
          </div> :
          <>
            <div class={styles.singerBox}>
              <div class={styles.musicSheetName}>
                <NoticeBar
                    text={state.musicDetail?.musicSheetName}
                    background="none"
                />
              </div>
              <div class={styles.singerName}>
                演奏：{state.musicDetail?.username}
              </div>
            </div>
            <Sticky offsetTop={state.heightV - 1 + "px"}>
              <div class={[styles.playSection, plyrState.mediaTimeShow && styles.mediaTimeShow,!plyrState.loaded && styles.notLoaded]} id="playMediaSection" onClick={handlerClickPlay}>
                {
                  state.playType &&
                  <>
                    {
                      state.playType === 'Audio' &&
                      <div class={styles.audioBox}>
                        <canvas class={styles.audioVisualizer} id="audioVisualizer"></canvas>
                        <Vue3Lottie class={styles.audioBga} animationData={audioBga} autoPlay={true} loop={true}></Vue3Lottie>
                        <Vue3Lottie class={styles.audioBga1} animationData={audioBga1} autoPlay={true} loop={true}></Vue3Lottie>
                        <Vue3Lottie class={styles.audioBga2} animationData={audioBga2} autoPlay={true} loop={true}></Vue3Lottie>
                        <audio
                          crossorigin="anonymous"
                          id="audioMediaSrc"
                          src={state.musicDetail?.videoUrl}
                          controls="false"
                          preload="metadata"
                          playsinline
                        />
                      </div>
                    }
                    {
                      state.playType === 'Video' &&
                      <video
                        id="videoMediaSrc"
                        class={styles.videoBox}
                        src={state.musicDetail?.videoUrl}
                        data-poster={ state.musicDetail?.videoImg || videobg}
                        preload="metadata"
                        playsinline
                        webkit-playsinline
                      />
                    }
                    <div class={[styles.playLarge, !plyrState.mediaTimeShow && plyrState.playIngShow && styles.playIngShow]}></div>
                    <div class={styles.mediaTimeCon}>
                      <div class={styles.mediaTime}>
                        <div>
                          {getSecondRPM(plyrState.currentTime)}
                        </div>
                        <div class={styles.note}>/</div>
                        <div class={styles.duration}>
                          {getSecondRPM(plyrState.duration)}
                        </div>
                      </div>
                    </div>
                    <div class={styles.landscapeScreen} onClick={handlerLandscapeScreen}></div>
                    {/* 谱面 */}
                    {
                      staffState.staffSrc &&
                      <div class={[styles.staffBoxCon, staffState.isShow && styles.staffBoxShow]}>
                        <div
                          class={styles.staffBox}
                          style={
                            {
                              '--staffBoxHeight':staffState.height
                            }
                          }
                        >
                          <div class={styles.mask}></div>
                          <iframe
                            ref={staffDom}
                            class={styles.staff}
                            frameborder="0"
                            src={staffState.staffSrc}>
                          </iframe>
                        </div>
                      </div>
                    }
                  </>
                }
              </div>
            </Sticky>
            <div class={[styles.musicSection, styles.musicShareSection]}>
              <div class={styles.avatarInfoBox}>
                <div class={styles.avatar}>
                  <Image class={styles.userLogo} src={state.musicDetail.avatar} />
                  <div class={styles.infoCon}>
                    <div class={styles.info}>
                      <span class={styles.userName}>{state.musicDetail?.username}</span>
                      {state.musicDetail.vipFlag && (
                        <img src={iconMember} class={styles.iconMember} />
                      )}
                    </div>
                    <div class={styles.sub}>
                      {state.musicDetail.subjectName}{' '}
                      {getGradeCh(state.musicDetail.currentGradeNum - 1)}
                    </div>
                  </div>
                </div>
                <div class={styles.linkes}  onClick={onStarChange}>
                  <img src={state.musicDetail.starFlag ? iconZanActive : iconZan} class={styles.iconZan} />
                  <span>{state.musicDetail.likeNum}</span>
                </div>
              </div>
              <TextEllipsis class={styles.textEllipsis} rows={2} content={state.musicDetail?.desc} expand-text="展开" collapse-text="收起" />
            </div>
            <div class={styles.likeSection}>
              <div class={styles.likeTitle}>推荐作品</div>
              {state.listState.dataShow ? (
                <>
                  <List
                    finished={true}
                    finishedText=" "
                    class={[styles.container, styles.containerInformation]}
                    //onLoad={getList}
                    immediateCheck={false}>
                    {state.list.map((item: any, index:number) => (
                      <Cell
                        class={[styles.likeShareItem, index===state.list.length-1&&styles.likeShareItemLast]}
                        border={false}
                        onClick={() => onDetail(item)}
                      >
                        {{
                          icon: () => (
                            <div class={styles.audioImgBox}>
                              <img
                                src={audioPan}
                                class={styles.audioPan}
                                crossorigin="anonymous"
                              />
                              <img
                                src={
                                  item.img || musicBg
                                }
                                class={styles.muploader}
                                crossorigin="anonymous"
                              />
                              <img class={styles.imgLabel} src={item.videoUrl?.lastIndexOf('mp4') !== -1 ? videoLabel : audioLabel} />
                            </div>
                          ),
                          title: () => (
                            <div class={styles.userInfo}>
                              <div class={[styles.musicSheetName,'van-ellipsis']}>{item.musicSheetName}</div>
                              <div class={styles.usernameCon}>
                                <div class={styles.likeNum}>
                                  <img src={iconZanActive} />
                                  <span>{item.likeNum}</span>
                                </div>
                                <div class={[styles.username, 'van-ellipsis']}>{item.username}</div>
                              </div>
                            </div>
                          ),
                          value: () => (
                            <img src={playImg} class={styles.playImg} />
                          )
                        }}
                      </Cell>
                    ))}
                  </List>
                  {
                    (!state.listState.finished || state.params.page>2) &&
                      <div class={styles.btnImg}>
                        <img onClick={handleChangeList} onTouchstart={()=>{}} src={btnImg} />
                      </div>
                  }
                </>
              ) : (
                <MEmpty image={"empty2"} description="暂无作品" />
              )}
            </div>
            {
              !isScreenScroll.value &&
              <MSticky position="bottom" offsetBottom={state.heightB - 1 + "px"} >
                <div class={styles.upward}>
                  <img src={iconUpward} />
                </div>
              </MSticky>
            }
          </>
        }
        <Popup
          v-model:show={state.loginStatus}
          style={{ background: 'transparent', overflow: 'inherit' }}>
          <LoginModel
            onClose={() => (state.loginStatus = false)}
            onConfirm={async (val: any) => {
              if (val.loginTag) {
                state.loginTag = val.loginTag;
                state.loginStatus = false;
                const { data } = await api_openUserMusicDetail(state.id);
                state.musicDetail = data;
              } else {
                state.credential = val.data;
                state.loginChangeState = true;
                state.loginStatus = false;
              }
            }}
          />
        </Popup>
        <Popup
          v-model:show={state.loginChangeState}
          style={{ background: 'transparent', overflow: 'inherit' }}>
          <LoginChangeModel
            credential={state.credential}
            onClose={() => {
              state.credential = {};
              state.loginChangeState = false;
            }}
            onConfirm={async (val: any) => {
              state.loginTag = val.loginTag;
              state.loginChangeState = false;
              const { data } = await api_openUserMusicDetail(state.id);
              state.musicDetail = data;
            }}
          />
        </Popup>
        <MWxTip
          v-model:show={state.messageStatus}
          message={state.message}
          showButton={false}
        />
        {
          !staffState.isShow && <Loading></Loading>
        }
      </div>
    );
  }
});
