import { SignJWT, jwtVerify, type JWTPayload } from "jose";
import { JWT_EXPIRY_SECONDS } from "@/lib/constants/auth";
import { unauthorized } from "@/modules/auth/errors";

export const EMBED_DEMO_ROLE = "embed_demo" as const;
export const EMBED_DEMO_COOKIE = "embed_demo_session";
export const EMBED_DEMO_DEFAULT_PASSWORD = "123456";

/**
 * 嵌入 Cookie 选项：生产环境 iframe（跨站宿主如 CC）须 SameSite=None + Secure，
 * 否则第三方 iframe 内登录态无法写入/回传。
 */
export function embedDemoCookieOptions(maxAgeSeconds?: number): {
  httpOnly: boolean;
  secure: boolean;
  sameSite: "lax" | "none";
  path: string;
  maxAge?: number;
} {
  const isProd = process.env.NODE_ENV === "production";
  const forceNone =
    process.env.EMBED_COOKIE_SAMESITE?.trim().toLowerCase() === "none";
  const useNone = isProd || forceNone;
  return {
    httpOnly: true,
    secure: useNone ? true : isProd,
    sameSite: useNone ? "none" : "lax",
    path: "/",
    ...(typeof maxAgeSeconds === "number" ? { maxAge: maxAgeSeconds } : {}),
  };
}

/** 登录类型：账号密码 / API Key */
export type EmbedDemoLoginType = "password" | "api_key";

export type EmbedDemoJwtPayload = {
  sub: string;
  role: typeof EMBED_DEMO_ROLE;
  loginType: EmbedDemoLoginType;
};

function normalizeLoginType(raw: unknown): EmbedDemoLoginType {
  // 兼容旧 Cookie（无 lt 声明）：默认按账号密码处理
  return raw === "api_key" ? "api_key" : "password";
}

function getJwtSecret(): Uint8Array {
  const secret = process.env.JWT_SECRET;
  if (!secret) {
    throw new Error("JWT_SECRET 未配置");
  }
  return new TextEncoder().encode(secret);
}

export function getEmbedDemoPassword(): string {
  return process.env.EMBED_DEMO_PASSWORD?.trim() || EMBED_DEMO_DEFAULT_PASSWORD;
}

function toEmbedPayload(payload: JWTPayload): EmbedDemoJwtPayload {
  if (typeof payload.sub !== "string" || payload.role !== EMBED_DEMO_ROLE) {
    throw unauthorized("无效的演示会话");
  }
  return {
    sub: payload.sub,
    role: EMBED_DEMO_ROLE,
    loginType: normalizeLoginType(payload.lt),
  };
}

export async function signEmbedDemoToken(
  customerId: string,
  loginType: EmbedDemoLoginType = "password",
): Promise<string> {
  return new SignJWT({ role: EMBED_DEMO_ROLE, lt: loginType })
    .setProtectedHeader({ alg: "HS256" })
    .setSubject(customerId)
    .setIssuedAt()
    .setExpirationTime(`${JWT_EXPIRY_SECONDS}s`)
    .sign(getJwtSecret());
}

export async function verifyEmbedDemoToken(
  token: string,
): Promise<EmbedDemoJwtPayload> {
  try {
    const { payload } = await jwtVerify(token, getJwtSecret(), {
      algorithms: ["HS256"],
    });
    return toEmbedPayload(payload);
  } catch {
    throw unauthorized("演示会话无效或已过期");
  }
}
