// 单点登录（SSO）落地页
// 参考：qd-ai-fe/admin-growth-matrix 的 Login.vue iframe 包装模式
// - 远端 SSO 登录页通过 iframe 嵌入
// - iframe 登录成功后向父窗口 postMessage `{type:"sso_token", data:<token>}`
// - 回跳兜底：URL query `?sso_token=xxx` 直接消费（镜像 postMessage 成功路径）
// - 登录成功 → localStorage 存 token → 跳回 `?from=<encoded path>`（缺省回 "/"）
//
// 配置：本文件下方 ENV_TABLE 三档 dev/test/prod。SSO URL 不暴露到 window。
// 未配置时页面给出明确提示，不静默失败。

const SSO_TOKEN_MESSAGE_TYPE = "sso_token";
const SSO_TOKEN_QUERY_KEY = "token";
const SSO_REDIRECT_QUERY_KEY = "redirect";
const SSO_LOGIN_TYPE_QUERY_KEY = "loginType";
const SSO_LOGIN_TYPE_VALUE = "wecom";
const TOKEN_STORAGE_KEY = "sso_token";
const USER_STORAGE_KEY = "sso_user";

// ===== 环境配置（闭包持有，[MUST NOT] 暴露到 window） =====
// 优先级：window.__ENV_OVERRIDE__（后端注入 DEPLOY_ENV）> DEFAULT_ENV（兜底）
const DEFAULT_ENV = "dev";
const ENV_TABLE = Object.freeze({
  dev: Object.freeze({
    SSO_LOGIN_URL: "http://10.1.2.99:8888/login",
    USER_API_BASE: "https://test.ai-qidian.com/a-api",
  }),
  test: Object.freeze({
    SSO_LOGIN_URL: "https://common-test.ai-qidian.com/login",
    USER_API_BASE: "https://test.ai-qidian.com/a-api",
  }),
  prod: Object.freeze({
    SSO_LOGIN_URL: "https://common.ai-qidian.com/login",
    USER_API_BASE: "https://www.ai-qidian.com/a-api",
  }),
});

const __envCfg = (() => {
  const override = typeof window !== "undefined" ? window.__ENV_OVERRIDE__ : "";
  const env = ENV_TABLE[override] ? override : DEFAULT_ENV;
  return ENV_TABLE[env] || ENV_TABLE[DEFAULT_ENV];
})();

// 用户信息接口（对齐 @qd-ai/api-admin → GetLoginUserInfo）
//   GET {USER_API_BASE}/account/v1/login_userinfo
//   Authorization: Bearer <token>
//   resp: { code: 200, message, data: { id, roleId, username, avatar, ... } }
const USER_INFO_PATH = "/account/v1/login_userinfo";
const BUSINESS_SUCCESS_CODE = 200;

/** 拉取用户信息（成功返回 user 对象；失败抛错） */
async function fetchUserInfo(token) {
  const base = (__envCfg.USER_API_BASE || "").replace(/\/+$/, "");
  if (!base) throw new Error("USER_API_BASE 未配置");
  if (!token) throw new Error("缺少 token");
  const url = base + USER_INFO_PATH;
  const resp = await fetch(url, {
    method: "GET",
    headers: { Authorization: `Bearer ${token}` },
  });
  if (!resp.ok) throw new Error(`HTTP ${resp.status}`);
  const body = await resp.json();
  if (body && body.code !== BUSINESS_SUCCESS_CODE) {
    throw new Error(body.message || `业务错误码 ${body.code}`);
  }
  return body && body.data;
}

// 暴露给其他 jsx 使用的轻量 auth 工具，[MUST NOT] 视为正式 auth 模块
const Auth = {
  getToken: () => {
    try { return localStorage.getItem(TOKEN_STORAGE_KEY) || ""; }
    catch (_) { return ""; }
  },
  setToken: (t) => {
    try { if (t) { localStorage.setItem(TOKEN_STORAGE_KEY, t); document.cookie = "sso_token=" + encodeURIComponent(t) + "; path=/; SameSite=Lax; max-age=2592000"; } }
    catch (_) {}
  },
  clearToken: () => {
    try {
      localStorage.removeItem(TOKEN_STORAGE_KEY);
      localStorage.removeItem(USER_STORAGE_KEY);
      document.cookie = "sso_token=; path=/; max-age=0";
    } catch (_) {}
  },
  isLogin: () => !!Auth.getToken(),
  getUser: () => {
    try {
      const raw = localStorage.getItem(USER_STORAGE_KEY);
      return raw ? JSON.parse(raw) : null;
    } catch (_) { return null; }
  },
  setUser: (u) => {
    try { if (u) localStorage.setItem(USER_STORAGE_KEY, JSON.stringify(u)); }
    catch (_) {}
  },
  /** 主动刷新用户信息（依赖现有 token） */
  loadUserInfo: async () => {
    const token = Auth.getToken();
    if (!token) return null;
    const user = await fetchUserInfo(token);
    Auth.setUser(user);
    return user;
  },
};

function resolveFromQuery() {
  try {
    const u = new URL(window.location.href);
    const raw = u.searchParams.get("from");
    if (!raw) return "/";
    const decoded = decodeURIComponent(raw);
    // 防 open-redirect：仅允许站内相对路径
    if (!decoded.startsWith("/") || decoded.startsWith("//")) return "/";
    if (decoded.startsWith("/login")) return "/";
    return decoded;
  } catch (_) {
    return "/";
  }
}

function buildSsoUrl(base) {
  if (!base) return "";
  try {
    const url = new URL(base, window.location.origin);
    // 把当前完整地址作为 redirect 一并带给 SSO，方便其失败兜底回跳
    url.searchParams.set(SSO_REDIRECT_QUERY_KEY, window.location.href);
    url.searchParams.set(SSO_LOGIN_TYPE_QUERY_KEY, SSO_LOGIN_TYPE_VALUE);
    return url.toString();
  } catch (_) {
    return base;
  }
}

function ssoOriginOf(base) {
  if (!base) return "";
  try {
    return new URL(base, window.location.origin).origin;
  } catch (_) {
    return "";
  }
}

function LoginPage() {
  const ssoBase = __envCfg.SSO_LOGIN_URL || "";
  const ssoUrl = React.useMemo(() => buildSsoUrl(ssoBase), [ssoBase]);
  const ssoOrigin = React.useMemo(() => ssoOriginOf(ssoBase), [ssoBase]);
  const [errorMsg, setErrorMsg] = React.useState("");

  /** 落 token + 拉用户信息 + 跳转。失败时清 token 让用户重登 */
  const finalizeLogin = React.useCallback(async (token) => {
    if (!token) return;
    Auth.setToken(token);
    try {
      await Auth.loadUserInfo();
    } catch (e) {
      Auth.clearToken();
      setErrorMsg(`获取用户信息失败：${e && e.message ? e.message : e}`);
      return;
    }
    const to = resolveFromQuery();
    window.history.replaceState({}, "", to);
    window.dispatchEvent(new PopStateEvent("popstate"));
  }, []);

  // URL query 兜底：携 token 直接登录（镜像 postMessage 成功路径）
  // 已登录到达 /login → 直接跳走（不重复拉用户信息）
  React.useEffect(() => {
    try {
      const u = new URL(window.location.href);
      const token = u.searchParams.get(SSO_TOKEN_QUERY_KEY);
      if (token) {
        u.searchParams.delete(SSO_TOKEN_QUERY_KEY);
        window.history.replaceState({}, "", u.pathname + u.search + u.hash);
        finalizeLogin(token);
      } else if (Auth.isLogin()) {
        const to = resolveFromQuery();
        window.history.replaceState({}, "", to);
        window.dispatchEvent(new PopStateEvent("popstate"));
      }
    } catch (_) {}
  }, [finalizeLogin]);

  // postMessage 监听
  React.useEffect(() => {
    if (!ssoOrigin) return;
    const onMessage = (event) => {
      if (event.origin !== ssoOrigin) return;
      const payload = event.data;
      if (!payload || payload.type !== SSO_TOKEN_MESSAGE_TYPE || !payload.data) return;
      finalizeLogin(payload.data);
    };
    window.addEventListener("message", onMessage);
    return () => window.removeEventListener("message", onMessage);
  }, [ssoOrigin, finalizeLogin]);

  if (!ssoUrl) {
    return (
      <div className="sso-empty">
        <div className="sso-empty-panel">
          <div className="sso-empty-title">未配置 SSO 登录地址</div>
          <div className="sso-empty-desc">
            当前环境 SSO_LOGIN_URL 为空。请在
            <code style={{ margin: "0 4px" }}>app/static/login.jsx</code>
            的 <code>ENV_TABLE</code> 内补全对应环境配置。
          </div>
        </div>
      </div>
    );
  }

  return (
    <>
      <iframe
        src={ssoUrl}
        title="SSO 登录"
        className="sso-iframe"
        onError={() => setErrorMsg("SSO 登录页加载失败")}
      />
      {errorMsg && <div className="sso-error-banner">{errorMsg}</div>}
    </>
  );
}

Object.assign(window, { LoginPage, Auth });
