<template>
  <div class="main">
    <div class="body">
      <h1 class="title">{{ entity?.course_name }}</h1>
      <h2 class="sections">
          {{ entity?.section_name }}
          <template v-if="entity?.course_category_name">
              ({{ entity?.course_category_name }})
          </template>
      </h2>
      <div class="desc" v-if="entity?.course_text">
        <h2>说明</h2>
        <div>
          <div v-for="line in entity?.course_text?.split('\n')">{{line}}</div>
        </div>
      </div>
      <div class="desc" v-if="entity?.teachers?.vals?.length">
        <h2>共享给老师</h2>
        <div>{{entity?.teachers?.vals?.map(v => v.teacher_name).join(", ")}}</div>
      </div>
      <div class="qupu">
        <h2>
          <span>图片</span>
          <div class="toolbar">
            <div class="toolbar-btn" v-if="state.allowMark">
              <van-button size="mini" :disabled="state.drawing || saving || !changed" type="primary" @click="piyue">保存标注</van-button>
            </div>
            <div class="toolbar-toggle" v-if="!disabled">
              <span class="action-label">{{state.allowMark ? '关闭': '打开'}}标注</span>
              <van-switch :disabled="state.drawing" v-model="state.allowMark" size="16" @change="closeMark()" />
            </div>
          </div>
        </h2>
        <div class="qupu-map-root" v-if="qupu_resource?.resource_url">
          <qupu-map :background-url="qupu_resource.resource_url" :marks="marks" :readonly="disabled || !state.allowMark"
                    @pause="pause" @draw="state.drawing = $event" @update="update($event)" />
        </div>
        <hty-image v-else-if="qupu_resource?.tasks" :task="qupu_resource?.tasks?.vals[0]" />
        <van-empty v-else description="暂无图片" />
      </div>
      <div class="example">
        <h2>视频<small>(标星的为示范曲)</small></h2>
        <upload-progress>
          <multi-video-uploader readonly :addable="false"  :model-value="videos" />
        </upload-progress>
      </div>
      <div class="example" v-if="audios?.length">
        <h2>音频<small>(标星的为示范曲)</small></h2>
        <audio-card readonly :model-value="audios"></audio-card>
      </div>
    </div>
    <div class="footer" v-if="isMine">
      <van-button type="primary" @click="$router.push('/course/section/edit?id=' + entity?.id)">编辑</van-button>
      <van-button type="danger" @click="onRemove()">删除</van-button>
      <van-button type="success" @click="onClone()">复制</van-button>
    </div>
    <div class="footer single" v-else-if="canEdit">
      <van-button type="primary" @click="$router.push('/course/section/edit?id=' + entity?.id)">编辑</van-button>
    </div>
  </div>
  <van-action-sheet :lock-scroll="false" v-model:show="state.replying" :title="'批注 ' + state.pausing"
                    @closeed="cancel" :close-on-click-overlay="false">
    <comments-sheet :disabled="disabled" :readonly="!state.allowMark" :ref_id="mark_id" v-model:comment="state.comment"
                    @submit="submit" @remove="remove">
    </comments-sheet>
  </van-action-sheet>
</template>

<script lang="ts">
import {computed, defineComponent, onBeforeMount, onBeforeUnmount, reactive, ref, watch} from 'vue';
import {ActionSheet, Button, Dialog, Loading, Switch, Toast, Empty, showConfirmDialog, showFailToast, showSuccessToast} from 'vant';
import {useRouter} from "vue-router";
import useCourseSection from "~/store/qumu-section";
import HtyImage from '~/components/hty-image.vue'
import MultiVideoUploader from '~/components/multi-video-uploader.vue';
import UploadProgress from '~/components/upload-progress.vue';
import {Comment, CommentRefTypes, HtyBaseRoles, RefResourceTypes, ResourceNote, RefResource, TaskFrom} from '~/types';
import useUser from "~/store/user";
import QupuMap from "~/components/qupu-map.vue";
import useComment from "~/store/comment";
import usePiyue from "~/store/piyue";
import CommentsSheet from "~/components/comments-sheet.vue";
import {is_equal} from "~/utils";
import useRefResource from "~/store/ref-resource";
import AudioCard from "~/components/audio-card.vue";
import useSupervisor from "~/store/supervisor";
import useTask from "~/store/task";

const marks_changed = (prev: string, cur: string) => {
  let prev_marks = JSON.parse(prev), cur_marks = JSON.parse(cur);
  if (prev_marks.length !== cur_marks.length) {
    return true;
  }
  for(let i = 0; i < cur_marks.length; i++) {
    let c = cur_marks[i];
    let p = prev_marks.find((x: ResourceNote) => c.serial_no === x.serial_no);
    if (!p) return true;
    if (c.marker?._leaflet_id !== p.marker?._leaflet_id) {
      return true;
    }
    let keys = ["id", "createdAt", "created_by", "note_type", "resource_pos", "comments", "comment", "lat_pos", "time_pos"];
    for (let j = 0; j < keys.length; j++) {
      if (!is_equal(p[keys[j]], c[keys[j]])) {
        return true;
      }
    }
  }
  return false;
}

export default defineComponent({
  name: "course-section-detail",
  components: {
    [AudioCard.name]: AudioCard,
    [Loading.name]: Loading,
    [Dialog.name]: Dialog,
    [Toast.name]: Toast,
    [Button.name]: Button,
    [HtyImage.name]: HtyImage,
    [MultiVideoUploader.name]: MultiVideoUploader,
    [UploadProgress.name]: UploadProgress,
    [QupuMap.name]: QupuMap,
    [CommentsSheet.name]: CommentsSheet,
    [ActionSheet.name]: ActionSheet,
    [Switch.name]: Switch,
    [Empty.name]: Empty
},
  props: {
    params: {} as any
  },
  setup(props: any) {
    const router = useRouter();
    const {store, read, remove_current, reset, clone} = useCourseSection(router);
    const {check_resources_task} = useRefResource();
    const {isTaskFinished} = useTask()
    const marks = ref<ResourceNote[]>([]);
    const timer = ref(0);
    const {create_comment, get_resource_note_group, check_resource_notes_task} = useComment();
    const {add_resource_notes, update_resource_notes} = usePiyue();
    const usingUser = useUser();
    const usingSupervisor = useSupervisor()
    let state = reactive({
      pausing: '',
      resizing: false,
      comment: null as (Comment | null),
      replying: false,
      allowMark: false,
      drawing: false
    });
    const saving = ref(false);

    let previous: string = "[]";

    const qupu_resource = computed(() => store.current.resources?.find(r => r.resource_type === RefResourceTypes.Picture))

    const has_pending_task = computed(() => {
      let r1 = store.current.resources?.some(r => r.tasks?.vals?.some(t => t.task_from !== TaskFrom.AI && !isTaskFinished(t.task_status)));
      let r2 = store.current.resource_note_group?.resource_notes?.some(r => r.comments?.some(c => c.ref_resources?.some(rr => rr.tasks?.vals?.some(t => !isTaskFinished(t.task_status)))));
      return r1 || r2
    })

    const timer_check = () => {
      if (!marks.value.length) {
        marks.value = store.current.resource_note_group?.resource_notes || [];
        previous = JSON.stringify(marks.value);
      }
      if (!has_pending_task.value) {
        clearInterval(timer.value);
        return;
      }
      check_resources_task(store.current.resources);
      check_resource_notes_task(store.current.resource_note_group)
    }

    const init = async () => {
        clearInterval(timer.value);
        await read(props.params?.id);
        await usingSupervisor.getSubsidiaries()
        if (store.current.id) {
            timer_check();
            timer.value = window.setInterval(() => {
                timer_check();
            }, 5000)
        }
    }

    watch(() => props.params, async (cur, prev) => {
        if (cur?.id !== prev?.id) {
            await init()
        }
    })

    onBeforeMount(init)

    const isMine = computed(() => {
      return store.current.created_by === usingUser.store.current.hty_id;
    })

    // if supervisor is added a shared teacher
    // supervisor can edit
    const canEdit = computed(() => {
      return store.current.teachers?.vals?.some(t => t.teacher_id === usingUser.store.current.hty_id) && usingSupervisor.store.subsidiaries.some(x => x.to_user_id === store.current.created_by)
    })


    const changed = computed(() => {
      return marks_changed(previous, JSON.stringify(marks.value), false);
    })

    onBeforeUnmount(() => {
      if (timer.value) {
        clearInterval(timer.value)
      }
      reset()
    })

    const onRemove = async () => {
      showConfirmDialog({
        title: "删除课程",
        message: "操作不可撤销，确认删除当前课程？"
      }).then(() => {
        remove_current();
      });
    };

    const submit = async () => {
      let {comment, pausing} = state;
      comment = comment as Comment
      let mark = marks.value.find((x: ResourceNote) => x.serial_no === pausing);
      if (mark && (!mark?.comments?.length || comment.id)) {
        mark.comment = comment;
        state.pausing = '';
        state.replying = false;
        state.comment = null;
      } else {
        comment.ref_id = mark?.id;
        comment.ref_type = CommentRefTypes.ResourceNote;
        await create_comment(comment);
      }

    }

    const remove = () => {
      state.replying = false;
      state.comment = null;
      if (state.allowMark) {
        let index = marks.value.findIndex((x: ResourceNote) => x.serial_no === state.pausing);
        marks.value.splice(index, 1);
      }
      // 后续的回复，如果删除，则仅删除当条回复，不删除标记
      state.pausing = '';
    }

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

    const pause = (data: ResourceNote) => {
      state.pausing = data.serial_no;
      state.replying = true;
      if (!data.comments?.length) {
        state.comment = data.comment || {
          ref_type: CommentRefTypes.Piyue,
          content: {text: ''}
        }
      } else if (state.allowMark) {
        state.comment = data.comments[0]
      }
    }

    const cancel = () => {
      state.pausing = '';
      state.replying = false;
      state.comment = null;
    }

    const piyue = async () => {
      if (saving.value) return;
      saving.value = true;
      let payload = {qupu: qupu_resource.value}
      let {resource_note_group} = store.current;
      let res;
      if (resource_note_group)  {
        res = await update_resource_notes(marks.value, payload, resource_note_group)
      } else {
        res = await add_resource_notes(marks.value, payload, store.current.id as string, "CourseSection");
      }
      // toggle status
      if (res) {
        showSuccessToast("保存成功！");
        await get_resource_note_group(store.current);
        marks.value = store.current.resource_note_group?.resource_notes || [];
        state.allowMark = false;
        previous = JSON.stringify(marks.value);
      }
      saving.value = false;
    }

    const mark_id = computed(() => {
      return marks.value.find((x: ResourceNote) => x.serial_no === state.pausing)?.id;
    })

    const entity = computed(() => store.current);

    const closeMark = () => {

      if (!state.allowMark && changed.value) {
        showFailToast("请先保存或还原所做更改！");
        state.allowMark = true;
      }

    }

    const onClone = () => {
        showConfirmDialog({
            message: "确认复制当前课程？"
        }).then(() => clone(router)).catch(() => {})
    }

    const videos = computed(() => store.current.resources?.filter(r => r.resource_type === RefResourceTypes.Video))
    const audios = computed(() => store.current.resources?.filter(r => r.resource_type === RefResourceTypes.Audio))

    const disabled = computed(() => usingUser.store.currentRole === HtyBaseRoles.TEACHER && usingUser.store.current.hty_id !== store.current.created_by)

    return {
      entity, onRemove, onClone, videos, audios, marks, disabled, pause, state, qupu_resource, mark_id, remove, cancel, submit, piyue, update, saving, changed, closeMark, isMine, canEdit
    };
  }

});
</script>

<style scoped lang="less">
  .main {

    .body {
      height: calc(100% - 1.06rem);
      padding: 0.32rem 0;
      overflow: auto;
    }

    .title {
      text-align: center;
      font-size: 0.48rem;
      margin-block-start: 0;
    }

    h2 {
      font-size: 0.32rem;
    }

    .sections {
      text-align: center;
      font-size: 0.36rem;
    }

    .desc {
      padding: 0 0.32rem;
      
      div {
        font-size: 0.24rem;
        color: #555;
        line-height: 1.5;
      }
    }

    .qupu {
      padding: 0 0.32rem;


      h2 {
        display: flex;
        align-items: center;
        justify-content: space-between;

        .toolbar {
          font-size: 0.24rem;
          font-family: unset;
          display: inline-flex;
          align-items: center;

          .toolbar-toggle {
            display: inline-flex;
            margin-left: 10px;
          }
        }
      }
      .qupu-map-root {
        height: 5rem;
      }
    }

    .example {
      padding: 0 0.32rem;
    }

    .footer {
      position: absolute;
      bottom: 0.16rem;
      width: 100%;
      padding: 0.01rem 0.32rem;
      display: flex;
      align-content: center;
      justify-content: space-between;

      button {
        width: 32%;
      }

      &.single {
        justify-content: center;

        button {
          width: 90%;
        }
      }
    }
  }
</style>
