// 环境配置
const environments = {
  development: {
    apiUrl: "https://test.hshuishang.com",
    picUrl: "https://test.hshuishang.com",
    aliyunOssUrl: "https://wechat-img-file-dev.oss-cn-beijing.aliyuncs.com",
    staticUrl: "https://static-dev.hshuishang.com",
  },
  production: {
    apiUrl: "https://api.hshuishang.com",
    picUrl: "https://api.hshuishang.com",
    aliyunOssUrl: "https://wechat-img-file.oss-cn-beijing.aliyuncs.com",
    staticUrl: "https://static.hshuishang.com",
  },
};

// 判断当前环境
const getCurrentEnvironment = () => {
  // 2. 微信小程序环境判断
  if (typeof wx !== "undefined" && wx.getAccountInfoSync) {
    try {
      const accountInfo = wx.getAccountInfoSync();
      const envVersion = accountInfo.miniProgram.envVersion;
      // 根据微信小程序环境返回对应环境标识
      if (envVersion === "release") {
        return "production"; // 正式版
      } else if (envVersion === "trial") {
        return "development"; // 体验版
      } else if (envVersion === "develop") {
        return "development"; // 开发版
      }
    } catch (e) {
      console.warn("获取小程序环境信息失败:", e);
    }
  }
  
  // 1. 优先通过NODE_ENV判断
  if (process && process.env && process.env.NODE_ENV) {
    return process.env.NODE_ENV;
  }

  // 3. 通过全局配置判断（例如Vercel等平台的环境变量）
  if (typeof global !== "undefined" && global.env) {
    return global.env;
  }

  // 4. 检查是否有全局的uni对象，可能是uni-app环境
  if (typeof uni !== "undefined") {
    // 可以根据实际情况添加更多uni-app环境的判断逻辑
  }

  // 默认返回生产环境，避免线上环境使用开发地址
  return "production";
};

// 获取当前环境配置
const currentEnv = getCurrentEnvironment();
const envConfig = environments[currentEnv] || environments.production;

export const RequsetUrl = envConfig.apiUrl; // 请求地址前缀
// 公开图片域名：统一走 CDN（dev: static-dev.hshuishang.com / prod: static.hshuishang.com）
export const picUrl = envConfig.staticUrl;
export const aliyunOssUrl = envConfig.aliyunOssUrl; // 阿里云OSS直链地址（私密文件签名 URL 已自带 host，一般不需要直接拼）
export const staticUrl = envConfig.staticUrl; // CDN 加速域名

/**
 * 处理图片URL，根据环境自动替换
 * @param {string} url - 原始图片URL
 * @returns {string} - 处理后的图片URL
 */
export const processImageUrl = (url) => {
  if (!url) return url;

  // 如果URL包含阿里云OSS地址，则根据环境替换
  if (url.includes(aliyunOssUrl)) {
    if (currentEnv === "production") {
      url = url.replace(aliyunOssUrl, staticUrl);

      return url;
    }
  }

  return url;
};

/**
 * @description 小程序跳转方法二次封装
 * @method NavgateTo
 * @param {String} path - 跳转的目标页面路径
 * @param {Object} options - 配置选项对象
 * @param {Boolean} options.isLogin - 是否需要校验登录态，默认为 true
 * @param {Boolean} options.forceReplace - 是否强制替换当前页面，解决webview数量限制问题，默认为 false
 */
export const NavgateTo = (path, options = {}) => {
  // 首页不需要登录验证
  if (path === "/pages/index/index") {
    uni.navigateTo({ url: path });
    return;
  }
  const { isLogin = true, forceReplace = false } = options;
  const ctoken = uni.getStorageSync("ctoken");

  // 登录校验
  if (isLogin && !ctoken) {
    uni.redirectTo({ url: "/pages/login/login" });
    return;
  }

  // 返回上一页
  if (path == "1") {
    uni.navigateBack({
      delta: 1,
    });
    return;
  }

  // 选择合适的跳转方式
  const navigateOptions = {
    url: path,
    fail: (err) => {
      // 处理webview数量限制错误
      if (err.errMsg && err.errMsg.includes("webview count limit")) {
        console.warn("检测到webview数量限制，自动切换为redirectTo模式");
        uni.redirectTo({ url: path });
      } else {
        console.error("页面跳转失败:", err);
      }
    },
  };

  // 如果强制替换，使用redirectTo
  if (forceReplace) {
    uni.redirectTo(navigateOptions);
  } else {
    uni.navigateTo(navigateOptions);
  }
};

/**
 * 封装请求方法
 * @param {string} url 请求地址
 * @param {string} method 请求方法
 * @param {Object} data 请求参数
 * @param {Object} options 配置选项对象
 * @param {Boolean} options.silent - 是否显示loading，默认为 true
 * @param {Boolean} options.nested - 是否平铺接口返回参数，默认为 false
 * @returns {Promise} 返回一个Promise对象
 */

export const request = (
  url,
  method = "POST",
  data = {},
  options = {},
  noLogin = true
) => {
  const { silent = true, nested = false } = options;

  let ctoken = null;
  if (options.token) {
    ctoken = options.token;
  } else {
    ctoken = uni.getStorageSync("ctoken"); // 后续接口强依赖强校验该字段
  }

  if (silent) {
    uni.showLoading({
      title: "加载中",
      mask: true,
    });
  }
  let params = {
    user_id: uni.getStorageSync("userId"),
    ...data,
  };
  return new Promise((resolve, reject) => {
    uni.request({
      url: RequsetUrl + url,
      method: method,
      data: params,
      header: {
        "Content-Type": "application/json",
        Authorization: ctoken,
        // ...header,
      },
      success: (res) => {
        // console.log('请求成功，接口返参', res);
        if (
          (res.statusCode == 401 && noLogin) ||
          (res.statusCode == 500 && res.data.msg == "效验令牌失败" && noLogin)
        ) {
          uni.removeStorageSync("ctoken");
          uni.removeStorageSync("userId");
          uni.removeStorageSync("is_worker");
          uni.showModal({
            title: "提示",
            content: "请登录后查看",
            confirmText: "去登陆",
            complete: (res) => {
              if (res.cancel) {
                uni.hideLoading();
                uni.redirectTo({
                  url: "/pages/index/index",
                });
                return;
              }

              if (res.confirm) {
                uni.redirectTo({
                  url: "/pages/login/login",
                });
              }
            },
          });
          return;
        }
        if (res.statusCode === 200) {
          if (silent) {
            uni.hideLoading();
          }
          if (options?.nested) {
            let data = {
              ...res.data,
            };
            resolve(data); // 请求成功
            return;
          }
          resolve(res.data.data); // 请求成功
        } else {
          console.log("走到这列",RequsetUrl, url,res.header,res.data,res.profile);
          uni.hideLoading();
          // uni.showToast({
          //   title: res.data.msg || "请求失败",
          //   icon: "none",
          // });

          reject({
            code: res.statusCode,
            message: res.data.msg || "请求失败",
            data: res.data,
          });
        }
      },
      fail: (err) => {
        uni.hideLoading();
        // uni.showToast({
        //   title: res.data.msg || "请求失败",
        //   icon: "none",
        // });
        reject({
          code: -1,
          message: "接口异常，请稍后重试",
          error: err,
        });
      },
    });
  });
};

/**
 * 校验手机号是否合法
 * @param {string} option 请求方法
 * @returns {Boolean} 手机号是否正确
 */
export const isPhone = (option) => {
  if (option.length != 11) {
    return false;
  }
  if (
    !/^1(3\d|4[5-9]|5[0-35-9]|6[2567]|7[0-8]|8\d|9[0-35-9])\d{8}$/.test(option)
  ) {
    return false;
  } else {
    return true;
  }
};

/**
 * 精确的浮点数运算
 * @param {number} num1 - 第一个数字
 * @param {number} num2 - 第二个数字
 * @param {string} operator - 运算符，支持 '+', '-', '*', '/', '+='
 * @returns {number} - 运算结果
 */
export const floatCalculate = (num1, num2, operator) => {
  // 获取小数位数
  function getPrecision(num) {
    const str = num.toString();
    const decimalIndex = str.indexOf(".");
    return decimalIndex === -1 ? 0 : str.length - decimalIndex - 1;
  }

  // 计算放大倍数
  const precision1 = getPrecision(num1);
  const precision2 = getPrecision(num2);
  const maxPrecision = Math.max(precision1, precision2);
  const factor = Math.pow(10, maxPrecision);

  // 将数字转换为整数
  const intNum1 = Math.round(num1 * factor);
  const intNum2 = Math.round(num2 * factor);

  // 根据运算符进行计算
  let result;
  switch (operator) {
    case "+":
      result = (intNum1 + intNum2) / factor;
      break;
    case "-":
      result = (intNum1 - intNum2) / factor;
      break;
    case "*":
      result = (intNum1 * intNum2) / (factor * factor);
      break;
    case "/":
      result = intNum1 / intNum2;
      break;
    case "+=":
      result = (intNum1 + intNum2) / factor;
      break;
    default:
      throw new Error("不支持的运算符");
  }

  return result;
};

/**
 * 图片上传 —— 走 OSS 直传，回调形状对齐旧后端 { code, data: { path } }，path 以 / 开头
 * @param {string} filename - 本地文件路径
 * @param {Function} fn      - 回调函数
 * @param {string}  [scene]  - 场景，默认 common
 */
export const upload = (filename, fn, scene = "common") => {
  // 引入此处避免顶层循环依赖
  const { uploadOSSCompat } = require("./uploadOSS.js");
  uploadOSSCompat(filename, fn, scene);
};

/**
 * 视频上传 —— 走 OSS 直传
 * @param {string} filename - 本地文件路径
 * @param {Function} fn      - 回调函数
 * @param {string}  [scene]  - 场景，默认 video
 */
export const uploadVideo = (filename, fn, scene = "video") => {
  const { uploadOSSCompat } = require("./uploadOSS.js");
  uploadOSSCompat(filename, fn, scene);
};

/**
 * 计算两地之间的距离
 * @param {string} lat1 第一个点的纬度
 * @param {string} lon1 第一个点的经度
 * @param {string} lat2 第二个点的纬度
 * @param {string} lon2 第二个点的经度
 * @returns {number} 距离
 */
export const calculateDistance = (lat1, lon1, lat2, lon2) => {
  // 将经纬度转换为弧度
  const toRad = (value) => (value * Math.PI) / 180;

  const R = 6371; // 地球半径（单位：千米）
  const dLat = toRad(lat2 - lat1);
  const dLon = toRad(lon2 - lon1);
  const a =
    Math.sin(dLat / 2) * Math.sin(dLat / 2) +
    Math.cos(toRad(lat1)) *
      Math.cos(toRad(lat2)) *
      Math.sin(dLon / 2) *
      Math.sin(dLon / 2);
  const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
  const distance = R * c; // 最终距离（单位：千米）
  return distance;
};
//
export const menuButtonInfo = () => {
  const systemInfo = uni.getSystemInfoSync();
  const platform = systemInfo.platform;

  if (platform === "ios") {
    // TODO: ios待测试
    return {
      height: systemInfo.statusBarHeight,
      top: 44,
    };
  }

  if (platform === "android") {
    return {
      height: systemInfo.statusBarHeight,
      top: 44, // 自定义导航栏默认高度
    };
  }

  if (systemInfo.uniPlatform === "mp-weixin") {
    // 微信小程序、支付宝小程序等，平台标识以 'mp-' 开头
    return uni.getMenuButtonBoundingClientRect();
  } else {
    return "Unknown";
  }
};

/**
 * 获取服务供应商
 * @param {string} opt - 服务类型
 * @returns {Promise} 返回一个Promise对象
 */
export const getProviderPromise = (opt) => {
  return new Promise((resolve, reject) => {
    uni.getProvider({
      service: opt,
      success: (res) => {
        console.log("获取支付服务提供商成功:", res.provider);
        resolve(res.provider);
      },
      fail: (err) => {
        console.error("获取支付服务提供商失败:", err);
        reject(err);
      },
    });
  });
};

//数组去重
export const uniqueByField = (arr, field) => {
  const seen = {};
  return arr.filter((item) => {
    const key = item[field];
    return seen.hasOwnProperty(key) ? false : (seen[key] = true);
  });
};

// 校验邮箱地址是否合法
export const validateEmail = (email) => {
  // 正则表达式验证邮箱格式
  const regex = /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/;
  if (!regex.test(email)) {
    return false;
  }

  return true;
};

/**
 * 防抖函数
 * @param {Function} fn 需要防抖的函数
 * @param {number} delay 延迟时间(毫秒)
 * @param {boolean} immediate 是否立即执行
 * @return {Function} 返回防抖处理后的函数
 */
export const debounce = (fn, delay = 300, immediate = false) => {
  let timer = null;

  return function (...args) {
    const context = this;

    if (timer) clearTimeout(timer);

    if (immediate && !timer) {
      fn.apply(context, args);
    }

    timer = setTimeout(() => {
      if (!immediate) {
        fn.apply(context, args);
      }
      timer = null;
    }, delay);
  };
};

/**
 * 格式化日期
 * @param {date} 时间戳
 */
export const formatDate = (date) => {
  const year = date.getFullYear();
  const month = String(date.getMonth() + 1).padStart(2, "0");
  const day = String(date.getDate()).padStart(2, "0");
  const hours = String(date.getHours()).padStart(2, "0");
  const minutes = String(date.getMinutes()).padStart(2, "0");
  const seconds = String(date.getSeconds()).padStart(2, "0");
  return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
};

