import { SignJWT, jwtVerify } from "jose";
import { cookies } from "next/headers";
import type { Role, SessionUser } from "./roles";
import { isRole } from "./roles";

const COOKIE = "eg_community";

function secret() {
  const value = process.env.AUTH_SECRET || "dev-only-change-me";
  return new TextEncoder().encode(value);
}

export async function createSessionToken(user: SessionUser) {
  return new SignJWT({
    email: user.email,
    name: user.name,
    role: user.role,
    verificationStatus: user.verificationStatus,
    wholesaleStatus: user.wholesaleStatus,
  })
    .setProtectedHeader({ alg: "HS256" })
    .setSubject(user.id)
    .setIssuedAt()
    .setExpirationTime("14d")
    .sign(secret());
}

export async function readSession(): Promise<SessionUser | null> {
  const token = (await cookies()).get(COOKIE)?.value;
  if (!token) return null;
  try {
    const { payload } = await jwtVerify(token, secret());
    const role = typeof payload.role === "string" && isRole(payload.role) ? payload.role : "member";
    if (!payload.sub || typeof payload.email !== "string") return null;
    return {
      id: payload.sub,
      email: payload.email,
      name: typeof payload.name === "string" ? payload.name : "Member",
      role: role as Role,
      verificationStatus: String(payload.verificationStatus ?? "pending"),
      wholesaleStatus: String(payload.wholesaleStatus ?? "none"),
    };
  } catch {
    return null;
  }
}

export async function setSessionCookie(user: SessionUser) {
  const token = await createSessionToken(user);
  (await cookies()).set(COOKIE, token, {
    httpOnly: true,
    sameSite: "lax",
    secure: process.env.NODE_ENV === "production",
    path: "/",
    maxAge: 60 * 60 * 24 * 14,
  });
}

export async function clearSessionCookie() {
  (await cookies()).delete(COOKIE);
}

export async function getSessionFromRequest(request: Request): Promise<SessionUser | null> {
  const token = request.headers
    .get("cookie")
    ?.split(";")
    .map((part) => part.trim())
    .find((part) => part.startsWith(`${COOKIE}=`))
    ?.slice(COOKIE.length + 1);
  if (!token) return null;
  try {
    const { payload } = await jwtVerify(token, secret());
    const role = typeof payload.role === "string" && isRole(payload.role) ? payload.role : "member";
    if (!payload.sub || typeof payload.email !== "string") return null;
    return {
      id: payload.sub,
      email: payload.email,
      name: typeof payload.name === "string" ? payload.name : "Member",
      role: role as Role,
      verificationStatus: String(payload.verificationStatus ?? "pending"),
      wholesaleStatus: String(payload.wholesaleStatus ?? "none"),
    };
  } catch {
    return null;
  }
}
