interface ConsultMessage {
  id: string; //	咨询记录详情ID
  consultRecordId: number; //咨询记录ID
  sender: "user" | "agent" | "human" | "system";
  sendType: string; //	发送类型 1-患者 2-医生 3-系统 4-AI
  messageType: "1" | "2"; // 1文本 2 图片
  messageContent?: string; // 消息内容
  sendTime?: string; // 发送消息的时间
}
import I18nBehavior from "../../../../i18n/behavior";
import { Post } from "../../../../lib/request/method";
import { upload } from "../../../../lib/request/upload";
import dayjs from "dayjs";

const sendTypeMap: Record<string, "user" | "agent" | "human" | "system"> = {
  "1": "user", // 患者
  "2": "human", // 医生
  "3": "system", // 系统
  "4": "agent", // AI
};

// 计算底部安全区位置（rpx）
function calculateSafeBottomRpx(): number {
  const systemInfo = wx.getSystemInfoSync();
  // 获取窗口的高度
  const windowHeight = systemInfo.windowHeight;
  // 获取安全区底部的高度
  const safeAreaBottom = systemInfo.safeArea?.bottom ?? windowHeight;
  const safeBottom = windowHeight - safeAreaBottom;
  //将px转为rpx
  return (750 / systemInfo.windowWidth) * safeBottom;
}

function isConsultEndMessage(msg: ConsultMessage): boolean {
  if (msg.sendType !== "3" || !msg.messageContent) {
    return false;
  }
  const content = msg.messageContent;
  const isReminder =
    content.includes("30分钟") &&
    (content.includes("5分钟后") || content.includes("将在"));
  const isRealEnd = content.includes("咨询结束") && !isReminder;
  return isRealEnd;
}

// 获取的聊天消息为ConsultMessage格式                                           
function transformMessage(item: AnyObject): ConsultMessage {
  const sender = sendTypeMap[item.sendType];
  return {
    id: `msg-${item.id}`,
    consultRecordId: item.consultRecordId,
    sender,
    sendTime: item.sendTime || "",
    sendType: item.sendType,
    messageType: item.messageType as "1" | "2",
    messageContent: item.messageContent || "",
  };
}

Component({
  behaviors: [I18nBehavior],
  properties: {},
  data: {
    title: '',
    i18n: {
      consultChat: { _: '聊天' }
    },
    messages: [] as ConsultMessage[],
    inputText: "",
    inputFocus: true,
    inputBoxBottom: 0,
    baseInputBottom: 0,
    keepFocus: true,
    _keyboardHeight: 0, // 当前键盘高度
    isTransferredToHuman: false, // 是否已转人工
    consultEnded: false, // 是否已结束咨询
    _pollTimer: 0 as any, // 5秒轮询最新消息定时器
    textareaHeight: 80, // textarea 高度（rpx），初始值与 min-height 一致
  },
  observers: {
    'i18n.consultChat._'(this: any, title: string) {
      this.setData({ title });
    },
  },
  lifetimes: {
    async attached() {
      const safeBottomRpx = calculateSafeBottomRpx();
      const tabBarHeight = 100; // rpx
      const baseBottom = safeBottomRpx + tabBarHeight;
      // 获取咨询中的id
      const consultId = wx.getStorageSync("consultId");
      let messages: ConsultMessage[] = [];

      if (consultId) {
        try {
          // 获取所有消息的数据
          const res = await Post(`/consultManage/getAllMsgs/${consultId}`);
          if (res.data && res.data.length > 0) {
            messages = res.data.map((item: AnyObject) => {
              const msg = transformMessage(item);
              return msg;
            });
          }
        } catch (error: any) {
          wx.showToast({
            title: error?.errMsg || "获取历史消息失败",
            icon: "none",
          });
        }
      }

      const hasEndMessage = messages.some((msg: ConsultMessage) =>
        isConsultEndMessage(msg)
      );

      const consultEnded = hasEndMessage || wx.getStorageSync("consultEnded");
      this.setData({
        baseInputBottom: baseBottom,
        inputBoxBottom: baseBottom,
        messages,
        consultEnded: !!consultEnded,
      });
      this.triggerEvent("boxBottom", { inputBoxBottom: baseBottom });
      const kbHandler = (res: any) => {
        const height = res?.height ?? 0;

        // 键盘收起时，直接更新位置
        if (height === 0) {
          this._updateInputPosition(0);
          return;
        }

        if (this.data.inputFocus || this.data.keepFocus) {
          this._updateInputPosition(height);
        }
      };

      wx.onKeyboardHeightChange?.(kbHandler);
      (this as any)._kbHandler = kbHandler;

      this._ensureFocus();

      const systemInfo = wx.getSystemInfoSync();
      const isHarmonyOS =
        systemInfo.system &&
        systemInfo.system.toLowerCase().includes("harmony");
      const delayTime = isHarmonyOS ? 300 : 0;

      if (delayTime > 0) {
        setTimeout(() => {
          if (this.data._keyboardHeight > 0 && this.data.keepFocus) {
            this._updateInputPosition(this.data._keyboardHeight);
          }
        }, delayTime);
      }

      // 如果咨询未结束，启动轮询最新消息
      if (!consultEnded) {
        this._startPolling();
      }
    },
    detached() {
      // 清理监听
      if ((this as any)._kbHandler) {
        wx.offKeyboardHeightChange?.((this as any)._kbHandler);
      }
      this._stopPolling();
    },
  },
  methods: {
    _scrollToBottom() {
      this.triggerEvent("scroll", { id: "bottom" });
    },
    _hideKeyboardAndUpdatePosition() {
      wx.hideKeyboard?.();
      this.setData({
        inputFocus: false,
        keepFocus: false,
      });
      this._updateInputPosition(0);
    },
    _updateInputPosition(keyboardHeight: number) {
      const systemInfo = wx.getSystemInfoSync();
      const rpx2px = systemInfo.windowWidth / 750;

      const keyboardHeightRpx =
        keyboardHeight > 0 ? keyboardHeight / rpx2px : 0;

      const nextBottom =
        keyboardHeight > 0 ? keyboardHeightRpx : this.data.baseInputBottom;

      // 避免重复更新相同位置（容差1rpx）
      if (Math.abs(nextBottom - this.data.inputBoxBottom) < 1) {
        if (keyboardHeight !== this.data._keyboardHeight) {
          this.setData({ _keyboardHeight: keyboardHeight });
        }
        return;
      }

      this.setData({
        inputBoxBottom: nextBottom,
        _keyboardHeight: keyboardHeight,
      });

      this.triggerEvent("boxBottom", { inputBoxBottom: nextBottom });

      if (keyboardHeight > 0) {
        this.triggerEvent("scroll", { id: "bottom" });
      }
    },
    _ensureFocus() {
      if (!this.data.keepFocus) return;
      this.setData({ inputFocus: false });
      wx.nextTick?.(() => {
        setTimeout(() => {
          if (this.data.keepFocus) {
            this.setData({ inputFocus: true });
            setTimeout(() => {
              if (this.data._keyboardHeight > 0 && this.data.inputFocus) {
                this._updateInputPosition(this.data._keyboardHeight);
              }
            }, 150);
          }
        }, 120);
      });
    },
    tapPanel() {
      if (!this.data.inputFocus && this.data.keepFocus) {
        this._ensureFocus();
      }
    },
    endConsult() {
      // 收起键盘并更新位置
      this._hideKeyboardAndUpdatePosition();
      wx.showModal({
        title: "",
        content: `确定要结束本次？${this.data.title}`,
        cancelText: `继续${this.data.title}`,
        confirmText: "结束",
      }).then((res: any) => {
        if (res.confirm) {
          // 确认结束
          this._endConsult();
        } else {
          // 继续咨询，恢复聚焦
          this.setData({ keepFocus: true });
          this._ensureFocus();
        }
      });
    },
    async _endConsult() {
      const endDate = dayjs().format("MM-DD HH:mm:ss");

      const consultId = wx.getStorageSync("consultId");
      this._appendMessage({
        id: `end-time-${Date.now()}`,
        consultRecordId: consultId || 0,
        sender: "system",
        sendType: "3",
        messageType: "1",
        messageContent: `${this.data.title}结束`,
        sendTime: endDate,
      });

      // 调用结束咨询接口
      if (consultId) {
        try {
          await Post(`/consultManage/end/${consultId}`);
        } catch (error: any) {
          wx.showToast({
            title: error?.errMsg || `结束${this.data.title}失败`,
            icon: "none",
          });
        }
      }

      // 设置结束状态
      this.setData({ consultEnded: true });

      wx.setStorageSync("consultEnded", true);
      wx.removeStorageSync("consultId");
      this._stopPolling();

      // 收起键盘
      wx.hideKeyboard?.();

      // 重置底部位置为正常值（tabbar 高度 + 安全区高度）
      const safeBottomRpx = calculateSafeBottomRpx();
      const tabBarHeight = 100; // rpx
      const normalBottom = tabBarHeight + safeBottomRpx;

      this.triggerEvent("boxBottom", { inputBoxBottom: normalBottom });

      // 通知父组件显示guide菜单组件
      this.triggerEvent("consultEvent", { type: "end" });

      // 滚动到底部
      this._scrollToBottom();
    },
    handleInput(event: any) {
      const value = event.detail.value;
      this.setData({ inputText: value });

      // 内容为空时，立即重置为最小高度
      if (!value || value.trim() === "") {
        if (this.data.textareaHeight !== 80) {
          this.setData({ textareaHeight: 80 });
        }
      }
    },
    onLineChange(event: any) {
      const minHeight = 80; // 最小高度（rpx）
      const maxHeight = 200; // 最大高度（rpx）
      const lineCount = event.detail.lineCount || 1;

      // 如果输入框为空，直接设置为最小高度
      if (!this.data.inputText || this.data.inputText.trim() === "") {
        if (this.data.textareaHeight !== minHeight) {
          this.setData({ textareaHeight: minHeight });
        }
        return;
      }

      if (lineCount === 1) {
        if (this.data.textareaHeight !== minHeight) {
          this.setData({ textareaHeight: minHeight });
        }
        return;
      }

      const lineHeight = 53; // 每行高度（rpx）
      const padding = 24;

      const calculatedHeight = lineCount * lineHeight + padding;
      const finalHeight = Math.max(
        minHeight,
        Math.min(maxHeight, calculatedHeight)
      );

      if (Math.abs(this.data.textareaHeight - finalHeight) > 3) {
        this.setData({ textareaHeight: finalHeight });
      }
    },
    onInputFocus(event: any) {
      const keyboardHeight = event.detail.height ?? 0;

      // 设置 focus 状态
      this.setData({
        inputFocus: true,
        keepFocus: true,
      });

      if (keyboardHeight > 0) {
        this._updateInputPosition(keyboardHeight);
      } else {
        if (this.data._keyboardHeight > 0) {
          // 延迟一点时间，等待键盘完全弹起后再更新
          setTimeout(() => {
            if (this.data.inputFocus && this.data._keyboardHeight > 0) {
              this._updateInputPosition(this.data._keyboardHeight);
            }
          }, 100);
        }
      }
    },
    onInputBlur() {
      // 设置 focus 状态
      this.setData({
        inputFocus: false,
      });

      setTimeout(() => {
        if (!this.data.inputFocus) {
          this._updateInputPosition(0);
        }
      }, 100);
    },

    // 启动轮询最新消息
    _startPolling() {
      if (this.data.consultEnded) return;
      this._stopPolling();
      const timer = setInterval(() => {
        if (this.data.consultEnded) {
          this._stopPolling();
          return;
        }
        this._getLatestMessages();
      }, 5000);
      this.setData({ _pollTimer: timer });
    },
    _stopPolling() {
      if (this.data._pollTimer) {
        clearInterval(this.data._pollTimer);
        this.setData({ _pollTimer: 0 });
      }
    },
    // 获取最新消息
    async _getLatestMessages() {
      const consultId = wx.getStorageSync("consultId");
      if (!consultId) return;
      try {
        // 获取最新消息
        const res = await Post(`/consultManage/getLatestMsgs/${consultId}`);
        if (res.data && Array.isArray(res.data) && res.data.length > 0) {
          const newMessages = res.data.map((item: AnyObject) => {
            const msg = transformMessage(item);
            return msg;
          });
          const allMessages = [...this.data.messages, ...newMessages];
          this.setData({ messages: allMessages });

          const hasEndMessage = newMessages.some((msg: ConsultMessage) =>
            isConsultEndMessage(msg)
          );

          if (hasEndMessage && !this.data.consultEnded) {
            this.setData({ consultEnded: true });
            wx.setStorageSync("consultEnded", true);
            this._stopPolling();

            // 收起键盘
            wx.hideKeyboard?.();

            const safeBottomRpx = calculateSafeBottomRpx();
            const tabBarHeight = 100; // rpx
            const normalBottom = tabBarHeight + safeBottomRpx;

            this.triggerEvent("boxBottom", { inputBoxBottom: normalBottom });

            // 通知父组件显示guide菜单组件
            this.triggerEvent("consultEvent", { type: "end" });
          }

          this._scrollToBottom();
        }
      } catch (error: any) {
        wx.showToast({
          title: error?.errMsg || "获取最新消息失败",
          icon: "none",
        });
      }
    },
    // 发送消息到后端
    async _sendMessage(messageType: "1" | "2", messageContent: string) {
      const consultId = wx.getStorageSync("consultId");
      if (!consultId) {
        wx.showToast({ title: `${this.data.title}ID不存在`, icon: "none" });
        return;
      }
      try {
        await Post(`/consultManage/sendConsultMsg`, {
          consultRecordId: consultId,
          messageType,
          messageContent,
        }).then(() => {
          this._stopPolling();
          this._getLatestMessages();
          setTimeout(() => {
            if (!this.data.consultEnded) {
              this._startPolling();
            }
          }, 5000);
        });
      } catch (error: any) {
        wx.showToast({
          title: error?.errMsg || "发送失败，请重试",
          icon: "none",
        });
      }
    },
    async sendText() {
      const text = this.data.inputText.trim();
      if (!text) {
        wx.showToast({ title: "发送内容不能为空", icon: "none" });
        return;
      }
      const consultId = wx.getStorageSync("consultId");
      // 先添加用户消息到界面
      const messageId = `user-text-${Date.now()}`;
      this._appendMessage({
        id: messageId,
        consultRecordId: consultId || 0,
        sender: "user",
        sendType: "1",
        messageType: "1",
        messageContent: text,
      });
      this._scrollToBottom();
      // 发送信息
      this._sendMessage("1", text);

      // 保存当前键盘状态
      const wasFocused = this.data.inputFocus;
      const currentKeyboardHeight = this.data._keyboardHeight;

      this.setData({
        inputText: "",
        textareaHeight: 80,
      });

      if (!wasFocused) {
        this.setData({
          inputFocus: false,
          keepFocus: false,
        });
      } else {
        if (currentKeyboardHeight > 0) {
          this._updateInputPosition(currentKeyboardHeight);
        }
      }
    },
    async chooseImage() {
      const wasFocused = this.data.inputFocus;
      const currentKeyboardHeight = this.data._keyboardHeight;

      this._hideKeyboardAndUpdatePosition();

      try {
        const res = await wx.chooseMedia({
          count: 1,
          mediaType: ["image"],
          sourceType: ["album", "camera"],
        });
        const files = res.tempFiles ?? [];
        const file = files[0];
        if (!file?.tempFilePath) return;
        const imagePath = file.tempFilePath;
        // 直接发送图片
        await this._sendImageMessage(imagePath);

        if (wasFocused) {
          wx.nextTick?.(() => {
            setTimeout(() => {
              this.setData({
                inputFocus: true,
                keepFocus: true,
              });
              // 恢复键盘位置
              if (currentKeyboardHeight > 0) {
                this._updateInputPosition(currentKeyboardHeight);
              }
            }, 200);
          });
        }
      } catch (error: any) {
        if (error.errMsg && !error.errMsg.includes("cancel")) {
          console.error("选择图片失败", error);
        }

        if (wasFocused) {
          wx.nextTick?.(() => {
            setTimeout(() => {
              this.setData({
                inputFocus: true,
                keepFocus: true,
              });
              // 恢复键盘位置
              if (currentKeyboardHeight > 0) {
                this._updateInputPosition(currentKeyboardHeight);
              }
            }, 200);
          });
        }
      }
    },
    // 发送图片
    async _sendImageMessage(imagePath: string) {
      const consultId = wx.getStorageSync("consultId");
      try {
        const messageId = `user-image-${Date.now()}`;
        this._appendMessage({
          id: messageId,
          consultRecordId: consultId || 0,
          sender: "user",
          sendType: "1",
          messageType: "2",
          messageContent: imagePath,
        });

        // 上传图片
        const imageUrl = await upload({
          params: { name: "file", file: imagePath },
          transform({ data }: any) {
            return data?.url || data;
          },
        });

        // 发送图片消息
        await this._sendMessage("2", imageUrl);

        // 更新消息中的图片URL
        const messages = this.data.messages;
        const messageIndex = messages.findIndex(
          (msg: ConsultMessage) => msg.id === messageId
        );
        if (messageIndex !== -1) {
          messages[messageIndex].messageContent = imageUrl;
          this.setData({ messages });
        }
        this._scrollToBottom();
      } catch (error: any) {
        wx.showToast({
          title: error?.errMsg || "图片上传失败",
          icon: "none",
        });
      }
    },
    // 预览图片
    previewImage(e: any) {
      const currentUrl = e.currentTarget.dataset.url;
      const urls = this.data.messages
        .filter(
          (msg: ConsultMessage) => msg.messageType === "2" && msg.messageContent
        )
        .map((msg: ConsultMessage) => msg.messageContent!);
      wx.previewImage({
        current: currentUrl,
        urls: urls.length > 0 ? urls : [currentUrl],
        fail: (err) => {
          wx.showToast({
            title: err?.errMsg || "预览图片失败",
            icon: "none",
          });
        },
      });
    },
    _appendMessage(message: ConsultMessage) {
      // 把获取的最新的消息追加到所有消息后面
      const messages = [...this.data.messages, message];
      this.setData({ messages });
    },
  },
});
