import { request } from "./request";

export const formatTime = (date: Date) => {
  const year = date.getFullYear()
  const month = date.getMonth() + 1
  const day = date.getDate()
  const hour = date.getHours()
  const minute = date.getMinutes()
  const second = date.getSeconds()

  return (
    [year, month, day].map(formatNumber).join('/') +
    ' ' +
    [hour, minute, second].map(formatNumber).join(':')
  )
}

const formatNumber = (n: number) => {
  const s = n.toString()
  return s[1] ? s : '0' + s
}


export function useSecondsToHMS(seconds: number) {
  const hour = Math.floor(seconds / 3600);
  const minute = Math.floor((seconds - hour * 3600) / 60);
  const second = Math.floor(seconds - hour * 3600 - minute * 60);
  let str = '';
  if (hour > 0) str += `${hour.toString().padStart(2, '0')}:`;
  str += `${minute.toString().padStart(2, '0')}:`;
  str += `${second.toString().padStart(2, '0')}`;
  return str;
}

/**将后端传过来的绝对值px转为相对值rpx,
*1rpx为屏幕宽度的750分之1，后台模拟界面写死为375px,
*所以1rpx为375/750=0.5px  1px为2rpx
*/
export function toRpx(px: number): number {
  return 2 * px
}

/**
 * 领取红包并拉起微信转账
 * @param data - 动态请求数据对象
 * @param url - 请求地址
 * @param appId - 当前小程序的 appId (也可选择从接口返回或 getAccountInfoSync 获取)
 * @returns Promise<void>
 */
export async function receiveRedPacket(data: any, url: string, appId: string): Promise<void> {
  wx.showLoading({ title: "领取中", mask: true });
  // 建议移除 3s 延迟。如果为了防抖，建议在外部触发点击事件时处理
  await new Promise(resolve => setTimeout(resolve, 3000));
  try {
    const res = await request<any>({
      options: {
        url,
        method: "POST",
        data
      },
      isLoading: false,
    });
    wx.hideLoading();
    if (res.code !== 200) {
      const title = res.msg || "领取失败";
      const duration = res.code === 503 ? 3000 : 1500;
      wx.showToast({ title, icon: "none", duration });
      throw new Error(res.msg || "领取失败");
    }

    const { packageInfo, mchId } = res.data || {};
    if (!packageInfo || !mchId) {
      wx.showToast({ title: "领取失败", icon: "none" });
      throw new Error("领取失败");
    }

    if (wx.canIUse?.("requestMerchantTransfer")) {
      // 把回调式 API 包装成 Promise，让调用方能正确捕获成功/失败
      await new Promise<void>((resolve, reject) => {
        // @ts-ignore
        wx.requestMerchantTransfer({
          mchId,
          appId,
          package: packageInfo,
          success: () => {
            wx.showToast({ title: "领取成功", icon: "success" });
            resolve();
          },
          fail: (err: any) => {
            console.error("拉起转账失败:", err);
            wx.showToast({ title: "领取失败", icon: "none" });
            reject(new Error(err?.errMsg || "领取失败"));
          },
        });
      });
    } else {
      wx.showModal({
        content: "你的微信版本过低，请更新至最新版本。",
        showCancel: false,
      });
      throw new Error("微信版本过低");
    }
  } catch (err: any) {
    wx.hideLoading();
    const msg = err?.data?.msg || err?.errMsg || err?.message || "领取失败";
    wx.showToast({ title: msg, icon: "none" });
    throw err;
  }
}

/**
 * 异步函数防并发锁
 * 直接用 lockPromise 包裹原有的点击逻辑
    handleReceiveClick: lockPromise(async function() {
      await receiveRedPacket(data, url, appId);
    })
 */
/**
 * 异步函数防并发锁
 * @param fn - 需要执行的异步函数
 */
export function lockPromise<T extends any[], R>(
  fn: (this: any, ...args: T) => Promise<R> | R
): (this: any, ...args: T) => Promise<R | void> {
  let isLocked = false;

  return async function (this: any, ...args: T): Promise<R | void> {
    // 如果正在执行中，直接返回，返回值为 void
    if (isLocked) return;

    isLocked = true;
    try {
      // 加上 return，确保原函数的返回值能够被向外传递
      return await fn.apply(this, args);
    } finally {
      isLocked = false;
    }
  };
}