<template>
  <div class="comment-editor" :id="info?.id">
    <div class="audio-area" v-if="!readonly || hasAudio">
      <audio-record :readonly="readonly" :model-value="content.audio" @update:model-value="audioRecord"></audio-record>
    </div>
    <div class="text-area" v-if="!readonly || content.text">
      <van-field :model-value="content.text" type="textarea" :readonly="readonly" autosize rows="1" @update:model-value="textInput($event)"
                 maxlength="200" :placeholder="readonly ? '' : '请输入'" />
    </div>
    <div class="video-area" :class="{empty: content.videos.length === 0}" v-if="!readonly || content.videos.length > 0">
      <upload-progress v-if="!readonly">
        <video-uploader :show-button="true" :downloadable="downloadable" :readonly="readonly" :model-value="content.videos" @update:model-value="videoUpload($event)" />
      </upload-progress>
      <template v-else><slot name="video"></slot></template>
    </div>
    <slot name="qupu"></slot>
    <div class="photo-area" :class="{empty: content.photos.length === 0}" v-if="!readonly || content.photos.length > 0">
      <photo-uploader multiple :do-upload="false" show-button :readonly="readonly" :model-value="content.photos" @update:model-value="photoUpload($event)" />
    </div>
    <div class="footer" :class="{justify: content.videos.length > 0 && piyueable}" v-if="!!info">
      <template v-if="content.videos.length > 0 && piyueable">
        <template v-if="!info.has_piyue">
          <span v-if="is_teacher"></span>
          <van-tag size="small" type="danger" v-else>未批阅</van-tag>
        </template>
        <van-tag size="small" type="success" v-else>已批阅</van-tag>
      </template>
      <div class="info">
        <span>{{info.creator_name}}</span><span>{{showDatetime(info.created_at)}}</span>
      </div>
    </div>
  </div>
</template>


<script lang="ts">
import {computed, defineComponent, getCurrentInstance, reactive, watch} from 'vue';
import {Button, Field, Tag} from 'vant'
import AudioRecord from './audio-record.vue';
import UploadProgress from './upload-progress.vue';
import VideoUploader from './video-uploader.vue';
import PhotoUploader from './photo-uploader.vue';
import QupuMap from "./qupu-map.vue";
import {HtyBaseRoles, RefResource, RefResourceTypes, TaskTypes, UploadPhoto} from "~/types";
import {DateFormatter, formatDate, MediaHelper} from '~/utils'
import useUser from "~/store/user";
import HtyVideo from "~/components/hty-video.vue";

export default defineComponent({
  name: "comment-editor",
  components: {
    [AudioRecord.name]: AudioRecord,
    [Field.name]: Field,
    [QupuMap.name]: QupuMap,
    [UploadProgress.name]: UploadProgress,
    [VideoUploader.name]: VideoUploader,
    [PhotoUploader.name]: PhotoUploader,
    [Button.name]: Button,
    [HtyVideo.name]: HtyVideo,
    [Tag.name]: Tag
  },
  props: ['modelValue', 'readonly', 'info', 'author', 'qupu', 'piyueable'],
  emits: ['update:modelValue'],
  setup(props) {
    const instance = getCurrentInstance();
    const usingUser = useUser()
    usingUser.loadMyTeachers();

    let content = reactive({
      audio: MediaHelper.audio_transform(props.modelValue?.audio),
      text: props.modelValue?.text,
      videos: props.modelValue?.video ?
          [{
            hty_resource_id: props.modelValue?.video.hty_resource_id,
            url: props.modelValue?.video.resource_url
          }] : [],
      photos: props.modelValue?.photos?.map(({hty_resource_id, resource_url, tasks, wx_cache, ...rest}: RefResource) => {
        let item: any = {id: hty_resource_id, url: resource_url, wx_cache};
        if (!wx_cache && !resource_url && tasks && tasks.vals[0]) {
          let { task_meta } = tasks.vals[0];
          let { media_id } = task_meta || {};
          if (media_id) {
            item.wx_cache = {serverId: media_id};
          }
        }
        return item;
      }) || []
    });

    watch(() => props.modelValue, () => {
      content.audio = MediaHelper.audio_transform(props.modelValue?.audio)
      content.text = props.modelValue?.text;
      if (props.modelValue?.video) {
        content.videos = [{
          hty_resource_id: props.modelValue?.video.hty_resource_id,
          url: props.modelValue?.video.resource_url
        }]
      } else {
        content.videos = []
      }

      content.photos = props.modelValue?.photos?.map(({hty_resource_id, resource_url, tasks, wx_cache, ...rest}: RefResource) => {
        let item: any = {hty_resource_id, url: resource_url, wx_cache};
        if (!wx_cache && !resource_url && tasks && tasks.vals[0]) {
          let { task_meta } = tasks.vals[0];
          let { media_id } = task_meta || {};
          if (media_id) {
            item.wx_cache = {serverId: media_id};
          }
        }
        return item;
      }) || []
    }, {deep: true});

    const hasAudio = computed(() => {
      let { audio_url, media_id } = content.audio;
      return audio_url || media_id;
    })

    const data = computed(() => props.modelValue)

    const audioRecord = ({media_id}: any) => {
      let task = { task_type: TaskTypes.CONVERT_AUDIO_FILE, task_meta: {media_id}}
      instance?.emit("update:modelValue", {...data.value, audio: {resource_type: RefResourceTypes.Audio, tasks: {vals: [task]}}})
    }

    const textInput = (value: string) => {
      instance?.emit("update:modelValue", {...data.value, text: value})
    }

    const videoUpload = (videos: any) => {
      let [video] = videos;
      if (video) {
        let { url, hty_resource_id, tasks } = video;
        instance?.emit("update:modelValue", {...data.value, video: {resource_url: url, hty_resource_id, resource_type: RefResourceTypes.Video, tasks}})
      } else {
        instance?.emit("update:modelValue", {...data.value, video: undefined})
      }
    }

    const photoUpload = (photos: UploadPhoto[]) => {
      instance?.emit("update:modelValue", {...data.value, photos: photos
            .map(({url, hty_resource_id, serverId, localId, localData, ...rest}) => {
              let item: RefResource = {...rest, resource_url: url, hty_resource_id, resource_type: RefResourceTypes.Picture}
              if (!url && serverId) {
                item.wx_cache = {serverId, localData, localId};
              }
              return item;
            })})
    }

    const showDatetime = (dt: string) => {
      return formatDate(dt, DateFormatter.DateTime);
    }

    const downloadable = computed(() => {
      if (!props.author) return true;
      const is_author = props.author === usingUser.store.current.hty_id;
      if (is_author) return true;
      return usingUser.store.teachers.mine.some(x => x.hty_id === props.author);
    })

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

    return {
      content, hasAudio, textInput, audioRecord, videoUpload, photoUpload, showDatetime,
      downloadable, is_teacher
    }
  }
});
</script>

<style scoped lang="less">

.comment-editor {
  width: calc(100% - 0.64rem);
  margin: 0 0.32rem 0.12rem;
  padding: 0.24rem 0.08rem;
  background: #eee;
  box-shadow: inset 0px 0px 5px 0px #ccc;
  border-radius: 4px;

  > div:not(:last-child) {
    margin-bottom: 0.16rem;
  }



  .audio-area {
    display: flex;
    align-items: center;
    justify-content: space-between;
    font-size: 0.2rem;
  }

  .text-area {
    font-size: 0.2rem;
    width: calc(100% - 0.32rem);
    margin: auto;
    background-clip: padding-box;
    border: 1px solid #dddddd;
  }

  .video-area {
    max-height: 30vh;
    height: 30vh;
    padding: 0 0.16rem;
    width: 100%;
    text-align: center;

    &.empty {
      height: auto;
      text-align: left;
    }

    :deep(.video-uploader) {
      height: 100%;
    }

  }

  .piyue-btn {
    text-align: center;
  }

  .photo-area {
    padding: 0 0.16rem;
    width: 100%;

    &.empty {
      height: auto;
    }

    :deep(.van-uploader__preview + .van-uploader__input-wrapper) {
      display: flex;
      align-items: center;
    }
  }

  .footer {
    font-size: 0.2rem;
    padding: 0 0.16rem;

    &.justify {
      display: flex;
      align-items: center;
      justify-content: space-between;
    }

    .info {
      text-align: right;

      span:first-child {
        margin-right: 0.1rem;
      }
    }

  }
}


</style>
