<!--
  - Copyright (C) 2018-2019
  - All rights reserved, Designed By www.joolun.com
  芋道源码：
  ① 移除多余的 rep 为前缀的变量，让 message 消息更简单
  ② 代码优化，补充注释，提升阅读性
  ③ 优化消息的临时缓存策略，发送消息时，只清理被发送消息的 tab，不会强制切回到 text 输入
  ④ 支持发送【视频】消息时，支持新建视频
-->
<script lang="ts" setup>
import type { Reply } from './components/types';

import { computed, ref, unref, watch } from 'vue';

import { IconifyIcon } from '@vben/icons';

import { Row, Tabs } from 'ant-design-vue';

import TabImage from './components/TabImage.vue';
import TabMusic from './components/TabMusic.vue';
import TabNews from './components/TabNews.vue';
import TabText from './components/TabText.vue';
import TabVideo from './components/TabVideo.vue';
import TabVoice from './components/TabVoice.vue';
import { createEmptyReply, NewsType, ReplyType } from './components/types';

defineOptions({ name: 'WxReplySelect' });

const props = withDefaults(defineProps<Props>(), {
  newsType: undefined,
});
const emit = defineEmits<{
  (e: 'update:modelValue', v: Reply): void;
}>();

interface Props {
  modelValue: Reply;
  newsType?: NewsType;
}
const reply = computed<Reply>({
  get: () => props.modelValue,
  set: (val) => emit('update:modelValue', val),
});
// 作为多个标签保存各自Reply的缓存
const tabCache = new Map<ReplyType, Reply>();
// 采用独立的ref来保存当前tab，避免在watch标签变化，对reply进行赋值会产生了循环调用
const currentTab = ref<ReplyType>(props.modelValue.type || ReplyType.Text);

watch(
  currentTab,
  (newTab, oldTab) => {
    // 第一次进入：oldTab 为 undefined
    // 判断 newTab 是因为 Reply 为 Partial
    if (oldTab === undefined || newTab === undefined) {
      return;
    }

    tabCache.set(oldTab, unref(reply));

    // 从缓存里面取出新tab内容，有则覆盖Reply，没有则创建空Reply
    const temp = tabCache.get(newTab);
    if (temp) {
      reply.value = temp;
    } else {
      const newData = createEmptyReply(reply);
      newData.type = newTab;
      reply.value = newData;
    }
  },
  {
    immediate: true,
  },
);

/** 清除除了`type`, `accountId`的字段 */
const clear = () => {
  reply.value = createEmptyReply(reply);
};

defineExpose({
  clear,
});
</script>

<template>
  <Tabs v-model:active-key="currentTab" type="card">
    <!-- 类型 1：文本 -->
    <Tabs.TabPane :key="ReplyType.Text">
      <template #tab>
        <Row align="middle">
          <IconifyIcon icon="mdi:text" class="mr-1" />
          文本
        </Row>
      </template>
      <TabText v-model="reply.content" />
    </Tabs.TabPane>

    <!-- 类型 2：图片 -->
    <Tabs.TabPane :key="ReplyType.Image">
      <template #tab>
        <Row align="middle">
          <IconifyIcon icon="mdi:image" class="mr-1" />
          图片
        </Row>
      </template>
      <TabImage v-model="reply" />
    </Tabs.TabPane>

    <!-- 类型 3：语音 -->
    <Tabs.TabPane :key="ReplyType.Voice">
      <template #tab>
        <Row align="middle">
          <IconifyIcon icon="mdi:microphone" class="mr-1" />
          语音
        </Row>
      </template>
      <TabVoice v-model="reply" />
    </Tabs.TabPane>

    <!-- 类型 4：视频 -->
    <Tabs.TabPane :key="ReplyType.Video">
      <template #tab>
        <Row align="middle">
          <IconifyIcon icon="mdi:video" class="mr-1" />
          视频
        </Row>
      </template>
      <TabVideo v-model="reply" />
    </Tabs.TabPane>

    <!-- 类型 5：图文 -->
    <Tabs.TabPane :key="ReplyType.News">
      <template #tab>
        <Row align="middle">
          <IconifyIcon icon="mdi:newspaper" class="mr-1" />
          图文
        </Row>
      </template>
      <TabNews v-model="reply" :news-type="newsType" />
    </Tabs.TabPane>

    <!-- 类型 6：音乐 -->
    <Tabs.TabPane :key="ReplyType.Music">
      <template #tab>
        <Row align="middle">
          <IconifyIcon icon="mdi:music" class="mr-1" />
          音乐
        </Row>
      </template>
      <TabMusic v-model="reply" />
    </Tabs.TabPane>
  </Tabs>
</template>

<style lang="scss" scoped>
.select-item {
  width: 280px;
  padding: 10px;
  margin: 0 auto 10px;
  border: 1px solid #eaeaea;
}

.select-item2 {
  padding: 10px;
  margin: 0 auto 10px;
  border: 1px solid #eaeaea;
}

.ope-row {
  padding-top: 10px;
  text-align: center;
}

.input-margin-bottom {
  margin-bottom: 2%;
}

.item-name {
  overflow: hidden;
  text-overflow: ellipsis;
  font-size: 12px;
  text-align: center;
  white-space: nowrap;
}

.el-form-item__content {
  line-height: unset !important;
}

.col-select {
  width: 49.5%;
  height: 160px;
  padding: 50px 0;
  border: 1px solid rgb(234 234 234);
}

.col-select2 {
  height: 160px;
  padding: 50px 0;
  border: 1px solid rgb(234 234 234);
}

.col-add {
  float: right;
  width: 49.5%;
  height: 160px;
  padding: 50px 0;
  border: 1px solid rgb(234 234 234);
}

.avatar-uploader-icon {
  width: 100px !important;
  height: 100px !important;
  font-size: 28px;
  line-height: 100px !important;
  color: #8c939d;
  text-align: center;
  border: 1px solid #d9d9d9;
}

.material-img {
  width: 100%;
}

.thumb-div {
  display: inline-block;
  text-align: center;
}

.item-infos {
  width: 30%;
  margin: auto;
}
</style>
