<template>
  <view class="chat-container" @touchend="handleTouchEnd">
    <!-- 顶部的背景 -->
    <ChatTopBgImg class="chat-container-bg"></ChatTopBgImg>

    <view class="chat-content">
      <!-- 顶部自定义导航栏 -->
      <view
        class="nav-bar-container"
        :style="{
          paddingTop: statusBarHeight + 'px',
        }"
      >
        <ChatTopNavBar @openDrawer="openDrawer"></ChatTopNavBar>
      </view>

      <!-- 消息列表（可滚动区域） -->
      <scroll-view
        :scroll-top="scrollTop"
        scroll-y
        :scroll-with-animation="true"
        class="area-msg-list"
        @scroll="handleScroll"
        @scrolltolower="handleScrollToLower"
      >
        <!-- welcome栏 -->
        <ChatTopWelcome
          class="chat-container-top-bannar"
          :initPageImages="mainPageDataModel.initPageImages"
          :welcomeContent="mainPageDataModel.welcomeContent"
        >
        </ChatTopWelcome>

        <view
          class="area-msg-list-content"
          v-for="item in chatMsgList"
          :key="item.msgId"
          :id="item.msgId"
        >
          <template v-if="item.msgType === MessageRole.AI">
            <ChatCardAI
              class="message-item-ai"
              :key="`ai-${item.msgId}-${item.msg ? item.msg.length : 0}`"
              :text="item.msg || ''"
              ,
              :isLoading="item.isLoading"
            >
              <template #content v-if="item.toolCall">
                <QuickBookingComponent
                  v-if="
                    item.toolCall.componentName === CompName.quickBookingCard
                  "
                />
                <DiscoveryCardComponent
                  v-else-if="
                    item.toolCall.componentName === CompName.discoveryCard
                  "
                />
                <CreateServiceOrder
                  v-else-if="
                    item.toolCall.componentName === CompName.createWorkOrderCard
                  "
                />
                <DetailCardCompontent
                  v-else-if="item.toolCall.componentName === ''"
                  :toolCall="item.toolCall"
                />
              </template>

              <template #footer>
                <!-- 这个是底部 -->
                <AttachListComponent
                  v-if="item.question"
                  :question="item.question"
                  @replySent="handleReply"
                />
              </template>
            </ChatCardAI>
          </template>

          <template v-else-if="item.msgType === MessageRole.ME">
            <ChatCardMine class="message-item-mine" :text="item.msg">
            </ChatCardMine>
          </template>

          <template v-else>
            <ChatCardOther class="message-item-other" :text="item.msg">
              <ChatMoreTips
                @replySent="handleReply"
                :itemList="mainPageDataModel.guideWords"
              />

              <ActivityListComponent
                v-if="mainPageDataModel.activityList.length > 0"
                :activityList="mainPageDataModel.activityList"
              />

              <RecommendPostsComponent
                v-if="mainPageDataModel.recommendTheme.length > 0"
                :recommendThemeList="mainPageDataModel.recommendTheme"
              />
            </ChatCardOther>
          </template>
        </view>
      </scroll-view>

      <!-- 输入框区域 -->
      <view class="footer-area">
        <ChatQuickAccess @replySent="handleReplyInstruct" />
        <ChatInputArea
          ref="inputAreaRef"
          v-model="inputMessage"
          :holdKeyboard="holdKeyboard"
          :is-session-active="isSessionActive"
          :stop-request="stopRequest"
          @send="sendMessageAction"
          @noHideKeyboard="handleNoHideKeyboard"
          @keyboardShow="handleKeyboardShow"
          @keyboardHide="handleKeyboardHide"
        />
      </view>
    </view>
  </view>
</template>

<script setup>
import { onMounted, nextTick, onUnmounted, ref, defineEmits } from "vue";
import { onLoad } from "@dcloudio/uni-app";
import {
  SCROLL_TO_BOTTOM,
  RECOMMEND_POSTS_TITLE,
  SEND_COMMAND_TEXT,
} from "@/constant/constant";
import { WSS_URL } from "@/constant/base";
import { MessageRole, MessageType, CompName } from "../../model/ChatModel";
import ChatTopWelcome from "./ChatTopWelcome.vue";
import ChatTopBgImg from "./ChatTopBgImg.vue";
import ChatTopNavBar from "./ChatTopNavBar.vue";
import ChatCardAI from "./ChatCardAI.vue";
import ChatCardMine from "./ChatCardMine.vue";
import ChatCardOther from "./ChatCardOther.vue";
import ChatQuickAccess from "./ChatQuickAccess.vue";
import ChatMoreTips from "./ChatMoreTips.vue";
import ChatInputArea from "./ChatInputArea.vue";
import QuickBookingComponent from "../module/booking/QuickBookingComponent.vue";
import DiscoveryCardComponent from "../module/discovery/DiscoveryCardComponent.vue";
import ActivityListComponent from "../module/banner/ActivityListComponent.vue";
import RecommendPostsComponent from "../module/recommend/RecommendPostsComponent.vue";
import AttachListComponent from "../module/attach/AttachListComponent.vue";
import CreateServiceOrder from "@/components/CreateServiceOrder/index.vue";
import DetailCardCompontent from "../module/detail/DetailCardCompontent.vue";
import { mainPageData } from "@/request/api/MainPageDataApi";
import {
  conversationMsgList,
  recentConversation,
} from "@/request/api/ConversationApi";
import WebSocketManager from "@/utils/WebSocketManager";
import TypewriterManager from "@/utils/TypewriterManager";
import { IdUtils } from "@/utils";

/// 导航栏相关
const statusBarHeight = ref(20);
/// 输入框组件引用
const inputAreaRef = ref(null);

const timer = ref(null);
/// focus时，点击页面的时候不收起键盘
const holdKeyboard = ref(false);
/// 是否在键盘弹出，点击界面时关闭键盘
const holdKeyboardFlag = ref(true);
/// 是否显示键盘
const isKeyboardShow = ref(false);

///（控制滚动位置）
const scrollTop = ref(99999);

// 用户滚动状态控制
const isUserScrolling = ref(false);

/// 会话列表
const chatMsgList = ref([]);
/// 输入口的输入消息
const inputMessage = ref("");

/// 从个渠道获取如二维，没有的时候就返回首页的数据
const sceneId = ref("");
/// agentId 首页接口中获取
const agentId = ref("1");
/// 会话ID 历史数据接口中获取
const conversationId = ref("");
/// 首页的数据
const mainPageDataModel = ref({});

// 会话进行中标志
const isSessionActive = ref(false);
/// 指令
let commonType = "";

// WebSocket 相关
let webSocketManager = null;
// 打字机管理器
let typewriterManager = null;
// 当前会话的消息ID，用于保持发送和终止的messageId一致
let currentSessionMessageId = null;

let loadingTimer = null;

// 打开抽屉
const emits = defineEmits(["openDrawer"]);
const openDrawer = () => emits("openDrawer");

/// =============事件函数↓================
const handleTouchEnd = () => {
  clearTimeout(timer.value);
  timer.value = setTimeout(() => {
    // 键盘弹出时点击界面则关闭键盘
    if (holdKeyboardFlag.value && isKeyboardShow.value) {
      uni.hideKeyboard();
    }
    holdKeyboardFlag.value = true;
  }, 100);
};

// 点击输入框、发送按钮时，不收键盘
const handleNoHideKeyboard = () => (holdKeyboardFlag.value = false);

// 键盘弹起事件
const handleKeyboardShow = () => {
  isKeyboardShow.value = true;
  holdKeyboard.value = true;
  // 键盘弹起时调整聊天内容的底部边距并滚动到底部
  setTimeout(() => {
    scrollToBottom();
  }, 150);
};

// 键盘收起事件
const handleKeyboardHide = () => {
  isKeyboardShow.value = false;
  holdKeyboard.value = false;
};

// 处理用户滚动事件
const handleScroll = (e) => {
  // 标记用户正在滚动
};

// 处理滚动到底部事件
const handleScrollToLower = () => {};

// 滚动到底部 - 优化版本，确保打字机效果始终可见
const scrollToBottom = () => {
  nextTick(() => {
    scrollTop.value = 99999;
    // 强制触发滚动更新
    setTimeout(() => {
      scrollTop.value = scrollTop.value + Math.random();
    }, 10);
  });
};

// 延时滚动
const setTimeoutScrollToBottom = () => setTimeout(() => scrollToBottom(), 100);

// 发送普通消息
const handleReply = (text) => {
  // 重置消息状态，准备接收新的AI回复
  resetMessageState();
  sendMessage(text);
  setTimeoutScrollToBottom();
};

// 是发送指令
const handleReplyInstruct = (item) => {
  if (item.type === "MyOrder") {
    // 订单
    uni.navigateTo({
      url: "/pages/order/list",
    });
    return;
  }
  commonType = item.type;
  // 重置消息状态，准备接收新的AI回复
  resetMessageState();
  sendMessage(item.title, true);
  setTimeoutScrollToBottom();
};

//  输入区的发送消息事件
const sendMessageAction = (inputText) => {
  console.log("输入消息:", inputText);
  if (!inputText.trim()) return;
  handleNoHideKeyboard();

  currentSessionMessageId = IdUtils.generateMessageId();
  // 重置消息状态，准备接收新的AI回复
  resetMessageState();

  sendMessage(inputText);
  // 发送消息后保持键盘状态
  if (holdKeyboard.value && inputAreaRef.value) {
    setTimeout(() => {
      inputAreaRef.value.focusInput();
    }, 100);
  }

  setTimeoutScrollToBottom();
};

/// 添加通知
const addNoticeListener = () => {
  uni.$on(SCROLL_TO_BOTTOM, () => {
    setTimeout(() => {
      scrollToBottom();
    }, 200);
  });

  uni.$on(RECOMMEND_POSTS_TITLE, (value) => {
    console.log("RECOMMEND_POSTS_TITLE:", value);
    if (value && value.length > 0) {
      handleReply(value);
    }
  });

  uni.$on(SEND_COMMAND_TEXT, (value) => {
    console.log("SEND_COMMAND_TEXT:", value);
    if (value && value.length > 0) {
      commonType = "Command.quickBooking";
      sendMessage(value, true);
      setTimeoutScrollToBottom();
    }
  });
};

/// =============生命周期函数↓================
onLoad(() => {
  uni.getSystemInfo({
    success: (res) => {
      statusBarHeight.value = res.statusBarHeight || 20;
    },
  });
});

onMounted(async () => {
  try {
    getMainPageData();
    await loadRecentConversation();
    loadConversationMsgList();
    addNoticeListener();
    initTypewriterManager();
    initWebSocket();
    uni.getProvider({
      service: "oauth",
      success: (res) => {
        console.log("getProvider success", res);
      },
      fail: (err) => {
        console.log("getProvider fail", err);
      },
    });
  } catch (error) {
    console.error("页面初始化错误:", error);
  }
});

/// =============页面配置↓================
// 获取最近一次的会话id
const loadRecentConversation = async () => {
  const res = await recentConversation();
  if (res.code === 0) {
    conversationId.value = res.data.conversationId;
  }
};

// 加载历史消息的数据
let historyCurrentPageNum = 1;
const loadConversationMsgList = async () => {
  const args = {
    pageNum: historyCurrentPageNum++,
    pageSize: 10,
    conversationId: conversationId.value,
  };
  const res = await conversationMsgList(args);
};

// 获取首页数据
const getMainPageData = async () => {
  const res = await mainPageData(sceneId.value);
  if (res.code === 0) {
    mainPageDataModel.value = res.data;
    agentId.value = res.data.agentId;
    initData();
    setTimeoutScrollToBottom();
  }
};

/// =============对话↓================
// 初始化WebSocket
const initWebSocket = () => {
  // 清理旧实例
  if (webSocketManager) {
    webSocketManager.destroy();
  }

  // 使用配置的WebSocket服务器地址
  const token = uni.getStorageSync("token");
  const wsUrl = `${WSS_URL}?access_token=${token}`;

  // 初始化WebSocket管理器
  webSocketManager = new WebSocketManager({
    wsUrl: wsUrl,
    reconnectInterval: 3000, // 重连间隔
    maxReconnectAttempts: 5, // 最大重连次数
    heartbeatInterval: 30000, // 心跳间隔

    // 连接成功回调
    onOpen: (event) => {
      // 重置会话状态
      isSessionActive.value = true;
    },

    // 连接断开回调
    onClose: (event) => {
      console.error("WebSocket连接断开:", event);
      // 停止当前会话
      isSessionActive.value = false;
      // 停止打字机效果
      if (typewriterManager) {
        typewriterManager.stopTypewriter();
      }
    },

    // 错误回调
    onError: (error) => {
      isSessionActive.value = false;
      console.error("WebSocket错误:", error);
    },

    // 消息回调
    onMessage: (data) => {
      handleWebSocketMessage(data);
    },

    // 获取会话ID回调 (用于心跳检测)
    getConversationId: () => conversationId.value,

    // 获取代理ID回调 (用于心跳检测)
    getAgentId: () => agentId.value,
  });

  // 初始化连接
  webSocketManager.connect().catch((error) => {
    console.error("WebSocket连接失败:", error);
  });
};

// 处理WebSocket消息
const handleWebSocketMessage = (data) => {
  if (loadingTimer) {
    clearInterval(loadingTimer);
    loadingTimer = null;
  }

  const aiMsgIndex = chatMsgList.value.length - 1;
  if (!chatMsgList.value[aiMsgIndex] || aiMsgIndex < 0) {
    return;
  }

  // 确保消息内容是字符串类型
  if (data.content && typeof data.content !== "string") {
    data.content = String(data.content);
  }

  // 处理content分片内容
  if (data.content) {
    // 使用打字机管理器添加内容
    if (typewriterManager) {
      typewriterManager.addContent(data.content);
    }

    // 确保新内容到达时页面保持在底部
    setTimeoutScrollToBottom();
  }

  // 处理完成状态
  if (data.finish) {
    clearInterval(loadingTimer);
    loadingTimer = null;
    // 等待打字机完成后处理其他数据
    const waitForTypingComplete = () => {
      const status = typewriterManager
        ? typewriterManager.getStatus()
        : { isTyping: false };
      if (status.isTyping) {
        setTimeout(waitForTypingComplete, 50);
        return;
      }

      const msg = chatMsgList.value[aiMsgIndex].msg;
      console.log("全量消息内容:", msg);
      if (!msg || msg === "加载中." || msg.startsWith("加载中")) {
        chatMsgList.value[aiMsgIndex].msg = "未获取到内容，请重试";
        chatMsgList.value[aiMsgIndex].isLoading = false;
        if (data.toolCall) {
          chatMsgList.value[aiMsgIndex].msg = "";
        }
      }

      // 处理toolCall
      if (data.toolCall) {
        chatMsgList.value[aiMsgIndex].toolCall = data.toolCall;
      }

      // 处理question
      if (data.question && data.question.length > 0) {
        chatMsgList.value[aiMsgIndex].question = data.question;
      }

      // 重置会话状态
      isSessionActive.value = false;
    };

    waitForTypingComplete();
  }
};

// 初始化打字机管理器
const initTypewriterManager = () => {
  if (typewriterManager) {
    typewriterManager.destroy();
  }

  typewriterManager = new TypewriterManager({
    typingSpeed: 30,
    cursorText: "",
  });

  // 设置回调函数
  typewriterManager.setCallbacks({
    // 每个字符打字时的回调
    onCharacterTyped: (displayedContent) => {
      // 只有在用户没有滚动时才自动滚动到底部
      scrollToBottom();
    },
    // 内容更新时的回调
    onContentUpdate: (content) => {
      const aiMsgIndex = chatMsgList.value.length - 1;
      if (aiMsgIndex >= 0 && chatMsgList.value[aiMsgIndex]) {
        chatMsgList.value[aiMsgIndex].isLoading = false;
        chatMsgList.value[aiMsgIndex].msg = content;
      }
    },
    // 打字完成时的回调
    onTypingComplete: (finalContent) => {
      const aiMsgIndex = chatMsgList.value.length - 1;
      if (aiMsgIndex >= 0 && chatMsgList.value[aiMsgIndex]) {
        chatMsgList.value[aiMsgIndex].isLoading = false;
        chatMsgList.value[aiMsgIndex].msg = finalContent;
      }
      // 打字完成后最后一次滚动到底部
      setTimeoutScrollToBottom();
    },
  });
};

// 重置消息状态
const resetMessageState = () => {
  if (typewriterManager) {
    typewriterManager.reset();
  }
};

// 初始化数据 首次数据加载的时候
const initData = () => {
  const msg = {
    msgId: `msg_${0}`,
    msgType: MessageRole.OTHER,
    msg: "",
  };
  chatMsgList.value.push(msg);
};

// 发送消息的参数拼接
const sendMessage = (message, isInstruct = false) => {
  if (isSessionActive.value) {
    uni.showToast({
      title: "请等待当前回复完成",
      icon: "none",
    });
    return;
  }
  isSessionActive.value = true;
  const newMsg = {
    msgId: `msg_${chatMsgList.value.length}`,
    msgType: MessageRole.ME,
    msg: message,
    msgContent: {
      type: MessageType.TEXT,
      text: message,
    },
  };
  chatMsgList.value.push(newMsg);
  inputMessage.value = "";
  sendChat(message, isInstruct);
  console.log("发送的新消息：", JSON.stringify(newMsg));
};

// 通用WebSocket消息发送函数
const sendWebSocketMessage = (messageType, messageContent, options = {}) => {
  const args = {
    conversationId: conversationId.value,
    agentId: agentId.value,
    messageType: String(messageType), // 消息类型 0-对话 1-指令 2-中断停止 3-心跳检测
    messageContent: messageContent,
    messageId: currentSessionMessageId,
  };

  try {
    webSocketManager.sendMessage(args);
    console.log(`WebSocket消息已发送 [类型:${messageType}]:`, args);
    return true;
  } catch (error) {
    console.error("发送WebSocket消息失败:", error);
    isSessionActive.value = false;
    return false;
  }
};

// 发送获取AI聊天消息
const sendChat = (message, isInstruct = false) => {
  if (!webSocketManager || !webSocketManager.isConnected()) {
    console.error("WebSocket未连接");
    isSessionActive.value = false;
    return;
  }

  const messageType = isInstruct ? 1 : 0;
  const messageContent = isInstruct ? commonType : message;

  // 重置消息状态，为新消息做准备
  resetMessageState();

  // 插入AI消息
  const aiMsg = {
    msgId: `msg_${chatMsgList.value.length}`,
    msgType: MessageRole.AI,
    msg: "加载中.",
    isLoading: true,
    msgContent: {
      type: MessageType.TEXT,
      url: "",
    },
  };
  chatMsgList.value.push(aiMsg);
  const aiMsgIndex = chatMsgList.value.length - 1;

  // 动态加载中动画
  let dotCount = 1;
  loadingTimer && clearInterval(loadingTimer);
  loadingTimer = setInterval(() => {
    dotCount = (dotCount % 3) + 1;
    chatMsgList.value[aiMsgIndex].msg = "加载中" + ".".repeat(dotCount);
  }, 400);

  // 发送消息
  const success = sendWebSocketMessage(messageType, messageContent);
  if (!success) {
    chatMsgList.value[aiMsgIndex].msg = "发送消息失败，请重试";
    chatMsgList.value[aiMsgIndex].isLoading = false;
    isSessionActive.value = false;
    resetMessageState();
  }
};

// 停止请求函数
const stopRequest = () => {
  console.log("停止请求");

  // 发送中断消息给服务器 (messageType=2)
  sendWebSocketMessage(2, "stop_request", { silent: true });

  if (loadingTimer) {
    clearInterval(loadingTimer);
    loadingTimer = null;
  }

  // 停止打字机效果
  if (typewriterManager) {
    typewriterManager.stopTypewriter();
  }

  // 重置会话状态和消息状态
  isSessionActive.value = false;
  resetMessageState();

  // 更新最后一条AI消息的状态
  const aiMsgIndex = chatMsgList.value.length - 1;
  if (
    chatMsgList.value[aiMsgIndex] &&
    chatMsgList.value[aiMsgIndex].msgType === MessageRole.AI
  ) {
    chatMsgList.value[aiMsgIndex].isLoading = false;
    if (
      !chatMsgList.value[aiMsgIndex].msg ||
      chatMsgList.value[aiMsgIndex].msg.startsWith("加载中")
    ) {
      chatMsgList.value[aiMsgIndex].msg = "请求已停止";
    }
  }

  console.log("请求已停止，状态已重置");

  setTimeoutScrollToBottom();
};

// 组件销毁时清理资源
onUnmounted(() => {
  uni.$off(SCROLL_TO_BOTTOM);
  uni.$off(RECOMMEND_POSTS_TITLE);
  uni.$off(SEND_COMMAND_TEXT);

  // 清理WebSocket连接
  if (webSocketManager) {
    webSocketManager.destroy();
    webSocketManager = null;
  }

  // 清理打字机管理器
  if (typewriterManager) {
    typewriterManager.destroy();
    typewriterManager = null;
  }

  // 重置消息状态
  resetMessageState();

  // 清理定时器
  if (timer.value) {
    clearTimeout(timer.value);
    timer.value = null;
  }
});
</script>

<style lang="scss" scoped>
@import "styles/ChatMainList.scss";
</style>
