<template>
  <div
    class="container"
    :style="{ height: `calc(100% - ${currentBottomHeight}px)` }"
  >
    <div class="chat-bg"></div>
    <!-- 顶部导航 -->
    <div class="header-chat">
      <svg-icon class="page-icon" name="lf-arrow" @click="goBack" />
      <div class="header-title">群聊2（{{ wsStore.messages.length }}）</div>
      <svg-icon class="page-icon" name="more" @click="goDetail" />
    </div>

    <!-- 聊天消息区域 -->
    <div class="chat-list" ref="chatListRef">
      <div v-for="(item, index) in wsStore.messages" :key="index">
        <div class="chat-time">
          {{ formatTime(item.timestamp || Date.now()) }}
        </div>
        <div class="box">
          <div
            class="list-item"
            :class="
              walletStore.account == item.toUsername ? '' : 'flex-reverse'
            "
          >
            <!-- 头像 -->
            <van-image
              class="list-img"
              :class="walletStore.account == item.toUsername ? 'mr12' : 'ml12'"
              round
              src="https://fastly.jsdelivr.net/npm/@vant/assets/cat.jpeg"
              @click="router.push('personal')"
            />
            <!-- 内容 -->
            <div class="list-cont">
              <div>{{ item.fromUsername || "匿名用户" }}</div>
              <div class="content" v-if="item.contentType === 1">
                {{ item.content }}
              </div>
              <!-- 可扩展 contentType === 2 图片，3 名片等 -->
            </div>
          </div>
        </div>
      </div>
    </div>

    <!-- 输入框 -->
    <div class="page-foot">
      <div class="flex-box">
        <svg-icon
          type="button"
          class="page-icon"
          name="voice"
          @mousedown="startAudio"
          @touchstart="startAudio"
          @mouseup="sendAudioMessage"
          @touchend="sendAudioMessage"
        />
        <van-field
          rows="1"
          type="textarea"
          :border="false"
          autosize
          class="input"
          v-model="text"
          @focus="onFocus"
          placeholder="输入文本"
          @keyup.enter="sendMessage"
        />
        <svg-icon
          class="page-icon mr12 emoji-toggle"
          name="emoji"
          @click="toggleAppBox(1)"
        />
        <svg-icon
          class="page-icon tools-toggle"
          name="add2"
          @click="toggleAppBox(2)"
        />
      </div>

      <!-- 表情面板 -->
      <div
        class="app-box"
        v-show="showEmoji"
        :style="{ height: `${appBoxHeight}px` }"
        ref="emojiRef"
      >
        😀 😃 😄 😁 😆 😅 😂 🤣 😊 😇 🙂 🙃 😉 😌 😍
      </div>

      <!-- 工具栏面板 -->
      <div
        class="app-box"
        v-show="showTools"
        :style="{ height: `${appBoxHeight}px` }"
        ref="toolsRef"
      >
        <div class="tool-btn">
          <svg-icon class="tool-icon" name="tp" />
          <div>图片</div>
        </div>
        <div class="tool-btn">
          <svg-icon class="tool-icon" name="ps" />
          <div>拍摄</div>
        </div>
        <div class="tool-btn">
          <svg-icon class="tool-icon" name="yyth" />
          <div>语音通话</div>
        </div>
        <div class="tool-btn">
          <svg-icon class="tool-icon" name="spth" />
          <div>视频通话</div>
        </div>
        <div class="tool-btn">
          <svg-icon class="tool-icon" name="mp" />
          <div>名片</div>
        </div>
      </div>
    </div>
  </div>
</template>

<script setup>
import { ref, computed, onMounted, onUnmounted, onBeforeUnmount } from "vue";
import { useRouter, useRoute } from "vue-router";
import { useWebSocketStore } from "@/stores/modules/webSocketStore.js";
import { useWalletStore } from "@/stores/modules/walletStore.js";
import { Keyboard } from "@capacitor/keyboard";
import { Capacitor } from "@capacitor/core";
import { MSG_TYPE, MESSAGE_TYPE_USER } from "@/common/constant/msgType";
 

// 路由 & store
const router = useRouter();
const route = useRoute();
const wsStore = useWebSocketStore();
const walletStore = useWalletStore();

// 输入框文本
const text = ref("");

// 状态管理
const keyboardHeight = ref(0);
const showEmoji = ref(false);
const showTools = ref(false);
const appBoxHeight = ref(210);
const chatListRef = ref(null);
const emojiRef = ref(null);
const toolsRef = ref(null);

// 滚动到底部
const scrollToBottom = () => {
  nextTick(() => {
    if (chatListRef.value) {
      const el = chatListRef.value;
      el.scrollTop = el.scrollHeight;
    }
  });
};

watch(() => wsStore.messages.length, ()=>{
  scrollToBottom();
})

// 平台判断
const isMobile = Capacitor.getPlatform() !== "web";

// 底部高度动态计算
// 语音
const isTouchDevice = ref(false);
const mediaRecorder = ref(null); // 录音对象
const audioChunks = ref([]); // 录音数据

// 计算当前底部总高度
const currentBottomHeight = computed(() => {
  if (keyboardHeight.value > 0) return keyboardHeight.value;
  if (showEmoji.value || showTools.value) return appBoxHeight.value;
  return 0;
});

// 切换表情/工具面板
const toggleAppBox = async (type) => {
  if (isMobile) await Keyboard.hide();
  keyboardHeight.value = 0;
  if (type === 1) {
    showEmoji.value = !showEmoji.value;
    showTools.value = false;
  } else {
    showTools.value = !showTools.value;
    showEmoji.value = false;
  }
  scrollToBottom();
};

const onFocus = () => {
  // 隐藏所有面板
  showEmoji.value = false;
  showTools.value = false;
  if (isMobile) setupKeyboardListeners();
  scrollToBottom();
};

// 键盘监听
const setupKeyboardListeners = async () => {
  Keyboard.addListener("keyboardWillShow", (info) => {
    keyboardHeight.value = info.keyboardHeight;
  });

  Keyboard.addListener("keyboardWillHide", () => {
    keyboardHeight.value = 0;
  });
};

// 录音
const startAudio = async (event) => {
  if (event.type === "touchstart") {
    isTouchDevice.value = true;
  }

  // 如果是触摸设备且事件是鼠标事件，则忽略
  if (isTouchDevice.value && event.type === "mousedown") {
    return;
  }
  try {
    // 请求麦克风权限
    const stream = await navigator.mediaDevices.getUserMedia({ audio: true });

    // 创建 MediaRecorder 实例
    mediaRecorder.value = new MediaRecorder(stream, {
      mimeType: "audio/webm; codecs=opus",
    });

    // 收集音频数据
    mediaRecorder.value.ondataavailable = (e) => {
      audioChunks.value.push(e.data);
    };

    mediaRecorder.value.start(1000); // 每1秒收集一次数据
    console.log("Recording started");
  } catch (error) {
    console.error("Error accessing microphone:", error);
  }
};
// 停止录音
const stopRecording = async () => {
  return new Promise(async (resolve) => {
    if (!mediaRecorder.value) {
      resolve(new Uint8Array());
      return;
    }

    // 停止录音
    mediaRecorder.value.stop();
    mediaRecorder.value.stream.getTracks().forEach((track) => track.stop());

    // 等待最后的数据可用
    mediaRecorder.value.onstop = async () => {
      // 合并所有音频片段
      const audioBlob = new Blob(audioChunks.value, { type: "audio/webm" });

      // 转换为 Uint8Array
      const arrayBuffer = await audioBlob.arrayBuffer();
      const audioData = new Uint8Array(arrayBuffer);

      resolve(audioData);
    };
  });
};

const sendAudioMessage = async (event) => {
  if (isTouchDevice.value && event.type === "mouseup") {
    return;
  }
  console.log("发送音频消息");
  try {
    // 1. 停止录音并获取音频数据
    const audioData = await stopRecording();

    // 2. 准备消息体
    const message = {
      content: text.value, // 如果有文本内容
      contentType: MSG_TYPE.AUDIO, // 音频消息类型
      messageType: MESSAGE_TYPE_USER, // 单聊消息
      to: route.query.uuid, // 接收方ID
      fileSuffix: "webm", // 使用webm后缀更准确
      file: Array.from(audioData), // 将Uint8Array转为普通数组
    };

    // 3. 通过WebSocket发送
    wsStore.sendMessage(message);

    // 4. 重置状态
    mediaRecorder.value = null;
    audioChunks.value = [];
  } catch (error) {
    console.error("Error sending audio message:", error);
  }
};

// 发送消息
const sendMessage = () => {
  if (!text.value.trim()) return;
  const message = {
    content: text.value,
    contentType: MSG_TYPE.TEXT, // 1: 文本消息
    messageType: MESSAGE_TYPE_USER, // 1: 单聊天
    to: route.query.uuid,
  };
  wsStore.sendMessage(message);
  text.value = "";
  scrollToBottom();
};

// 时间格式化
const formatTime = (timestamp) => {
  const date = new Date(timestamp);
  const h = date.getHours().toString().padStart(2, "0");
  const m = date.getMinutes().toString().padStart(2, "0");
  return `${h}:${m}`;
};

// 页面生命周期
onMounted(() => {
  wsStore.getMessages({
    uuid: walletStore.account,
    messageType: 1,
    friendUsername: route.query.uuid,
  });
  scrollToBottom();
  document.addEventListener("click", handleClickOutside);
});

onUnmounted(() => {
  if (isMobile) Keyboard.removeAllListeners();
});
onBeforeUnmount(() => {
  document.removeEventListener("click", handleClickOutside);
});

// 判断是否点击在元素外
const handleClickOutside = (event) => {
  const emojiEl = emojiRef.value;
  const toolsEl = toolsRef.value;
  const target = event.target;

  if (
    showEmoji.value &&
    emojiEl &&
    !emojiEl.contains(target) &&
    !target.closest(".emoji-toggle")
  ) {
    showEmoji.value = false;
  }

  if (
    showTools.value &&
    toolsEl &&
    !toolsEl.contains(target) &&
    !target.closest(".tools-toggle")
  ) {
    showTools.value = false;
  }
};

// 页面跳转
const goBack = () => router.push("im");
const goDetail = () => router.push("detail");
</script>

<style lang="less" scoped>
.mr12 {
  margin-right: 12px;
}
.ml12 {
  margin-left: 12px;
}
.text-right {
  text-align: right;
}
.page-icon {
  width: 24px;
  height: 24px;
  flex-shrink: 0;
}
.container {
  display: flex;
  flex-direction: column;
  .chat-bg {
    height: 126px;
    background: linear-gradient(90deg, @theme-color1 0%, #40a4fb 100%);
    position: absolute;
    left: 0;
    right: 0;
    z-index: -1;
  }
  .header-chat {
    padding-top: 56px;
    margin: 0 16px;
    display: flex;
    align-items: center;
    color: @theme-color1;
    .header-title {
      flex: 1;
      font-family:
        PingFang SC,
        PingFang SC;
      font-weight: 500;
      font-size: 19px;
      color: #ffffff;
      text-align: center;
    }
  }
  .chat-list {
    background: #f7f8fa;
    border-radius: 30px 30px 0 0;
    flex: 1;
    overflow: auto;
    margin-top: 20px;
    padding: 0 16px 24px;
    .chat-time {
      font-family:
        PingFang SC,
        PingFang SC;
      font-weight: 400;
      font-size: 12px;
      color: #8d8d8d;
      text-align: center;
      margin: 20px 0;
    }
    .box {
      .list-item {
        display: flex;
        margin-bottom: 24px;
        .list-img {
          width: 44px;
          height: 44px;
          flex-shrink: 0;
        }
        .list-cont {
          font-family:
            PingFang SC,
            PingFang SC;
          font-weight: 400;
          font-size: 12px;
          color: #8d8d8d;
          max-width: 70%;
          display: flex;
          flex-direction: column;
          align-items: flex-start;
          .business-card {
            width: 199px;
            height: 93px;
            background: #ffffff;
            border-radius: 10px;
            margin-top: 8px;
            padding: 10px;
            box-sizing: border-box;
            .business-card-cont {
              display: flex;
              align-items: center;
              font-family:
                PingFang SC,
                PingFang SC;
              font-weight: 400;
              font-size: 15px;
              color: #000000;
            }
            .line {
              height: 1px;
              background: #f2f2f2;
              margin: 10px 0 6px;
            }
            .business-card-text {
              font-family:
                PingFang SC,
                PingFang SC;
              font-weight: 400;
              font-size: 10px;
              color: #8d8d8d;
            }
          }
          .content {
            background: #ffffff; // 对方消息背景白色
            color: #000;
            border-radius: 10px;
            margin-top: 8px;
            padding: 8px 17px;
            word-break: break-word;
            white-space: pre-wrap;
            max-width: 100%;
            font-family:
              PingFang SC,
              PingFang SC;
            font-weight: 400;
            font-size: 15px;
          }
        }
      }
      .withdrawal {
        display: flex;
        justify-content: center;
        margin-bottom: 24px;
        .withdrawal-text {
          width: 142px;
          height: 29px;
          line-height: 29px;
          box-sizing: border-box;
          background: #f2f2f2;
          border-radius: 4px;
          font-family:
            PingFang SC,
            PingFang SC;
          font-weight: 400;
          font-size: 12px;
          color: #8d8d8d;
          text-align: center;
        }
      }
      .flex-reverse {
        flex-direction: row-reverse;
      }
      .flex-reverse .list-cont {
        align-items: flex-end;
        .content {
          background: #4d71ff; // 自己的消息是蓝色
          color: #ffffff; // 白字
        }
      }
    }
  }
  .chat-list::-webkit-scrollbar {
    width: 0;
  }
  .page-foot {
    position: relative;
    background-color: #fff;
    .flex-box {
      padding: 8px 16px;
      display: flex;
      align-items: center;
      box-sizing: border-box;
      .input {
        flex: 1;
        background: #f2f2f2;
        border-radius: 17px;
        border: 1px solid #d8d8d8;
        padding: 6px 16px;
        font-weight: 500;
        font-size: 15px;
        margin: 0 12px;
        overflow-y: auto;
      }
    }
  }
}
.app-box {
  position: fixed;
  bottom: 210px;
  left: 0;
  right: 0;
  background: white;
  transition: transform 0.3s ease;
  transform: translateY(100%);
  display: flex;
  flex-wrap: wrap;
  padding: 10px 0 0 32px;

  &.visible {
    transform: translateY(0);
  }
  .tool-btn {
    margin-right: 32px;
    display: flex;
    flex-direction: column;
    align-items: center;
    font-family:
      PingFang SC,
      PingFang SC;
    font-weight: 400;
    font-size: 12px;
    color: #000000;
    .tool-icon {
      width: 56px;
      height: 56px;
      margin-bottom: 4px;
    }
  }
}

.page-foot {
  position: relative;
  z-index: 10; /* 确保输入框在上层 */
}
</style>
