// package-live/wxroom/index.ts
import VolcMiniSdk, { EVENTS } from "../volc-mini-sdk/index";
import { request } from "../../utils/request";
import { appId } from "../../env";
import { aesDecrypt, aesEncrypt } from "../../utils/crypto";
import { AES_KEY, AES_IV } from "../../env";
import { receiveRedPacket, lockPromise } from "../../utils/util";
const WXROOM_REDIRECT_PATH_KEY = "wxroomRedirectPath";
const WXROOM_PAGE_PATH = "/package-live/wxroom/index";

const isMobileEnvironment = (): boolean => {
  const platform = wx.getSystemInfoSync().platform?.toLowerCase() || '';
  return platform !== 'windows' && platform !== 'mac';
};

let pageOptionsCache: Record<string, string | undefined> = {};
Page({
  data: {
    sdk: null as any,
    activityId: 0,
    loading: false,
    loadingText: "",
    showError: false,
    errorTitle: "",
    errorMessage: "",
    inviterToken: "",
    msg: "",
    userId: "",
    isLandscape: false,
  },

  async onLoad(options: Record<string, string | undefined>) {
    pageOptionsCache = options || {};
    const activityId = this.getActivityId(options);
    if (!activityId) {
      this.handleEnterError(
        "缺少直播间ID，请重新从正确的直播链接进入。",
        "无法进入直播间",
      );
      return;
    }

    if (!isMobileEnvironment()) {
      this.handleEnterError(
        "当前环境不支持观看直播，请使用手机观看。",
        "环境不支持",
      );
      return;
    }

    this.cacheRedirectPath(options);
    this.setData({
      activityId,
      inviterToken: options.inviterToken,
      userId: options.userId,
      isLandscape: String(options.isLandscape) === "true",
    });
    const app = getApp<IAppOption>();
    this.setLoading("正在校验登录状态...");
    const isLogin = app.checkLoginState();
    if (!isLogin) {
      wx.reLaunch({ url: `/package-live/login/login?userId=${options?.userId}&activityId=${activityId}` });
      return;
    };

    await this.initSdk(activityId, options);
  },
  onHide() {
    // 不销毁SDK，避免接电话返回后重复初始化导致声音重叠
  },
  async initSdk(
    activityId: number,
    options?: Record<string, string | undefined>,
  ) {
    if (this.data.sdk) return; // 防止重复实例化SDK

    try {
      this.clearError();
      this.setLoading("正在获取直播凭证...");

      const signToken = await this.fetchSignToken();
      if (!signToken) {
        wx.redirectTo({
          url: `/package-live/login/login?userId=${options?.userId}&activityId=${activityId}&show=${true}&msg=${this.data.msg}`
        })
        throw new Error("未获取到直播凭证，请稍后重试");
      }

      this.setLoading("正在进入直播间...");

      const sdk = VolcMiniSdk({
        activityId,
        signToken,
        mode: Number(options?.mode || 2) || 2,
      } as any);

      sdk.on(EVENTS.error, (err: any) => {
        console.log("sdk error", err?.code, err?.message);
        this.handleEnterError(
          err?.message || "直播间加载失败，请稍后重试",
          "直播间加载失败",
        );
      });
      const debugInfo = sdk.getDebugInfo()
      console.log('debugInfo:', debugInfo)

      //商品卡片，浮动卡片
      sdk.on('floatingCard.click', this.handleFloatingCardClick);
      //商品卡片，购物车
      sdk.on(EVENTS.card.click, (payload: any) => {
        console.log('card.click', payload)
      });
      // 按钮红包功能
      sdk.on(EVENTS.feature.click, (payload: any) => {
        console.log('feature.click', payload)
      });
      sdk.on(EVENTS.luckymoney.withdrawal, (payload: any) => {
        this.handleReceive(payload);
      });

      sdk.on(EVENTS.activity.status, (status: 1 | 2 | 3 | 4 | 5) => {
        if (status === 4) {
          wx.switchTab({
            url: `/pages/tab-bar/profile/index`
          })
        }
      });

      this.setData({
        sdk,
        loading: false,
        loadingText: "",
      });
    } catch (error: any) {
      console.error("init wxroom sdk failed:", error);
      this.handleEnterError(
        error?.message || "进入直播间失败，请稍后重试",
        "进入直播间失败",
      );
    }
  },

  async fetchSignToken() {
    const nickName = wx.getStorageSync("userName") || "微信用户";
    const userIdStr = String(wx.getStorageSync("mbuId") || "");
    const avatarUrl = wx.getStorageSync("avatarUrl") || "";

    if (!userIdStr) {
      throw new Error("登录信息缺失，请重新登录后再进入直播间");
    }

    const res = await request<any>({
      options: {
        url: "/app/saas/activity-login",
        method: "POST",
        data: aesEncrypt(JSON.stringify({
          nickName,
          userIdStr,
          avatarUrl,
          userId: this.data.userId,
          inviterToken: this.data.inviterToken,
          activityId: this.data.activityId,
          mpUserId: wx.getStorageSync("userId"),
        }), AES_KEY, AES_IV)
      },
      loadingTitle: "进入直播间",
      isLoading: false,
    });
    const data = JSON.parse(aesDecrypt(res?.data, AES_KEY, AES_IV))
    this.setData({ msg: data?.msg ?? "暂无活动" });
    return (
      data?.signToken || ""
    );
  },
  handleFloatingCardClick: lockPromise(async function (payload: any) {
    if (!payload?.RedirectUrl) return;
    try {
      const res = await request({
        options: {
          url: payload.RedirectUrl,
          method: 'POST',
        },
      });
      if (res.code !== 200) {
        wx.showToast({ title: res.msg || '请求失败', icon: 'none' });
        return;
      }
      const payParams = res.data;
      wx.requestPayment({
        timeStamp: payParams.timeStamp,
        nonceStr: payParams.nonceStr,
        package: payParams.packageVal,
        signType: payParams.signType || 'RSA',
        paySign: payParams.paySign,
        success() {
          wx.showToast({ title: '支付成功', icon: 'success' });
          console.log('支付成功:');
        },
        fail(err) {
          wx.showToast({ title: '支付取消', icon: 'none' });
          console.error('支付失败:', err);
        },
      });
    } catch (err) {
      console.error('floatingCard请求失败:', err);
    }
  }),
  handleReceive: lockPromise(async function (data: any) {
    const params = {
      appId: appId,
      outRewardsId: data.redPacketId,
      openId: wx.getStorageSync("openId"),
    }
    try {
      await receiveRedPacket(
        params,
        '/app/general/receive-red',
        appId
      );
    } catch (err) {
      console.error('领取红包失败:', err);
    }
  }),
  getActivityId(options: Record<string, string | undefined>) {
    const rawActivityId = options.activityId || options.roomId || "";
    const activityId = Number(rawActivityId);
    return Number.isFinite(activityId) ? activityId : 0;
  },

  buildQueryString(params: Record<string, string | undefined>) {
    return Object.entries(params)
      .filter(([, value]) => value !== undefined && value !== "")
      .map(
        ([key, value]) =>
          `${encodeURIComponent(key)}=${encodeURIComponent(String(value))}`,
      )
      .join("&");
  },

  cacheRedirectPath(options: Record<string, string | undefined>) {
    const query = this.buildQueryString(options);
    const path = query ? `${WXROOM_PAGE_PATH}?${query}` : WXROOM_PAGE_PATH;
    wx.setStorageSync(WXROOM_REDIRECT_PATH_KEY, path);
  },

  setLoading(text: string) {
    this.setData({
      loading: true,
      loadingText: text,
      showError: false,
      errorTitle: "",
      errorMessage: "",
    });
  },

  clearError() {
    this.setData({
      showError: false,
      errorTitle: "",
      errorMessage: "",
    });
  },

  handleEnterError(message: string, title = "无法进入直播间") {
    this.destroySdk();
    this.setData({
      loading: false,
      loadingText: "",
      showError: true,
      errorTitle: title,
      errorMessage: message,
    });
  },

  retryEnter() {
    const activityId =
      this.data.activityId || this.getActivityId(pageOptionsCache);
    if (!activityId) {
      this.handleEnterError(
        "缺少直播间ID，请重新从正确的直播链接进入。",
        "无法进入直播间",
      );
      return;
    }

    this.initSdk(activityId, pageOptionsCache);
  },

  goBack() {
    const pages = getCurrentPages();
    if (pages.length > 1) {
      wx.navigateBack({
        delta: 1,
      });
      return;
    }

    wx.switchTab({
      url: "/pages/tab-bar/medicine-box/index",
    });
  },

  destroySdk() {
    this.data.sdk?.destroy?.();
    if (this.data.sdk) {
      this.setData({
        sdk: null,
      });
    }
  },

  onUnload() {
    this.destroySdk();
  },
});