// app.js
const api = require('./api/index.js'); // 注意路径
App({
  globalData: {
    socketTask: null,
    isConnected: false,
    reconnectTimer: null,
    heartbeatTimer: null,
    currentWorkorderId: '',
    userInfo: wx.getStorageSync('user') || {}
  },

  onLaunch() {
    // wx.setStorageSync('user', { userId: 'driver_1001', operationRole: 4 }); 
    this.initWebSocketService();
    wx.onAppShow(() => this.handleAppShow());
    wx.onAppHide(() => this.handleAppHide());
    this.locationService = {
      isTracking: false,
      currentWorkorderId: '', // 存储当前跟踪的工单ID
      isLocationUpdateStarted: false // 标记是否已启动定位服务
    };
  },

  initWebSocketService() {
    if (!this.wsService) {
      this.wsService = {
        connect: (url) => {
          const that = this;
          if (that.globalData.socketTask) {
            that.wsService.close();
          }

          console.log('正在连接WebSocket:', url);
          const socketTask = wx.connectSocket({ url, header: { 'content-type': 'application/json' } });

          socketTask.onOpen(() => {
            console.log('WebSocket 连接成功');
            that.globalData.isConnected = true;
            that.globalData.socketTask = socketTask;
            that.clearReconnectTimer();
            // that.startHeartbeat();
            if (that.globalData.currentWorkorderId) {
              that.wsService.send({ type: 'subscribe', workorderId: that.globalData.currentWorkorderId });
            }
            wx.$emit('socketOpen');
          });

          socketTask.onMessage((res) => {
            try {
              console.log(res);
              const message = JSON.parse(res.data);
              console.log('收到消息:', message);
              wx.$emit('wsMessage', message);
            } catch (err) { console.error('消息解析失败', err); }
          });

          socketTask.onClose((res) => {
            console.log('WebSocket 连接关闭, 状态码:', res.code);
            that.globalData.isConnected = false;
            that.globalData.socketTask = null;
            that.stopHeartbeat();
            wx.$emit('socketClose');
            if (res.code !== 1000) { that.startReconnect(); }
          });

          socketTask.onError((err) => {
            console.error('WebSocket 连接错误:', err);
            that.globalData.isConnected = false;
            that.globalData.socketTask = null;
            that.stopHeartbeat();
            wx.$emit('socketError', err);
          });
        },

        send: (data) => {
          const that = this;
          if (that.globalData.isConnected && that.globalData.socketTask) {
            try {
              that.globalData.socketTask.send({
                data: JSON.stringify(data),
                fail: (err) => {
                  console.error('消息发送失败:', err);
                  wx.showToast({ title: '消息发送失败', icon: 'none' });
                }
              });
            } catch (e) { console.error('消息序列化失败:', e); }
          } else {
            console.warn('WebSocket 未连接');
            wx.showToast({ title: '网络连接中...', icon: 'none' });
          }
        },

        close: (code = 1000, reason = 'normal close') => {
          const that = this;
          if (that.globalData.socketTask) {
            console.log(`关闭WebSocket连接: ${code} - ${reason}`);
            that.globalData.socketTask.close({ code, reason });
          }
        }
      };
    }
  },

  handleAppShow() {
    const that = this;
    console.log(!that.globalData.isConnected);
    console.log(!that.globalData.reconnectTimer);
    if (!that.globalData.isConnected && !that.globalData.reconnectTimer) {
      const { operationId, operationRole } = that.globalData.userInfo;
      console.log(operationRole);
      // 修复：startReconnect 中用了 operationId，这里统一字段
      if (!operationId) {
        console.error('用户operationId不存在，无法连接WebSocket');
        return;
      }
      const wsUrl = `wss://esos-iot.bjdexn.cn:9443/communication/update/${operationId}`;
      that.wsService.connect(wsUrl);
    }
  },

  handleAppHide() {
    // 可以选择在后台关闭连接
    // this.wsService.close(1001, 'app enter background');
  },

  startHeartbeat() {
    const that = this;
    that.stopHeartbeat();
    that.heartbeatTimer = setInterval(() => {
      if (that.globalData.isConnected) {
        that.wsService.send({ type: 'heartbeat', timestamp: Date.now() });
      }
    }, 5000);
  },

  stopHeartbeat() {
    if (this.heartbeatTimer) {
      clearInterval(this.heartbeatTimer);
      this.heartbeatTimer = null;
    }
  },

  startReconnect() {
    const that = this;
    that.clearReconnectTimer();
    let delay = 1000;
    that.globalData.reconnectTimer = setInterval(() => {
      if (!that.globalData.isConnected) {
        console.log(`尝试重连 in ${delay}ms...`);
        const { operationId, operationRole } = that.globalData.userInfo; // 修复：用 operationId 而非 userId
        if (operationId) {
          const wsUrl = `wss://esos-iot.bjdexn.cn:9443/communication/update/${operationId}`;
          that.wsService.connect(wsUrl);
        }
        delay = Math.min(delay * 2, 8000);
      } else {
        that.clearReconnectTimer();
      }
    }, delay);
  },

  clearReconnectTimer() {
    if (this.globalData.reconnectTimer) {
      clearInterval(this.globalData.reconnectTimer);
      this.globalData.reconnectTimer = null;
    }
  },

  /**
   * 司机端开始后台定位并上传（单工单）
   * @param {string} workorderId - 当前工单ID
   */
  startDriverLocationUpload(workorderId) {
    const service = this.locationService;

    // 入参校验
    if (!workorderId) {
      console.error('工单ID不能为空');
      wx.showToast({ title: '工单ID异常', icon: 'none' });
      return;
    }

    // 如果已经在为当前订单上传，则忽略
    if (service.isTracking && service.currentWorkorderId === workorderId) {
      console.log(`已经在为订单 ${workorderId} 上传位置`);
      return;
    }

    // 如果已经在为其他订单上传，先停止
    if (service.isTracking && service.currentWorkorderId !== workorderId) {
      console.log(`当前正在为订单 ${service.currentWorkorderId} 上传，切换到 ${workorderId}，先停止旧定位`);
      this.stopDriverLocationUpload();
    }

    // 权限校验
    wx.getSetting({
      success: (res) => {
        if (!res.authSetting['scope.userLocationBackground']) {
          wx.authorize({
            scope: 'scope.userLocationBackground',
            success: () => {
              this._doStartLocationUpload(workorderId, service);
            },
            fail: () => {
              wx.showModal({
                title: '权限不足',
                content: '需要开启后台定位权限才能实时上传位置，请前往设置页开启',
                confirmText: '去设置',
                success: (modalRes) => {
                  if (modalRes.confirm) {
                    wx.openSetting({
                      success: (settingRes) => {
                        if (settingRes.authSetting['scope.userLocationBackground']) {
                          this._doStartLocationUpload(workorderId, service);
                        }
                      }
                    });
                  }
                }
              });
            } 
          });
        } else {
          this._doStartLocationUpload(workorderId, service);
        }
      }
    });
  },

  /**
   * 私有方法：执行真正的定位启动逻辑（核心修复：兼容低版本，改用 wx.onLocationChange）
   */
  _doStartLocationUpload(workorderId, service) {
    console.log(`开始为订单 ${workorderId} 启动后台定位上传...`);
    service.currentWorkorderId = workorderId;

    // 修复1：先移除旧的定位监听（防止重复监听）
    this._removeLocationListener();

    // 修复2：启动后台定位（兼容低版本，用 startLocationUpdate 兜底）
    const startLocationApi = wx.startLocationUpdateBackground || wx.startLocationUpdate;
    startLocationApi({
      type: 'gcj02',
      success: (res) => {
        console.log('定位服务已启动', res);
        service.isLocationUpdateStarted = true;

        // 修复3：改用低版本支持的 wx.onLocationChange（替代 wx.watchPosition）
        wx.onLocationChange((location) => {
          console.log('位置变化，准备上传:', location);
          this._uploadLocation(location, workorderId);
        });

        // 标记定位中状态
        service.isTracking = true;
        console.log('位置监听已注册，开始实时上传');
      },
      fail: (err) => {
        let errMsg = '启动定位失败';
        if (err.errMsg.includes('auth deny')) errMsg = '定位权限被拒绝';
        else if (err.errMsg.includes('system')) errMsg = '系统不支持定位';
        
        console.error(errMsg, err);
        wx.showToast({ title: errMsg, icon: 'none', duration: 2000 });
      }
    });
  },

  /**
   * 司机端停止定位上传（核心修复：对应移除 wx.onLocationChange 监听）
   */
  stopDriverLocationUpload() {
    const service = this.locationService;

    if (!service.isTracking) {
      return;
    }

    console.log(`停止为订单 ${service.currentWorkorderId} 上传位置`);

    // 1. 移除位置监听（wx.onLocationChange 对应 wx.offLocationChange）
    this._removeLocationListener();

    // 2. 停止定位服务（兼容低版本，用 stopLocationUpdate 兜底）
    this._stopLocationService();

    // 3. 重置状态
    service.isTracking = false;
    service.currentWorkorderId = '';
    service.isLocationUpdateStarted = false;
  },

  /**
   * 私有方法：移除位置监听（兼容低版本）
   */
  _removeLocationListener() {
    if (wx.offLocationChange) {
      wx.offLocationChange();
      console.log('位置监听已移除');
    } else {
      console.warn('当前基础库不支持 wx.offLocationChange，可能存在重复监听风险');
    }
  },

  /**
   * 私有方法：统一停止定位服务（兼容低版本）
   */
  _stopLocationService() {
    const stopLocationApi = wx.stopLocationUpdateBackground || wx.stopLocationUpdate;
    if (stopLocationApi && this.locationService.isLocationUpdateStarted) {
      stopLocationApi({
        success: (res) => {
          console.log('定位服务已停止', res);
        },
        fail: (err) => {
          console.error('停止定位服务失败:', err);
        }
      });
    }
  },

  /**
   * 私有方法：上传位置到服务器（无改动）
   */
  _uploadLocation(location, workorderId, retryCount = 0) {
    const maxRetry = 2;
    const isLatValid = location.latitude >= 3.86 && location.latitude <= 53.55;
    const isLngValid = location.longitude >= 73.66 && location.longitude <= 135.05;

    if (!isLatValid || !isLngValid) {
      console.warn(`无效位置信息（订单: ${workorderId}），跳过上传`, location);
      return;
    }

    const data = {
      workorderId: workorderId,
      latitude: location.latitude,
      longitude: location.longitude,
      createTime: Date.now(),
      accuracy: location.accuracy
    };

    api.request(`/sysworkorder/insercoordinateredis`, 'post', data, { isPublic: false })
      .then((response) => {
        if (response.code !== 200) {
          throw new Error(`响应码异常: ${response.code}`);
        }
        console.log(`位置上传成功 (订单: ${workorderId})`, data);
      })
      .catch((err) => {
        console.error(`位置上传失败（第${retryCount+1}次）(订单: ${workorderId})`, err);
        if (retryCount < maxRetry) {
          setTimeout(() => {
            this._uploadLocation(location, workorderId, retryCount + 1);
          }, 10000 * (retryCount + 1));
        } else {
          wx.showToast({ title: '位置上传失败，请检查网络', icon: 'none' });
        }
      });
  },
});

// 全局事件总线
wx.$on = function (eventName, callback) {
  if (!this.$events) this.$events = {};
  if (!this.$events[eventName]) this.$events[eventName] = [];
  this.$events[eventName].push(callback);
};

wx.$emit = function (eventName, data) {
  if (!this.$events || !this.$events[eventName]) return;
  this.$events[eventName].forEach(callback => callback(data));
};

wx.$off = function (eventName, callback) {
  if (!this.$events || !this.$events[eventName]) return;
  if (callback) {
    this.$events[eventName] = this.$events[eventName].filter(cb => cb !== callback);
  } else {
    this.$events[eventName] = [];
  }
};
// 司机端增加人脸识别与指纹识别，
// 云平台12月份电价整理
