import Taro from "@tarojs/taro";
import { clearToken, getToken, getRefreshToken, setRefreshToken, setToken } from "../utils/auth";
import { getAdminToken, getAdminRefreshToken, setAdminTokens, clearAdminTokens } from "../utils/adminAuth";

const BASE_URL = __API_BASE__;

// 用于防止并发刷新 token
let refreshPromise: Promise<boolean> | null = null;
let adminRefreshPromise: Promise<boolean> | null = null;

/** 错误消息映射 — 用 code 优先，fallback 文本匹配 */
const ERROR_MSG_MAP: Record<number, string> = {
  401000: "登录已过期，请重新登录",
  403000: "无权限访问",
  404000: "数据不存在或已删除",
  409000: "重复操作，请刷新后重试",
};

function showAdminLoginRequired() {
  Taro.showModal({
    title: "请先登录员工通道",
    content: "返回登录页后点击员工通道，使用管理员账号继续操作。",
    showCancel: false,
    success: () => {
      Taro.redirectTo({ url: "/pages/login/index?staff=1" }).catch(() => undefined);
    },
  });
}

export function normalizeMessage(msg: string, code?: number): string {
  if (code && ERROR_MSG_MAP[code]) return ERROR_MSG_MAP[code];
  const text = String(msg || "");
  if (/Only members/i.test(text)) return "仅会员可操作";
  if (/not found/i.test(text)) return "数据不存在或已删除";
  if (/already/i.test(text)) return "重复操作，请刷新后重试";
  if (/forbidden/i.test(text)) return "无权限访问";
  if (/Network request failed/i.test(text)) return "网络请求失败";
  if (/Bad Request/i.test(text)) return "请求参数有误";
  if (/GET.*not supported/i.test(text)) return "请求方式错误";
  return text || "请求失败";
}

/**
 * 刷新普通用户 token
 */
async function tryRefreshToken(): Promise<boolean> {
  if (refreshPromise) return refreshPromise;

  refreshPromise = (async () => {
    try {
      const refreshToken = getRefreshToken();
      if (!refreshToken) return false;

      const res = await Taro.request({
        url: `${BASE_URL}/api/auth/refresh`,
        method: "POST",
        header: { "Content-Type": "application/json" },
        data: { refreshToken }
      });
      if (res.statusCode === 200 && res.data?.code === 0) {
        setToken(res.data.data.accessToken);
        if (res.data.data.refreshToken) {
          setRefreshToken(res.data.data.refreshToken);
        }
        return true;
      }
      return false;
    } catch {
      return false;
    } finally {
      refreshPromise = null;
    }
  })();

  return refreshPromise;
}

/**
 * 刷新管理员 token
 */
async function tryAdminRefreshToken(): Promise<boolean> {
  if (adminRefreshPromise) return adminRefreshPromise;

  adminRefreshPromise = (async () => {
    try {
      const refreshToken = getAdminRefreshToken();
      if (!refreshToken) return false;

      const res = await Taro.request({
        url: `${BASE_URL}/api/admin/auth/refresh`,
        method: "POST",
        header: { "Content-Type": "application/json" },
        data: { refreshToken }
      });
      if (res.statusCode === 200 && res.data?.code === 0) {
        setAdminTokens(res.data.data.token, res.data.data.refreshToken);
        return true;
      }
      return false;
    } catch {
      return false;
    } finally {
      adminRefreshPromise = null;
    }
  })();

  return adminRefreshPromise;
}

/**
 * 普通客户端请求只使用用户 token，管理员 token 只能由 adminApiRequest 显式使用。
 */
export function getBestToken() {
  return getToken();
}

export async function apiRequest(url: string, options: Record<string, any> = {}) {
  const token = getToken();
  const hadToken = !!token;
  const path = String(url || "");
  const isAuthEndpoint = path.startsWith("/api/auth/") || path.startsWith("/api/admin/auth/") || path === "/api/admin/login";
  let payload = options.data;
  if (payload === undefined && options.body !== undefined) {
    if (typeof options.body === "string") {
      try {
        payload = JSON.parse(options.body);
      } catch {
        payload = options.body;
      }
    } else {
      payload = options.body;
    }
  }
  const headers: Record<string, string> = {
    "Content-Type": "application/json",
    ...(options.header || {}),
    ...(!isAuthEndpoint && token ? { Authorization: `Bearer ${token}` } : {}),
  };

  const doRequest = () =>
    Taro.request({
      url: `${BASE_URL}${url}`,
      method: options.method || "GET",
      data: payload,
      header: headers,
    });

  let response = await doRequest();

  // 401 → 尝试 token 刷新一次
  if (response.statusCode === 401 && hadToken) {
    const refreshed = await tryRefreshToken();
    if (refreshed) {
      headers.Authorization = `Bearer ${getToken()}`;
      response = await doRequest();
    }
  }

  // 已登录状态刷新后仍 401 → 强制登出；未登录访问公开页遇到 401 只抛错，不抢页面。
  if (response.statusCode === 401) {
    if (hadToken) {
      clearToken();
      await Taro.reLaunch({ url: "/pages/login/index" });
    }
    throw new Error("UNAUTHORIZED");
  }

  const body = response.data as any;
  if (!body || body.code !== 0) {
    const msg = normalizeMessage(body?.message || "REQUEST_FAILED", body?.code);
    Taro.showToast({ title: msg, icon: "none" });
    throw new Error(msg);
  }

  return body.data;
}

/**
 * 管理员专用请求（强制使用 adminToken）
 */
export async function adminApiRequest(url: string, options: Record<string, any> = {}) {
  const adminToken = getAdminToken();
  if (!adminToken) {
    showAdminLoginRequired();
    throw new Error("ADMIN_NOT_LOGGED_IN");
  }

  let payload = options.data;
  if (payload === undefined && options.body !== undefined) {
    if (typeof options.body === "string") {
      try {
        payload = JSON.parse(options.body);
      } catch {
        payload = options.body;
      }
    } else {
      payload = options.body;
    }
  }

  const headers: Record<string, string> = {
    "Content-Type": "application/json",
    ...(options.header || {}),
    Authorization: `Bearer ${adminToken}`,
  };

  const doRequest = () =>
    Taro.request({
      url: `${BASE_URL}${url}`,
      method: options.method || "GET",
      data: payload,
      header: headers,
    });

  let response = await doRequest();

  // 401 → 尝试刷新管理员 token
  if (response.statusCode === 401) {
    const refreshed = await tryAdminRefreshToken();
    if (refreshed) {
      headers.Authorization = `Bearer ${getAdminToken()}`;
      response = await doRequest();
    }
  }

  // 仍 401 → 清除管理员 token，并提示重新进入员工通道。
  if (response.statusCode === 401) {
    clearAdminTokens();
    showAdminLoginRequired();
    throw new Error("ADMIN_UNAUTHORIZED");
  }

  if (response.statusCode === 403) {
    const body = response.data as any;
    const msg = normalizeMessage(body?.message || "当前账号没有该管理权限", body?.code);
    if (String(body?.message || "").includes("禁用")) {
      clearAdminTokens();
      Taro.showModal({
        title: "提示",
        content: "账号已被禁用，请联系平台管理员",
        showCancel: false,
      });
      throw new Error("ADMIN_FORBIDDEN");
    }
    Taro.showModal({
      title: "提示",
      content: msg,
      showCancel: false
    });
    throw new Error(msg);
  }

  const body = response.data as any;
  if (!body || body.code !== 0) {
    const msg = normalizeMessage(body?.message || "REQUEST_FAILED", body?.code);
    Taro.showToast({ title: msg, icon: "none" });
    throw new Error(msg);
  }

  return body.data;
}
