<template>
  <div class="main">
    <template v-if="ready">
      <div class="body">
        <van-pull-refresh v-model="refreshing" @refresh="refresh">
          <van-cell v-if="!nameState.editing" :label="entity.name">
            <template #value v-if="entity.is_yanqi">
              <span class="text-expired">已延期</span>
            </template>
            <template #title>
              <span>名称</span>
              <van-icon v-if="is_author && is_teacher" name="edit" @click="editName" class="name-editor"/>
            </template>
          </van-cell>
          <van-field v-if="nameState.editing" label="名称" v-model="nameState.text" required colon>
            <template #button>
              <van-button size="mini" type="primary" @click="saveName" icon="success"></van-button>
            </template>
          </van-field>
          <van-cell title="学生" :value="entity.group_name" :label="group_users"/>
          <van-cell title="课程" is-link :arrow-direction="show_courses ? 'up': 'down'" @click="show_courses = !show_courses">
            共 {{entity.course_sections.length}} 条课程
          </van-cell>
          <course-section-group :dataset="entity.course_sections" :show="show_courses" :can-modify="is_teacher && (is_assigned || is_author)" @modify="modify_course_section"/>
          <van-cell title="周期" :value-class="{'text-unwrap': true, 'text-expired': expired}" :value="period" />
          <van-cell title="批阅老师" v-if="entity.teachers?.vals?.length" :label="assigned_teachers"/>
          <van-cell title="备注" :value="entity.desc" />
          <van-cell :border="false" title="学生练习"></van-cell>
          <lianxi-group v-if="is_teacher" :total="entity.lianxi_count" :movements="entity.course_sections" @piyue="piyue" />
          <lianxi-group v-else :total="entity.lianxi_count" :movements="entity.course_sections" :removable="true" @remove="remove_lianxi" @piyue="view_piyue" />
        </van-pull-refresh>
      </div>
      <div class="footer">
        <van-badge v-if="comments_count || !expired" :content="comments_count" color="#0dcaf0" :show-zero="false" max="99">
          <van-button size="small" type="primary" @click="replying = true">留言回复</van-button>
        </van-badge>
        <template v-if="is_author && is_teacher && !entity.lianxi_count">
          <van-button size="small" type="primary" @click="$router.push('/daka/edit?id=' + entity.id)">编辑</van-button>
          <van-button size="small" type="danger" @click="onRemove()">删除</van-button>
        </template>
        <template v-if="!is_teacher && !expired">
          <van-button size="small" type="primary" @click="$router.push('/student/lianxi/add?daka_id=' + entity.id)">添加练习</van-button>
        </template>
        <van-button v-if="is_teacher && is_author" size="small" type="warning" @click="delaying = true">延期</van-button>
      </div>
    </template>
    <DetailSkeleton v-else/>
  </div>
  <van-calendar v-model:show="delaying" @confirm="onDelay" title="延期至"
                 :min-date="minDate" color="#1989fa"/>
  <van-action-sheet :lock-scroll="false" v-model:show="replying" title="留言回复" @close="removeComment" :close-on-click-overlay="false">
    <comments-sheet :disabled="expired" :ref_id="entity.id" :comment="commenting" @reply="replyComment" @submit="saveComment" @remove="removeComment"></comments-sheet>
  </van-action-sheet>
</template>

<script lang="ts">
import {computed, defineComponent, onBeforeUnmount, ref, onBeforeMount, reactive} from 'vue';
import {ActionSheet, Badge, Button, Cell, Field, Collapse, CollapseItem, Empty, Icon, PullRefresh, Calendar, Tag, showFailToast, showConfirmDialog} from 'vant';
import useDaka from "~/store/daka";
import {formatDate} from "~/utils";
import {useRouter} from "vue-router";
import {wxUtil} from "~/utils/wx";
import {Comment, CommentContent, CommentRefTypes, HtyBaseRoles, Lianxi, NotifyParam, NotifyTypes} from "~/types";
import AudioPlay from '~/components/audio-play.vue';
import dayjs from "dayjs";
import CommentsSheet from '~/components/comments-sheet.vue'
import ScoreShow from '~/components/score-show.vue';
import LianxiGroup from '~/components/lianxi-group.vue';
import useUser from '~/store/user';
import useUserGroup from '~/store/user-group';
import useComment from "~/store/comment";
import useTimer from "~/store/timer";
import CourseGroup from "~/components/qumu-section-group.vue";
import DetailSkeleton from '~/components/detail-skeleton.vue';
import useSession from "~/store/session";
export default defineComponent({
  name: "daka-detail",
  components: {
    DetailSkeleton,
    [Cell.name]: Cell,
    [Field.name]: Field,
    [Button.name]: Button,
    [ActionSheet.name]: ActionSheet,
    [Tag.name]: Tag,
    [Icon.name]: Icon,
    [AudioPlay.name]: AudioPlay,
    [Empty.name]: Empty,
    [PullRefresh.name]: PullRefresh,
    [Badge.name]: Badge,
    [CommentsSheet.name]: CommentsSheet,
    [ScoreShow.name]: ScoreShow,
    [LianxiGroup.name]: LianxiGroup,
    [Collapse.name]: Collapse,
    [CollapseItem.name]: CollapseItem,
    [CourseGroup.name]: CourseGroup,
    [Calendar.name]: Calendar,
  },
  props: {
    params: {}
  },
  setup({params}: any) {
    wxUtil.init(['playVoice', 'pauseVoice', 'stopVoice', 'onVoicePlayEnd', 'downloadVoice'])
    const {store, read, remove, check_tasks, notify, create_daka_comment, update, prepare, delete_daka_lianxi} = useDaka();
    const {count_comments} = useComment()
    const session = useSession();
    const usingUser = useUser();
    const {startTimer, stopTimer} = useTimer()
    const usingUserGroup  = useUserGroup();
    const router = useRouter();
    const period = computed(() => {
      let {start_date, duration_days, end_date} = store.current;
      return [formatDate(start_date), formatDate(end_date)].join(' ~ ') + ' (' + duration_days + '天)'
    });
    const replying = ref(false)
    const commenting = ref<Comment | null>(null)
    const entity = computed(() => store.current)
    const ready = ref(false)
    const delaying = ref(false)
    const nameState = reactive({editing: false, text: ''})
    
    const onRemove = () => {
      showConfirmDialog({
        title: "删除打卡",
        message: "操作不可撤销，确认删除当前打卡？"
      }).then(async () => {
        let r = await remove();
        if (r) {
          router.back();
        }
      });
    };

    const refreshing = ref(false);
    const show_courses = ref(false)

    const refresh = async () => {
      ready.value = false;
      await read(params?.id, true);
      refreshing.value = false;
      if (store.current.id) {
        stopTimer();
        startTimer(() => store.current, check_tasks)
      }
      ready.value = true
    }


    const notify_comment = ({comment_id, serial}: {comment_id: string, serial?: string}) => {
      let role = usingUser.store.currentRole;
      if (role === HtyBaseRoles.STUDENT) {
        // student comment, notify supervisor teacher first
          notify({
            notify_type: NotifyTypes.StudentCommentDaka,
            hty_id: store.current.teacher_id,
            daka_id: store.current.id,
            comment_id, serial
          }, HtyBaseRoles.TEACHER)
          // notify piyue-teacher
          store.current.teachers?.vals?.forEach(t => {
            notify({
              notify_type: NotifyTypes.StudentCommentDaka,
              hty_id: t.teacher_id,
              daka_id: store.current.id,
              comment_id, serial
            }, HtyBaseRoles.TEACHER)
          })
      } else {
        // teacher comment, notify all other teachers and all students
        let teachers = [...(store.current.teachers?.vals || []).map(t => t.teacher_id), store.current.teacher_id];
        teachers.forEach(t => {
          if (t === usingUser.store.current.hty_id) return;
          notify({
            notify_type: NotifyTypes.TeacherCommentDaka,
            hty_id: t, daka_id: store.current.id,
            comment_id, serial
          }, HtyBaseRoles.TEACHER)
        })
        let { mine, assigned } = usingUserGroup.store;
        let group = store.current.students?.val || [...mine, ...assigned].find(g => g.id === store.current.group_id)
        if (group) {
          group.users.vals.forEach(u => {
            let params: NotifyParam = {
              notify_type: NotifyTypes.TeacherCommentDaka,
              hty_id: u.user_id,
              daka_id: store.current.id,
              comment_id, serial
            }
            notify(params, HtyBaseRoles.STUDENT)
          })
        }
      }

    }

    const replyComment = (parent_id?: string) => {
      commenting.value = { parent_id, ref_type: CommentRefTypes.Daka, content: {} as CommentContent} as Comment
    }

    const saveComment = async () => {
      let comment = commenting.value as Comment;
      comment.ref_id = store.current.id;
      let created = await create_daka_comment(comment);
      if (created) {
        commenting.value = null;
        notify_comment({comment_id: created.id as string})
      }
    }

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

    const group_users = computed(() => {
      let { mine, assigned } = usingUserGroup.store;
      let group = store.current.students?.val || [...mine, ...assigned].find(g => g.id === store.current.group_id)
      return group?.users?.vals?.map(x => x.real_name).join(", ");
    })

    const assigned_teachers = computed(() => {
      return [store.current.teacher_name, ...(store.current.teachers?.vals?.map(x => x.teacher_name) || [])].join(", ")
    })

    onBeforeMount(async () => {
      ready.value = false;
      let { id, comment_id, qs, from_tongzhi } = params;
      await read(id, true);
      if (store.current.is_delete) {
        showConfirmDialog({
          message: "该打卡已被删除",
          cancelButtonText: "返回通知",
          confirmButtonText: "查看打卡列表",
          showCancelButton: !!from_tongzhi
        }).then(() => {
          router.replace("/daka")
        }).catch(() => {
          router.back();
        })
        return;
      }
      if (qs) {
        show_courses.value = true;
      }
      if (comment_id) {
        replying.value = true;
      }
      if (store.current.id) {
        session.write("DAKA", await prepare())
        startTimer(() => store.current, check_tasks)
      }
      await Promise.all([
        usingUserGroup.query("mine"),
        usingUserGroup.query("assigned")
      ]);
      ready.value = true
    })

    onBeforeUnmount(() => {
      session.clear()
      stopTimer()
    })

    const piyue = (lianxi: Lianxi) => {
      router.push(`/daka/piyue?daka_id=${store.current.id}&lianxi_id=${lianxi.id}`)
    }

    const expired = computed(() => dayjs(entity.value.end_date).valueOf() < dayjs().startOf('date').valueOf())

    const is_author = computed(() => entity.value.teacher_id === usingUser.store.current.hty_id);

    const is_teacher = computed(() => usingUser.store.currentRole === HtyBaseRoles.TEACHER)

    const comments_count = computed(() => count_comments(entity.value.id))

   const remove_lianxi = async (lianxi: Lianxi) => {
      if (lianxi.piyue) {
        showFailToast('该练习已有批阅，不能删除')
        return;
      }
     showConfirmDialog({
        title: "删除练习",
        message: "操作不可撤销，确认删除当前练习？"
      }).then(async () => {
        await delete_daka_lianxi(lianxi);
      }).catch(() => {})
    }


    const view_piyue = (lianxi: Lianxi) => {
      router.push(`/daka/piyue?daka_id=${store.current.id}&lianxi_id=${lianxi.id}`)
    }

    const modify_course_section = (qs_id: string) => {
      router.push(`/course/section/modify?daka_id=${store.current.id}&qs_id=${qs_id}`)
    }

    const is_assigned = computed(() => entity.value.teachers?.vals?.some(t => t.teacher_id === usingUser.store.current.hty_id) )

    const onDelay = async (date: Date) => {
      let {id, duration_days, end_date, is_yanqi} = store.current;
      store.current.duration_days = Math.floor((date.valueOf() - new Date(entity.value.start_date).valueOf()) / (1000 * 3600 * 24));
      console.log("duration...", entity.value.start_date, date)
      store.current.is_yanqi = true;
      let r = await update();
      if (r) {
        delaying.value = false;
        await read(id, true);
      } else {
        store.current.duration_days = duration_days;
        store.current.end_date = end_date;
        store.current.is_yanqi = is_yanqi;
      }
    }

    const minDate = computed(() => {
      let d = new Date()
      d.setDate(d.getDate() + 1)
      return d;
    })

    const editName = () => {
      nameState.editing = true;
      nameState.text = entity.value.name
    }

    const saveName = async () => {
      let {id, name} = store.current;
      if (nameState.text === name) {
        nameState.editing = false;
      } else {
        store.current.name = nameState.text;
        let r = await update();
        if (r) {
          nameState.editing = false;
          await read(id, true);
        } else {
          store.current.name = name;
        }
      }
    }

    return {
      entity, period, onRemove, piyue, refreshing, refresh, show_courses, expired, remove_lianxi, group_users, ready, is_teacher,
      commenting, replyComment, replying, saveComment, removeComment, is_author, view_piyue, comments_count, assigned_teachers,
      modify_course_section, is_assigned, onDelay, delaying, minDate, editName, nameState, saveName
    }
  }
});
</script>

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


    .body {
      height: calc(100% - 1.06rem);
      overflow: auto;
      background: #FFFFFF;
      &::-webkit-scrollbar {
        display: none;
      }

      .name-editor {
        font-size: 0.32rem;
        line-height: inherit;
        margin-left: 0.2rem;
        cursor: pointer;
        color: var(--van-button-danger-background);
      }

      :deep(.van-pull-refresh) {
        min-height: 100%;
      }

      .lianxis {
        box-shadow: inset 0 0 3px 8px #f2f3f5;
        padding: 8px;

        .course-right {
          display: inline-flex;
          align-items: center;

          span:first-child {
            margin-right: 5px;
            font-size: 0.2rem;
          }
        }

        .lianxi {
          margin-bottom: 0.32rem;
          border-top: 1px dashed #dddddd;
          padding: 0 0.32rem;

          &.hide {
            display: none;
          }

          .lianxi-line {
            padding: 0.2rem 0;
            font-size: 14px;
            display: flex;
            align-items: center;
            justify-content: space-between;

            &.double {
              display: block;
              .audio-area {
                display: flex;
                align-items: center;
                justify-content: space-between;
                margin-bottom: 0.1rem;
              }

              .lianxi-line-label {
                margin-bottom: 0.1rem;
              }
            }

            .text-area {
              background: #e9ecef;
              font-size: 12px;
              width: 100%;
              padding: 0.125rem 0.25rem;
              background-clip: padding-box;
              border-radius: 0.125rem;
            }
          }
        }
      }
    }

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

      .van-badge__wrapper {
        display: inline-flex;
      }

      button {
        width: 1.6rem;
      }
    }

  }
</style>
