import { createHash, randomBytes } from "node:crypto";
import { cookies } from "next/headers";
import { redirect } from "next/navigation";
import { db } from "@/lib/db";

const LEGACY_COOKIE = process.env.SESSION_COOKIE_NAME ?? "shop_compras_session";
const COOKIES = { tenant: `${LEGACY_COOKIE}_tenant`, admin: `${LEGACY_COOKIE}_admin` } as const;
export type SessionScope = keyof typeof COOKIES;
const DAYS = 30;
const hash = (token: string) => createHash("sha256").update(token).digest("hex");

export async function createSession(userId: string, scope: SessionScope = "tenant") {
  const token = randomBytes(32).toString("base64url");
  const expiresAt = new Date(Date.now() + DAYS * 86_400_000);
  await db.session.create({ data: { userId, tokenHash: hash(token), expiresAt } });
  (await cookies()).set(COOKIES[scope], token, { httpOnly: true, sameSite: "lax", secure: process.env.NODE_ENV === "production", path: "/", expires: expiresAt });
}

export async function currentUser(scope: SessionScope = "tenant") {
  const jar=await cookies();
  const token = jar.get(COOKIES[scope])?.value ?? jar.get(LEGACY_COOKIE)?.value;
  if (!token) return null;
  const session = await db.session.findUnique({ where: { tokenHash: hash(token) }, include: { user: { include: { memberships: { include: { tenant: { include: { subscription: true } } } } } } } });
  if (!session || session.expiresAt <= new Date() || session.user.deletedAt) return null;
  const isPlatform=Boolean(session.user.isSuperAdmin||session.user.platformRole);
  if((scope==="admin"&&!isPlatform)||(scope==="tenant"&&isPlatform))return null;
  return session.user;
}

export async function requireUser() {
  const user = await currentUser();
  if (!user) {
    if (await currentUser("admin")) redirect("/admin");
    redirect("/login");
  }
  if (user.isSuperAdmin || user.platformRole) redirect("/admin");
  return user;
}

export type PlatformAccess = "SUPER_ADMIN" | "ADMIN" | "FINANCE" | "SELLER";
export function userPlatformRole(user:{isSuperAdmin:boolean;platformRole:PlatformAccess|null}) { return user.isSuperAdmin ? "SUPER_ADMIN" : user.platformRole; }
export async function requirePlatformAccess(allowed:PlatformAccess[]) { const user=await currentUser("admin"); if(!user) redirect("/admin/login"); const role=userPlatformRole(user); if(!role||!allowed.includes(role)) redirect("/admin/login"); return {user,role}; }

export async function requireTenantAdmin() {
  const user = await requireUser();
  const membership = user.memberships.find((item) => item.active && item.role === "TENANT_ADMIN");
  if (!membership) redirect("/painel");
  return { user, membership, tenant: membership.tenant };
}

export async function requireTenantDelivery() {
  const context=await requireTenantAdmin();
  if(!context.tenant.deliveryEnabled)redirect("/painel/plano?delivery=necessario");
  return context;
}

export async function destroySession(scope: SessionScope = "tenant") {
  const jar = await cookies();
  const token = jar.get(COOKIES[scope])?.value;
  if (token) await db.session.deleteMany({ where: { tokenHash: hash(token) } });
  jar.delete(COOKIES[scope]);
  jar.delete(LEGACY_COOKIE);
}
