import { defineStore } from "pinia";

// #ifdef H5
const socketUrl = "http://192.168.1.42:2348";
// #endif
// #ifndef H5
const socketUrl = "ws://192.168.1.42:2348";
// #endif

// 聊天
export const useChatStore = defineStore("chat", {
  state: () => {
    return {
      socketUrl,
      isConnect: false,
      socketTask: null,
      onReceiveMsg: () => {},
      chatList: [],
      shop_id: "",
      group_id:'',

      // ========== Socket 保活与重连状态 ==========
      isManualClose: false, // 是否主动关闭（true：主动关闭，不重连；false：意外断开，自动重连）
      heartbeatTimer: null, // 心跳定时器
      reconnectTimer: null, // 重连定时器
      connectionMonitorTimer: null, // 连接状态监控定时器
      reconnectCount: 0, // 当前重连次数
      maxReconnectCount: 8, // 最大重连次数
      reconnectDelay: 1000, // 初始重连延迟（ms）
      maxReconnectDelay: 8000, // 最大重连延迟（ms）
      heartbeatInterval: 15000, // 心跳间隔15s

      // ========== 应用与网络状态监听 ==========
      isAppActive: true, // 应用是否在前台
      lastHeartbeatTime: 0, // 上次心跳时间戳
      _listenersInitialized: false, // 状态监听器是否已初始化

      // ========== 消息去重机制 ==========
      recentMessages: new Map(), // 最近处理的消息映射表：key=消息特征哈希，value=处理时间戳
      deduplicationWindow: 5000, // 去重时间窗口（5秒内相同消息只处理一次）
      maxRecentMessages: 100, // 最近消息缓存最大数量

      // ========== 连接状态锁 ==========
      isConnecting: false, // 是否正在建立连接（防止重复创建连接）
      lastConnectTime: 0, // 上次连接时间（防止短时间内频繁连接）

      // ========== 消息回调队列 ==========
      receiveMsgCallbacks: [], // 消息接收回调队列，支持多页面同时监听
    };
  },

  actions: {
    // ========== 初始化 ==========
    init() {
      if (!this.isConnect) {
        return uni.showToast({
          title: "请先连接socket",
          icon: "none",
        });
      }
      this.sendMessage(
        {
          type: "OnbocChat",
          operate_type: "init",
          shop_id: this.shop_id,
          token: uni.cache.get("token"),
        },
        false
      );
    },

    // ========== 发送消息（核心优化） ==========
    sendMessage(msg, isAutoAppend = true) {
      // 1. 主动关闭状态：提示用户
      if (this.isManualClose) {
        return uni.showToast({
          title: "Socket已主动关闭，请重新连接",
          icon: "none",
        });
      }

      // 2. 连接未建立或 SocketTask 已失效：立即重连并延迟发送
      if (!this.isConnect || !this.socketTask) {
        console.warn("Socket连接未建立，尝试重连...");
        // 立即重连
        this.forceReconnect();
        // 延迟发送，确保重连成功
        setTimeout(() => {
          this.sendMessage(msg, isAutoAppend);
        }, 1500); // 延长延迟时间，确保重连完成
        return;
      }

      // 3. 正常发送消息
      console.log("发送的消息", msg);
      const message = isAutoAppend
        ? {
            type: "OnbocChat",
            operate_type: "sendMsg",
            shop_id: this.shop_id,
            token:
              uni.getStorageSync("iToken")?.tokenValue ||
              uni.cache.get("token") ||
              "",
            ...msg,
          }
        : msg;

      try {
        this.socketTask.send({
          data: JSON.stringify(message),
          success: (res) => {
            console.log("发送成功", res);
          },
          fail: (error) => {
            console.error("发送失败，触发重连", error);
            // 发送失败，立即重连
            this.forceReconnect();
            // 重连后重试发送
            setTimeout(() => {
              this.sendMessage(msg, isAutoAppend);
            }, 1500);
          },
        });
      } catch (error) {
        console.error("发送消息异常，触发重连", error);
        // 捕获异常，立即重连
        this.forceReconnect();
        // 重连后重试发送
        setTimeout(() => {
          this.sendMessage(msg, isAutoAppend);
        }, 1500);
      }
    },

    // ========== 发送心跳包 ==========
    sendHeartbeat() {
      if (!this.isConnect || this.isManualClose || !this.socketTask) return;

      const now = Date.now();
      this.lastHeartbeatTime = now; // 记录心跳时间

      this.socketTask.send({
        data: JSON.stringify({
          type: "ping_interval",
        }),
        fail: (error) => {
          console.log("心跳发送失败，触发重连", error);
          this.forceReconnect();
        },
      });
    },

    // ========== 启动心跳定时器 ==========
    startHeartbeat() {
      // 清除旧定时器，避免重复
      if (this.heartbeatTimer) {
        clearInterval(this.heartbeatTimer);
      }

      // 立即发送一次心跳，确保连接活跃
      this.sendHeartbeat();

      // 每15s发送一次心跳
      this.heartbeatTimer = setInterval(() => {
        this.sendHeartbeat();
      }, this.heartbeatInterval);
    },

    // ========== 停止心跳定时器 ==========
    stopHeartbeat() {
      if (this.heartbeatTimer) {
        clearInterval(this.heartbeatTimer);
        this.heartbeatTimer = null;
      }
    },

    // ========== 启动连接状态监控 ==========
    startConnectionMonitor() {
      // 清除旧定时器
      if (this.connectionMonitorTimer) {
        clearInterval(this.connectionMonitorTimer);
      }

      // 每30秒检查一次连接状态
      this.connectionMonitorTimer = setInterval(() => {
        // 如果应该连接但实际未连接，触发重连
        if (!this.isManualClose && this.isConnect && !this.socketTask) {
          console.warn("连接监控：发现连接状态异常，强制重置");
          this.forceReconnect();
        }
      }, 30000);
    },

    // ========== 停止连接状态监控 ==========
    stopConnectionMonitor() {
      if (this.connectionMonitorTimer) {
        clearInterval(this.connectionMonitorTimer);
        this.connectionMonitorTimer = null;
      }
    },

    // ========== 智能重连逻辑 ==========
    reconnect() {
      // 1. 主动关闭或已连接：不重连
      if (this.isManualClose || this.isConnect) return;

      // 2. 正在连接中：不重连
      if (this.isConnecting) {
        console.log("正在建立连接中，跳过重连");
        return;
      }

      // 3. 短时间内已尝试连接：不重连（防止频繁连接）
      const now = Date.now();
      if (now - this.lastConnectTime < 1000) {
        console.log("短时间内已尝试连接，跳过重连");
        return;
      }

      // 4. 超过最大重连次数：停止重连
      if (this.reconnectCount >= this.maxReconnectCount) {
        console.log("已达最大重连次数，停止重连");
        return;
      }

      // 5. 清除旧重连定时器
      if (this.reconnectTimer) {
        clearTimeout(this.reconnectTimer);
      }

      // 6. 计算重连延迟（退避算法）
      const baseDelay = this.isAppActive ? 500 : this.reconnectDelay;
      const delay = Math.min(
        baseDelay * Math.pow(2, this.reconnectCount),
        this.maxReconnectDelay
      );

      console.log(`第${this.reconnectCount + 1}次重连，延迟${delay}ms`);

      // 7. 延迟执行重连
      this.reconnectTimer = setTimeout(() => {
        this.connectSocket();
        this.reconnectCount++;
      }, delay);
    },

    // ========== 强制重连方法 ==========
    forceReconnect() {
      // 主动关闭状态下不重连
      if (this.isManualClose) return;

      console.log("执行强制重连");

      // 1. 清理现有连接资源，强制重置所有状态
      if (this.socketTask) {
        try {
          this.socketTask.close({
            code: 1000, // 正常关闭
            reason: "force reconnect",
          });
        } catch (error) {
          console.error("关闭Socket失败", error);
        } finally {
          // 强制重置所有状态
          this.socketTask = null;
          this.isConnect = false;
          this.isConnecting = false;
        }
      }

      // 2. 重置重连状态
      this.reconnectCount = 0;
      this.stopHeartbeat();

      // 3. 立即重新连接
      setTimeout(() => {
        this.connectSocket();
      }, 100);
    },

    // ========== 内部关闭Socket方法（不设置手动关闭标记） ==========
    closeSocketInternal() {
      // 1. 停止所有定时器
      this.stopHeartbeat();
      this.stopConnectionMonitor();
      if (this.reconnectTimer) {
        clearTimeout(this.reconnectTimer);
        this.reconnectTimer = null;
      }

      // 2. 关闭Socket连接（Uniapp会自动清理监听器）
      if (this.socketTask) {
        try {
          this.socketTask.close({
            code: 1000, // 正常关闭
            reason: "internal close",
          });
        } catch (error) {
          console.error("关闭Socket失败", error);
        } finally {
          // 3. 重置状态
          this.socketTask = null;
          this.isConnect = false;
          this.isConnecting = false;
        }
      }
    },

    // ========== 初始化状态监听器 ==========
    initStateListeners() {
      // 避免重复初始化
      if (this._listenersInitialized) return;

      console.log("初始化状态监听器");

      // 监听应用前后台切换
      uni.onAppShow(() => {
        console.log("应用切前台，检查Socket连接");
        this.isAppActive = true;
        // 应用切前台，强制重连
        this.forceReconnect();
      });

      uni.onAppHide(() => {
        console.log("应用切后台");
        this.isAppActive = false;
      });

      // 监听网络状态变化
      uni.onNetworkStatusChange((res) => {
        console.log("网络状态变化", res);
        if (res.isConnected) {
          // 网络恢复，自动重连
          console.log("网络恢复，触发重连");
          this.forceReconnect();
        }
      });

      this._listenersInitialized = true;
    },

    // ========== 连接Socket ==========
    connectSocket() {
      // 1. 严格检查：避免重复连接
      if (this.isConnect || this.isConnecting || this.isManualClose) {
        console.warn("跳过连接：当前状态不允许建立新连接", {
          isConnect: this.isConnect,
          isConnecting: this.isConnecting,
          isManualClose: this.isManualClose,
        });
        // 关键：如果 socketTask 已失效但 isConnect 为 true，强制重置状态
        if (this.isConnect && !this.socketTask) {
          console.warn("Socket连接状态异常，强制重置");
          this.isConnect = false;
          this.forceReconnect();
        }
        return;
      }

      // 2. 设置连接中状态
      this.isConnecting = true;
      this.lastConnectTime = Date.now();

      // 3. 重置主动关闭标记
      this.isManualClose = false;

      console.log("开始创建新的Socket连接");

      // 4. 创建Socket连接
      this.socketTask = uni.connectSocket({
        url: this.socketUrl,
        success: (res) => {
          console.log("Socket连接请求发送成功");
        },
        fail: (res) => {
          console.log("Socket连接请求失败", res);
          // 请求失败，重置状态
          this.isConnecting = false;
          // 触发重连
          this.reconnect();
        },
      });

      // 5. 连接成功回调
      this.socketTask.onOpen((res) => {
        console.log("Socket连接成功");
        // 重置连接状态
        this.isConnect = true;
        this.isConnecting = false;
        this.reconnectCount = 0; // 重置重连次数

        this.init(); // 初始化聊天
        this.startHeartbeat(); // 启动心跳
        this.startConnectionMonitor(); // 启动连接状态监控

        // 初始化状态监听器
        this.initStateListeners();
      });

      // 6. 接收消息回调 - 支持多回调
      this.socketTask.onMessage((res) => {
        try {
          const data = JSON.parse(res.data);
          console.log("收到服务器消息", data);

          // 处理发送消息（服务器转发的自己发送的消息）
          if (data?.operate_type === "sendMsg") {
            // 添加方向标识：send
            const sendMsg = {
              ...data.data,
              direction: "send",
            };
            this.processMessage(sendMsg);
          }

          // 处理接收消息（他人发送的消息）
          if (data?.operate_type === "receive_msg") {
            // 添加方向标识：receive
            const receiveMsg = {
              ...data.data,
              coupon: data.data.coupon ? JSON.parse(data.data.coupon) : {},
              operate_type: "receive_msg",
              direction: "receive",
            };
            this.processMessage(receiveMsg);
          }

          // 处理心跳响应
          if (data?.operate_type === "heartbeat_ack") {
            console.log("心跳响应正常");
          }
        } catch (error) {
          console.error("消息解析失败", error);
        }
      });

      // 7. 连接错误回调
      this.socketTask.onError((res) => {
        console.log("Socket连接错误", res);
        // 重置连接状态
        this.isConnect = false;
        this.isConnecting = false;
        // 错误触发重连
        this.forceReconnect();
      });

      // 8. 连接关闭回调
      this.socketTask.onClose(() => {
        console.log("Socket连接已关闭");
        // 重置连接状态
        this.isConnect = false;
        this.isConnecting = false;
        this.stopHeartbeat(); // 停止心跳
        this.stopConnectionMonitor(); // 停止连接监控

        // 只有非主动关闭时才重连
        if (!this.isManualClose) {
          console.log("意外断开，触发重连");
          this.reconnect();
        } else {
          console.log("主动关闭，不重连");
        }
      });
    },

    // ========== 消息处理与去重 ==========
    processMessage(msg) {
      // 1. 生成消息特征哈希
      const msgHash = this.generateMessageHash(msg);
      const now = Date.now();

      // 2. 清理过期消息
      this.cleanupExpiredMessages(now);

      // 3. 去重逻辑：只对接收的消息应用严格去重
      if (msg.direction === "receive") {
        // 接收消息：5秒内相同特征的消息只处理一次
        const lastProcessTime = this.recentMessages.get(msgHash);
        if (
          lastProcessTime &&
          now - lastProcessTime < this.deduplicationWindow
        ) {
          console.log("重复接收消息，已忽略（特征哈希：", msgHash, "）");
          return; // 重复消息，直接返回
        }
        // 记录接收消息的处理时间
        this.recentMessages.set(msgHash, now);
      } else {
        // 发送消息：直接通过，不做严格去重
        console.log("发送消息，直接处理（特征哈希：", msgHash, "）");
      }

      // 4. 限制最近消息数量，避免内存泄漏
      if (this.recentMessages.size > this.maxRecentMessages) {
        // 移除最早的消息
        const firstKey = this.recentMessages.keys().next().value;
        this.recentMessages.delete(firstKey);
      }
      // 5. 正常处理消息

      if (this.group_id == msg.to_id) {
        this.chatList.unshift(msg);
      }

      // 6. 触发所有消息回调（支持多页面同时监听）
      this.triggerReceiveMsgCallbacks(msg);
    },

    // ========== 触发消息回调 ==========
    triggerReceiveMsgCallbacks(msg) {
      // 调用旧的单个回调（兼容原有代码）
      if (typeof this.onReceiveMsg === "function") {
        this.onReceiveMsg(msg);
      }

      // 调用所有注册的回调
      this.receiveMsgCallbacks.forEach((callback) => {
        if (typeof callback === "function") {
          callback(msg);
        }
      });
    },

    // ========== 注册消息回调 ==========
    registerReceiveMsgCallback(callback) {
      if (
        typeof callback === "function" &&
        !this.receiveMsgCallbacks.includes(callback)
      ) {
        this.receiveMsgCallbacks.push(callback);
      }
    },

    // ========== 移除消息回调 ==========
    removeReceiveMsgCallback(callback) {
      const index = this.receiveMsgCallbacks.indexOf(callback);
      if (index > -1) {
        this.receiveMsgCallbacks.splice(index, 1);
      }
    },

    // ========== 生成消息特征哈希 ==========
    generateMessageHash(msg) {
      // 基于消息的核心字段生成哈希
      const {
        content, // 消息内容
        msg_type, // 消息类型
        timestamp, // 时间戳
        operate_type, // 操作类型
        from_user_id, // 发送者ID
        to_user_id, // 接收者ID
        image_url, // 图片URL
        coupon, // 优惠券信息
        direction, // 消息方向
      } = msg;

      // 组合核心字段，生成唯一字符串
      // 发送消息添加随机数，确保每次发送的消息哈希唯一
      const msgFeatures = JSON.stringify({
        content: content || "",
        msg_type: msg_type || "",
        operate_type: operate_type || "",
        from_user_id: from_user_id || "",
        to_user_id: to_user_id || "",
        image_url: image_url || "",
        coupon_id: coupon?.id || "",
        direction: direction || "",
        // 发送消息添加随机数，确保每次发送的消息哈希唯一
        random:
          direction === "send" ? Math.random().toString(36).substr(2, 9) : "",
      });

      // 使用简单的哈希算法生成32位哈希值
      return this.simpleHash(msgFeatures);
    },

    // ========== 简单哈希算法 ==========
    simpleHash(str) {
      let hash = 0;
      for (let i = 0; i < str.length; i++) {
        const char = str.charCodeAt(i);
        hash = (hash << 5) - hash + char;
        hash = hash & hash; // 转换为32位整数
      }
      return Math.abs(hash).toString(16); // 转换为16进制字符串
    },

    // ========== 清理过期消息 ==========
    cleanupExpiredMessages(currentTime) {
      for (const [hash, time] of this.recentMessages.entries()) {
        if (currentTime - time > this.deduplicationWindow) {
          this.recentMessages.delete(hash);
        }
      }
    },

    // ========== 主动关闭Socket ==========
    closeSocket() {
      // 1. 设置主动关闭标记
      this.isManualClose = true;

      // 2. 关闭Socket连接（内部方法会处理状态重置）
      this.closeSocketInternal();

      console.log("Socket已主动关闭");
    },
  },

  unistorage: false, // 开启后对 state 的数据读写都将持久化
});
