<template>
  <div class="main" v-if="!!lianxi">
    <van-sticky>
      <div class="header" ref="header">
        <div class="top-area">
          <span class="piyue-teacher">
              本练习由<strong class="text-primary">AI </strong>打分
              <template v-if="lianxi.piyue?.teacher_name">，<strong class="text-info">{{lianxi.piyue?.teacher_name}}</strong> 老师批阅</template>
          </span>
          <div class="rate-area">
            <van-rate color="#ffd21e" :size="18" readonly v-model="rating_value" />
            <i class="rate-text">{{rating_text}}</i>
          </div>
        </div>
        <div class="text-area" v-if="lianxi?.text_question">
          {{lianxi.text_question}}
        </div>
        <div class="course-area" v-if="course_section">
          {{course_section.course_name}}({{course_section.section_name}})
          <span class="extra-span">
            <van-icon size="16" name="guide-o" color="#1989fa" @click="$router.push('/student/jihua/detail?id=' + params.jihua_id + '&qs=' + course_section.id)" />
            <score-show :icon="'video'" v-if="lianxi.video?.resource_url" :target="lianxi.video?.resource_url" :horizontal="true" :simple="true" :scores="lianxi.scores"></score-show>
            <i v-if="lianxi.video?.resource_url && lianxi.audio?.resource_url" class="fa-solid fa-slash backslash"></i>
            <score-show :icon="'audio'" v-if="lianxi.audio?.resource_url" :target="lianxi.audio?.resource_url" :horizontal="true" :simple="true" :scores="lianxi.scores"></score-show>
          </span>
        </div>
      </div>
    </van-sticky>
    <div class="piyue" :style="{height: 'calc(100% - ' + header_height + ' - 0.8rem - 1rem)'}">
      <div class="mark-area">
        <lianxi-pigai v-if="qupu" :disabled="expired" :video_id="video_id" :replyable="replyable" :readonly="readonly" :qupu="qupu" :marks="marks"
                      @notify="notify_comment($event)" @update="update($event)" :commentator="create_jihua_comment" />
      </div>
      <div class="playing-area" v-if="video">
        <hty-video :id="video_id" :downloadable="true" :src="video"></hty-video>
      </div>
    </div>
    <div class="audio-area" v-if="has_audio">
      <strong>练习录音：</strong>
      <audio-play @click="play_question(lianxi)" :playing="playing === lianxi?.id"></audio-play>
    </div>
    <div class="footer">
      <div class="audio-area">
        <van-badge v-if="comments_count || !expired" :content="comments_count" color="#0dcaf0" :show-zero="false" max="99">
          <van-button type="primary" size="small" @click="replying = true">留言回复</van-button>
        </van-badge>
      </div>
    </div>
  </div>
  <van-action-sheet :lock-scroll="false" v-model:show="replying" title="留言回复" @closed="replying = false" :close-on-click-overlay="false" :closeable="!state.comment">
    <comments-sheet :disabled="expired" :ref_id="lianxi?.piyue?.id" :comment="state.comment" :qupu="qupu" @reply="replyComment" @submit="saveComment" @remove="removeComment"></comments-sheet>
  </van-action-sheet>
</template>

<script lang="ts">
import {
  computed,
  defineComponent,
  nextTick,
  onBeforeMount,
  onBeforeUnmount,
  reactive,
  ref,
  watch
} from 'vue';
import {ActionSheet, Badge, Button, Empty, Popover, Rate, Sticky, Icon, showConfirmDialog} from 'vant';
import LianxiPigai from "~/components/lianxi-pigai.vue";
import CommentsSheet from '~/components/comments-sheet.vue';
import useJihua from "~/store/jihua";
import useUser from "~/store/user";
import {
  Comment,
  CommentContent,
  CommentRefTypes, HtyBaseRoles,
  Lianxi,
  NotifyParam,
  NotifyTypes, PickTargets,
  RatingTexts,
  RefResourceTypes,
  ResourceNote,
  PoolData
} from "~/types";
import useAudio from "~/store/audio";
import {wxUtil} from "~/utils/wx";
import AudioPlay from '~/components/audio-play.vue'
import HtyVideo from '~/components/hty-video.vue'
import ScoreShow from '~/components/score-show.vue'
import usePool from "~/store/pool";
import useComment from "~/store/comment";
import {useRouter} from "vue-router";
import useTimer from "~/store/timer";
import dayjs from "dayjs";
import {uuid} from "~/utils";


export default defineComponent({
  name: 'student-piyue',
  components: {
    [Button.name]: Button,
    [Rate.name]: Rate,
    [LianxiPigai.name]: LianxiPigai,
    [Empty.name]: Empty,
    [AudioPlay.name]: AudioPlay,
    [Popover.name]: Popover,
    [Sticky.name]: Sticky,
    [ActionSheet.name]: ActionSheet,
    [Badge.name]: Badge,
    [HtyVideo.name]: HtyVideo,
    [CommentsSheet.name]: CommentsSheet,
    [Icon.name]: Icon,
    [ScoreShow.name]: ScoreShow
  },
  props: {
    params: {}
  },
  setup({params}: any) {
    const router = useRouter();
    wxUtil.init(['startRecord', 'stopRecord', 'onVoiceRecordEnd', 'playVoice', 'pauseVoice', 'stopVoice', 'onVoicePlayEnd', 'uploadVoice', 'downloadVoice']);
    const {store, create_jihua_comment, notify, check_tasks, read} = useJihua();
    const usingAudio = useAudio();
    const usingUser = useUser();
    const usingPool = usePool();
    const { count_comments, get_comments, check_comments_score } = useComment();
    const {stopTimer, startTimer} = useTimer()
    const marks = ref<ResourceNote[]>(store.current_lianxi?.piyue?.resource_note_group?.resource_notes || [])
    const video = computed(() => store.current_lianxi?.video?.resource_url)

    const qupu = computed(() => {
      let lianxi_qupu = store.current_lianxi?.qupu;
      if (lianxi_qupu) return lianxi_qupu;
      let qs = store.current.course_sections.find(x => x.lianxis?.includes(store.current_lianxi));
      return (qs?.ref_resources || qs?.resources)?.find(r => r.resource_type === RefResourceTypes.Picture);
    })

    const header = ref(null)
    const header_height = ref('1rem')

    const show_text_question = ref(false);
    const replying = ref(false);
    const lianxi = computed(() => store.current_lianxi);
    const rating_text = computed(() => RatingTexts[store.current_lianxi?.piyue?.rating.stars || 0])

    const rating_value = computed(() => store.current_lianxi?.piyue?.rating.stars || 0);

    const state = reactive({
      comment: null as (null | Comment)
    })


    watch(() => store.current_lianxi, (value) => {
      if (value &&  value.piyues) {
        marks.value = value.piyues[0]?.resource_note_group?.resource_notes || [];
      }

    })

    const notify_comment = ({comment_id, serial}: {comment_id: string, serial?: string}) => {
      let params: NotifyParam = {
        notify_type: NotifyTypes.StudentCommentPiyue,
        hty_id: store.current.teacher_id,
        hty_id2: store.current.student_id,
        lianxi_id: store.current_lianxi?.id,
        jihua_id: store.current.id,
        comment_id, serial
      }
      notify(params, HtyBaseRoles.TEACHER)
    }

    const replyComment = (parent_id?: string) => {
      state.comment = { parent_id, ref_type: CommentRefTypes.Piyue, content: {} as CommentContent} as Comment
    }

    const saveComment = async () => {
      let comment = state.comment as Comment;
      comment.ref_id = store.current_lianxi?.piyue?.id;
        let created = await create_jihua_comment(comment);
        if (created) {
          state.comment = null;
          notify_comment({comment_id: created.id})
        }
    }

    const removeComment = () => {
      state.comment = null;
      replying.value = false;
    }

    const playing = computed(() => usingAudio.store.target)
    const play_question = ({id, audio}: Lianxi) => {
      if (playing.value === id) {
        usingAudio.stop();
      } else {
        if (audio?.tasks?.vals) {
          let media_id = audio?.tasks?.vals[0]?.task_meta?.media_id;
          usingAudio.play({target: id, audio_url: audio?.resource_url, serverId: media_id})
        }
      }
    }

    onBeforeMount(async () => {
      if (params) {
        let { lianxi_id, jihua_id, from_tongzhi, ref_id, comment_id } = params;
        let data: PoolData = {lianxi_id, jihua_id, business_type: PickTargets.JIHUA}
        if ((from_tongzhi || !store.current_lianxi) && lianxi_id && jihua_id) {
          await read(jihua_id, store.current.id !== jihua_id || from_tongzhi);
        }
        (store.current.course_sections || []).forEach(qs => {
          (qs.lianxis || []).forEach(lianxi => {
            if (lianxi.id === lianxi_id) {
              store.current_lianxi = lianxi;
              data.piyue_id = lianxi.piyue?.id;
              data.course_section = qs;
            }
          })
        })
        // 该lianxi可能已经被删除
        if (!store.current_lianxi) {
          showConfirmDialog({
            message: "该练习已被删除",
            cancelButtonText: "返回通知",
            confirmButtonText: "查看计划详情",
            showCancelButton: !!from_tongzhi
          }).then(() => {
            router.replace("/student/jihua/detail?id=" + jihua_id)
          }).catch(() => {
            router.back();
          })
          return;
        }
        usingPool.set(data)
        // new comment added to piyue, or new resource notes added to piyue comment
        // show comments sheet
        if (ref_id || comment_id) {
          let comments = get_comments(data.piyue_id);
          if(comments.some(c => c.id === ref_id || c.id === comment_id)) {
            replying.value = true;
          }
        }
      }
      await nextTick(() => {
        let el = header.value as unknown as HTMLDivElement;
        header_height.value = el.offsetHeight + 'px';
      })
      usingUser.set_editing(true)

      if (store.current.id) {
        startTimer(() => store.current, check_tasks)
      }
    });

    onBeforeUnmount(() => {
      store.current_lianxi = undefined;
      stopTimer()
    })
    const video_id = uuid();
    const has_audio = computed(() => store.current_lianxi?.audio)

    const comments_count = computed(() => count_comments(store.current_lianxi?.piyue?.id))
    const course_section = computed(() => {
      return store.current.course_sections.find(x => x.lianxis?.includes(store.current_lianxi));
    })

    const expired = computed(() => dayjs(store.current.end_date).valueOf() < dayjs().startOf('date').valueOf())

    const readonly = computed(() => !!(lianxi.value?.piyue?.id))
    const replyable = computed(() => {
      let user_id = usingUser.store.current.hty_id;
      // only student of this lianxi can add comments
      return store.current_lianxi?.created_by === user_id;
    });

    const update = (data: ResourceNote[]) => {
      marks.value = data;
    }

    return {
      marks, video, qupu, lianxi, playing, video_id, readonly, replyable, rating_value, rating_text, has_audio, course_section,
      play_question, update, show_text_question, replying, state, header, header_height, comments_count,
      replyComment, saveComment, removeComment, notify_comment, create_jihua_comment, expired
    }
  },
})
</script>

<style scoped lang="less">
  .main {
    padding: 0;
    overflow: auto;
    position: relative;


    .header {
      padding: 0.16rem;
      background: #FFFFFF;
      box-shadow: 0 0 5px 6px #eeeeee;

      .top-area {
        display: flex;
        align-items: center;
        justify-content: space-between;

        .piyue-teacher {
          font-size: 0.2rem;
        }

        .rate-area {
          display: flex;
          flex-direction: column;
          align-items: center;
          justify-content: space-between;
          width: 2.4rem;

          .rate-text {
            font-size: 0.16rem;
            color: #9e9e9e;
          }
        }
      }

      .text-area, .course-area {
        border-top: 1px dashed #e5e5e5;
        font-size: 12px;
        color: #999999;
        width: 100%;
        padding-top: 0.12rem;
        background-clip: padding-box;
        border-radius: 0.125rem;
      }

      .course-area {
        color: #333;
        font-weight: bolder;
        text-align: center;
        display: flex;
        flex-direction: column;
        font-size: 0.2rem;

        .extra-span {
          display: inline-flex;
          align-items: baseline;
          justify-content: center;
          height: 16px;

          i.backslash {
            transform: rotateY(180deg);
            margin-left: 5px;
          }
        }
      }

    }

    .audio-area {
      display: flex;
      align-items: center;
      font-size: 0.28rem;
      justify-content: space-between;
      margin-top: 0.2rem;
      padding: 0 0.25rem;
      height: 0.6rem;

      .btn-info {
        border: none;
        margin: 0 0.06rem;

        &:before {
          background: #fff;
          border: none;
        }
      }

      .no-text {
        color: #9e9e9e;
        font-size: 0.24rem;
      }
    }

    .piyue {
      display: flex;
      flex-direction: column;
      justify-content: space-between;
      padding: 0.16rem 0;
      height: calc(100% - 2rem);
      align-content: center;

      .playing-area {
        height: 49%;
        width: 94%;
        margin: 0.16rem auto;
      }

      .mark-area {
        width: 94%;
        margin: auto;
        height: 49%;
      }

    }

    .footer {
      height: 1rem;
      display: flex;
      align-items: center;
      justify-content: space-between;
      padding: 0.16rem;
      background: #FFFFFF;
      box-shadow: 0 0 5px 6px #eeeeee;

      .audio-area {
        display: flex;
        align-items: center;
        font-size: 0.28rem;

        label {
          white-space: nowrap;
          word-break: keep-all;
          margin-right: 0.06rem;
        }

        .btn-info {
          border: none;
          margin-right: 0.06rem;

          &:before {
            background: #fff;
            border: none;
          }
        }

        .no-text {
          color: #9e9e9e;
          font-size: 0.24rem;
        }
      }
    }
  }

  .popover-text {
    padding: 0.16rem;
    font-size: 0.24rem;
  }
</style>
