import api from "@/utils/api";
import { toast } from "@/utils/widget";
import { resolveSubscribeTemplates } from "./subscribe-message-config";

const SUBSCRIBE_ACCEPT_STATUS = "accept";
const SUBSCRIBE_REJECT_STATUS = "reject";
const SUBSCRIBE_BAN_STATUS = "ban";
const SUBSCRIBE_FILTER_STATUS = "filter";
const SUBSCRIBE_CANCEL_STATUS = "cancel";
const SUBSCRIBE_FAILED_STATUS = "failed";
const subscribeDisplayConfigCache = new Map();

function canUseSubscribeMessage() {
  return (
    typeof wx !== "undefined" &&
    typeof wx.requestSubscribeMessage === "function"
  );
}

function requestSubscribeMessage(tmplIds = []) {
  return new Promise((resolve) => {
    wx.requestSubscribeMessage({
      tmplIds,
      success(res) {
        resolve({ ok: true, res });
      },
      fail(err) {
        resolve({ ok: false, err });
      },
    });
  });
}

function normalizeFailStatus(err = {}) {
  const errCode = Number(err.errCode || 0);
  const errMsg = String(err.errMsg || "").toLowerCase();

  if (errCode === 20004 || errMsg.includes("main switch")) {
    return SUBSCRIBE_BAN_STATUS;
  }
  if (errCode === 20005 || errMsg.includes("ban")) {
    return SUBSCRIBE_BAN_STATUS;
  }
  if (errMsg.includes("filter")) {
    return SUBSCRIBE_FILTER_STATUS;
  }
  if (errMsg.includes("cancel")) {
    return SUBSCRIBE_CANCEL_STATUS;
  }
  return SUBSCRIBE_FAILED_STATUS;
}

function buildTemplateResultRecords(templates = [], requestResult = {}, context = {}) {
  const requestedAt = Date.now();

  if (requestResult.ok) {
    const res = requestResult.res || {};
    return templates.map((template) => ({
      role: context.role || "",
      scene: context.scene || "",
      conversationId: context.conversationId || "",
      groupId: context.groupId || "",
      corpId: context.corpId || "",
      teamId: context.teamId || "",
      patientId: context.patientId || "",
      doctorId: context.doctorId || "",
      userId: context.userId || "",
      openid: context.openid || "",
      unionid: context.unionid || "",
      templateId: template.id,
      templateCode: template.code,
      templateName: template.name,
      eventTypes: template.events,
      status: String(res[template.id] || SUBSCRIBE_FAILED_STATUS),
      rawResult: res,
      requestedAt,
      extraData: context.extraData || {},
    }));
  }

  const status = normalizeFailStatus(requestResult.err);
  return templates.map((template) => ({
    role: context.role || "",
    scene: context.scene || "",
    conversationId: context.conversationId || "",
    groupId: context.groupId || "",
    corpId: context.corpId || "",
    teamId: context.teamId || "",
    patientId: context.patientId || "",
    doctorId: context.doctorId || "",
    userId: context.userId || "",
    openid: context.openid || "",
    unionid: context.unionid || "",
    templateId: template.id,
    templateCode: template.code,
    templateName: template.name,
    eventTypes: template.events,
    status,
    rawResult: requestResult.err || {},
    requestedAt,
    extraData: context.extraData || {},
  }));
}

function buildToastMessage(records = [], reportResult = { success: false }) {
  const accepted = records.some((item) => item.status === SUBSCRIBE_ACCEPT_STATUS);

  if (accepted && reportResult?.success === false) {
    return reportResult?.message || "提醒开启失败，请稍后再试";
  }

  if (records.some((item) => item.status === SUBSCRIBE_ACCEPT_STATUS)) {
    return "会话消息提醒开启";
  }
  if (records.some((item) => item.status === SUBSCRIBE_BAN_STATUS)) {
    return "请先在微信设置中开启订阅消息提醒";
  }
  if (records.some((item) => item.status === SUBSCRIBE_FILTER_STATUS)) {
    return "当前提醒模板暂不可用";
  }
  if (records.some((item) => item.status === SUBSCRIBE_REJECT_STATUS)) {
    return "你已拒绝本次提醒订阅";
  }
  if (records.some((item) => item.status === SUBSCRIBE_CANCEL_STATUS)) {
    return "你已取消本次提醒订阅";
  }
  return "提醒订阅请求失败，请稍后再试";
}

async function reportSubscribeResult(records = []) {
  if (!records.length) return { success: false };
  try {
    return await api(
      "saveConversationSubscribeResult",
      {
        records,
      },
      false
    );
  } catch (error) {
    console.error("保存订阅结果失败:", error);
    return { success: false, message: error?.message || "保存失败" };
  }
}

export async function checkConversationSubscribeEntryVisible(
  corpId = "",
  forceRefresh = false
) {
  const normalizedCorpId = String(corpId || "").trim();
  if (!normalizedCorpId) return false;

  if (!forceRefresh && subscribeDisplayConfigCache.has(normalizedCorpId)) {
    return subscribeDisplayConfigCache.get(normalizedCorpId);
  }

  try {
    const result = await api(
      "getConversationSubscribeConfig",
      { corpId: normalizedCorpId },
      false
    );
    const enabled = !!result?.data?.enabled;
    subscribeDisplayConfigCache.set(normalizedCorpId, enabled);
    return enabled;
  } catch (error) {
    console.error("获取订阅提醒显示配置失败:", error);
    subscribeDisplayConfigCache.set(normalizedCorpId, false);
    return false;
  }
}

export async function requestConversationSubscribeMessage(context = {}) {
  const templates = resolveSubscribeTemplates({
    role: context.role,
    scene: context.scene,
  });
  const requestTemplates = templates.slice(0, 1);

  if (!requestTemplates.length) {
    await toast("暂未配置提醒模板");
    return {
      success: false,
      code: "template_missing",
      records: [],
    };
  }

  if (!canUseSubscribeMessage()) {
    await toast("当前微信版本不支持订阅消息");
    return {
      success: false,
      code: "unsupported",
      records: [],
    };
  }

  const requestResult = await requestSubscribeMessage(
    requestTemplates.map((item) => item.id)
  );
  const records = buildTemplateResultRecords(
    requestTemplates,
    requestResult,
    context
  );

  const reportResult = await reportSubscribeResult(records);
  await toast(buildToastMessage(records, reportResult));

  const subscribeSuccess =
    records.some((item) => item.status === SUBSCRIBE_ACCEPT_STATUS) &&
    reportResult?.success !== false;

  return {
    success: subscribeSuccess,
    reportResult,
    records,
    acceptedTemplateIds: records
      .filter((item) => item.status === SUBSCRIBE_ACCEPT_STATUS)
      .map((item) => item.templateId),
  };
}
