export const formatTimestamp = (timestamp) => {
  const date = new Date(timestamp);
  const year = date.getFullYear();
  const month = date.getMonth() + 1;
  const day = date.getDate();

  return `${year}-${month}-${day}`;
};

export const debounce = (fn, delay = 300) => {
  let timer = null;
  return async (...args) => {
    if (timer) clearTimeout(timer);
    return new Promise((resolve, reject) => {
      timer = setTimeout(async () => {
        try {
          const result = await fn(...args);
          resolve(result);
        } catch (error) {
          reject(error);
        } finally {
          timer = null;
        }
      }, delay);
    });
  };
};

export const isUnlimitedLimit = (item = {}) => Number(item.limit) === -1;

export const getLimitCountText = (label, item = {}) => {
  if (!item || isUnlimitedLimit(item)) return "";
  const count = Number(item.count || 0);
  const limit = Number(item.limit || 0);
  return `今日${label}次数：${count}/${limit}`;
};

export const isLimitReached = (item = {}) => {
  if (!item || isUnlimitedLimit(item)) return false;
  return Number(item.count || 0) >= Number(item.limit || 0);
};

export const isLimitError = (error) => {
  const message = typeof error === "string" ? error : error?.message;
  return String(message || "").includes("已达上限");
};

const isShareCancel = (error) =>
  String(error?.errMsg || error || "").toLowerCase().includes("cancel");

export const wxShare = async (canvasId = "shareCanvas") => {
  try {
    // 先尝试按 id 查找 <canvas type="2d"> 节点
    const { pixelRatio: dpr = 1 } = uni.getSystemInfoSync() || {};
    const info = await new Promise((resolve) => {
      const query = uni.createSelectorQuery();
      query
        .select(`#${canvasId}`)
        .fields({ node: true, size: true })
        .exec((res) => resolve(res && res[0]));
    });

    const canvas = info?.node;
    const cssWidth = info?.width;
    const cssHeight = info?.height;

    if (canvas && typeof canvas.getContext === "function") {
      // 2D 画布导出：传入 canvas 节点
      const tempPath = await new Promise((resolve, reject) => {
        uni.canvasToTempFilePath({
          canvas,
          width: cssWidth,
          height: cssHeight,
          // 按 DPR 导出更清晰的图片
          destWidth: Math.round(cssWidth * dpr),
          destHeight: Math.round(cssHeight * dpr),
          fileType: "png",
          quality: 1,
          success: (r) => {
            const p = r.tempFilePath || r.apFilePath || r.filePath;
            if (!p) {
              reject(new Error("share image path is empty"));
              return;
            }
            resolve(p);
          },
          fail: reject,
        });
      });
      await new Promise((resolve, reject) => {
        wx.showShareImageMenu({
          entrancePath: "pages/index",
          path: tempPath,
          success: resolve,
          fail: (error) => {
            if (isShareCancel(error)) {
              resolve({ canceled: true });
              return;
            }
            reject(error);
          },
        });
      });
      return tempPath;
    }

    // 回退：旧版非 2D 画布（通过 canvasId 导出）
    const res = await new Promise((resolve, reject) => {
      uni.canvasToTempFilePath({
        canvasId,
        fileType: "png",
        quality: 1,
        success: resolve,
        fail: reject,
      });
    });
    const tempPath = res.tempFilePath || res.apFilePath || res.filePath;
    if (!tempPath) {
      throw new Error("share image path is empty");
    }
    await new Promise((resolve, reject) => {
      wx.showShareImageMenu({
        entrancePath: "pages/index",
        path: tempPath,
        success: resolve,
        fail: (error) => {
          if (isShareCancel(error)) {
            resolve({ canceled: true });
            return;
          }
          reject(error);
        },
      });
    });
    return tempPath;
  } catch (error) {
    console.log("生成图片失败:", error);
    throw error;
  }
};

// 获取元素尺寸和位置信息
export const getElementRect = (classname) => {
  return new Promise((resolve) => {
    const query = uni.createSelectorQuery();
    query
      .select(classname)
      .boundingClientRect((rect) => {
        resolve(rect);
      })
      .exec();
  });
};

const calcNormalBowTarget = (x, y, diameter, arrowRadius) => {
  // 将弓箭左上角坐标转换为圆心坐标
  const arrowCenterX = x + arrowRadius;
  const arrowCenterY = y + arrowRadius;

  // 计算靶心坐标（靶纸中心）
  const centerX = (diameter + arrowRadius * 2) / 2;
  const centerY = (diameter + arrowRadius * 2) / 2;

  // 计算弓箭圆心到靶心的距离
  const deltaX = arrowCenterX - centerX;
  const deltaY = arrowCenterY - centerY;
  const distanceToCenter = Math.sqrt(deltaX * deltaX + deltaY * deltaY);

  // 计算弓箭边缘到靶心的最近距离
  const distance = Math.max(0, distanceToCenter - arrowRadius);

  // 计算靶纸半径（取宽高中较小值的一半）
  const targetRadius = diameter / 2;

  // 计算相对距离（0-1之间）
  let relativeDistance = distance / targetRadius;

  // 全环靶有10个环，每个环占半径的10%
  // 从外到内：1环到10环
  // 距离越近靶心，环数越高
  if (relativeDistance <= 0.05) return "X";
  if (relativeDistance <= 0.1) return 10;
  if (relativeDistance <= 0.2) return 9;
  if (relativeDistance <= 0.3) return 8;
  if (relativeDistance <= 0.4) return 7;
  if (relativeDistance <= 0.5) return 6;
  if (relativeDistance <= 0.6) return 5;
  if (relativeDistance <= 0.7) return 4;
  if (relativeDistance <= 0.8) return 3;
  if (relativeDistance <= 0.9) return 2;
  if (relativeDistance <= 1) return 1;
  return 0; // 脱靶
};

const calcHalfBowTarget = (x, y, diameter, arrowRadius, noX = false) => {
  // 将弓箭左上角坐标转换为圆心坐标
  const arrowCenterX = x + arrowRadius;
  const arrowCenterY = y + arrowRadius;

  // 计算靶心坐标（靶纸中心）
  const centerX = (diameter + arrowRadius * 2) / 2;
  const centerY = (diameter + arrowRadius * 2) / 2;

  // 计算弓箭圆心到靶心的距离
  const deltaX = arrowCenterX - centerX;
  const deltaY = arrowCenterY - centerY;
  const distanceToCenter = Math.sqrt(deltaX * deltaX + deltaY * deltaY);

  // 计算弓箭边缘到靶心的最近距离
  const distance = Math.max(0, distanceToCenter - arrowRadius);

  // 计算靶纸半径（取宽高中较小值的一半）
  const targetRadius = diameter / 2;

  // 计算相对距离（0-1之间）
  let relativeDistance = distance / targetRadius;
  if (relativeDistance <= 0.1) return noX ? 10 : "X";
  if (relativeDistance <= 0.2) return noX ? 9 : 10;
  if (relativeDistance <= 0.4) return 9;
  if (relativeDistance <= 0.6) return 8;
  if (relativeDistance <= 0.8) return 7;
  if (relativeDistance <= 1) return 6;

  return 0; // 脱靶
};

export const calcTripleBowTarget = (
  x,
  y,
  diameter,
  arrowRadius,
  noX = false
) => {
  const side = diameter * 0.325;
  if (y / diameter >= 0.661) {
    return calcHalfBowTarget(
      x - diameter * 0.336,
      y - diameter * 0.675,
      side,
      arrowRadius,
      noX
    );
  }
  if (y / diameter >= 0.323) {
    return calcHalfBowTarget(
      x - diameter * 0.336,
      y - diameter * 0.337,
      side,
      arrowRadius,
      noX
    );
  }
  if (y / diameter >= -0.026) {
    return calcHalfBowTarget(
      x - diameter * 0.336,
      y - diameter * 0.0,
      side,
      arrowRadius,
      noX
    );
  }
  return 0;
};

export const calcPinBowTarget = (x, y, diameter, arrowRadius, noX = false) => {
  const side = diameter * 0.482;
  let r1 = 0;
  let r2 = 0;
  let r3 = 0;
  if (x / diameter >= 0.23 && y / diameter >= 0.005) {
    r1 = calcHalfBowTarget(
      x - diameter * 0.26,
      y - diameter * 0.034,
      side,
      arrowRadius,
      noX
    );
  }
  if (x / diameter >= -0.03 && y / diameter >= 0.456) {
    r2 = calcHalfBowTarget(x, y - diameter * 0.484, side, arrowRadius, noX);
  }
  if (x / diameter >= 0.49 && y / diameter >= 0.456) {
    r3 = calcHalfBowTarget(
      x - diameter * 0.52,
      y - diameter * 0.485,
      side,
      arrowRadius,
      noX
    );
  }
  return r1 || r2 || r3;
};

export const calcRing = (bowtargetId, x, y, diameter, arrowRadius = 5) => {
  if (bowtargetId < 4) {
    return calcNormalBowTarget(x, y, diameter, arrowRadius);
  } else if (bowtargetId < 7) {
    return calcHalfBowTarget(x, y, diameter, arrowRadius);
  } else if (bowtargetId === 7) {
    return calcTripleBowTarget(x, y, diameter, arrowRadius);
  } else if (bowtargetId === 8) {
    return calcPinBowTarget(x, y, diameter, arrowRadius);
  } else if (bowtargetId === 9) {
    return calcTripleBowTarget(x, y, diameter, arrowRadius, true);
  } else if (bowtargetId === 10) {
    return calcPinBowTarget(x, y, diameter, arrowRadius, true);
  }
  return 0;
};

export const getDirectionText = (angle = 0) => {
  if (angle < 0) return "";
  if (angle >= 337.5 || angle < 22.5) {
    return "下";
  } else if (angle >= 22.5 && angle < 67.5) {
    return "左下";
  } else if (angle >= 67.5 && angle < 112.5) {
    return "左";
  } else if (angle >= 112.5 && angle < 157.5) {
    return "左上";
  } else if (angle >= 157.5 && angle < 202.5) {
    return "上";
  } else if (angle >= 202.5 && angle < 247.5) {
    return "右上";
  } else if (angle >= 247.5 && angle < 292.5) {
    return "右";
  } else if (angle >= 292.5 && angle < 337.5) {
    return "右下";
  }
};

export const wxLogin = () => {
  return new Promise((resolve, reject) => {
    uni.login({
      provider: "weixin",
      success: resolve,
      fail: (err) => {
        uni.showToast({
          title: "登录失败",
          icon: "none",
        });
        console.error("登录失败：", err);
        reject(err);
      },
    });
  });
};

export const canEenter = (user, device, online, page = "") => {
  const { miniProgram } = uni.getAccountInfoSync();
  if (!device.deviceId) {
    uni.showToast({
      title: "请先绑定设备",
      icon: "none",
    });
    return false;
  }
  if (miniProgram.envVersion !== "release") return true;
  if (!online) {
    uni.showToast({
      title: "智能弓未连接",
      icon: "none",
    });
    return false;
  }
  if (!user.trio && page !== "/pages/first-try") {
    uni.showToast({
      title: "请先完成新手试炼",
      icon: "none",
    });
    return false;
  }
  return true;
};

export const capsuleHeight = uni.getMenuButtonBoundingClientRect().top - 9;
