import { SignJWT, jwtVerify } from 'jose';
import { cookies } from 'next/headers';
import { JWT_SECRET } from './jwt-secret';

export const COOKIE_NAME = 'restroagent_session';

export interface SessionPayload {
  userId: string;
  email: string;
  role: string;
  restaurantId: string | null;
  /**
   * Currently active branch for this session. For owners/admins this comes
   * from the topbar branch picker (POST /api/auth/switch-branch) and may be
   * null when "All branches" is selected. For users hard-pinned to a single
   * branch (`users.branch_id IS NOT NULL`) this always equals
   * `pinnedBranchId` and cannot be changed via switch-branch.
   */
  branchId: string | null;
  /**
   * Hard branch pin from `users.branch_id`. Set at sign-in and never
   * mutated for the life of the session. Drives `assertBranchAccess` —
   * pinned users are barred from any other branch's data even if they
   * tamper with the active `branchId` cookie.
   */
  pinnedBranchId?: string | null;
}

export async function createSessionToken(payload: SessionPayload): Promise<string> {
  return createSession(payload);
}

export async function createSession(payload: SessionPayload): Promise<string> {
  return new SignJWT({ ...payload })
    .setProtectedHeader({ alg: 'HS256' })
    .setIssuedAt()
    .setExpirationTime('7d')
    .sign(JWT_SECRET);
}

export async function verifySession(token: string): Promise<SessionPayload | null> {
  try {
    const { payload } = await jwtVerify(token, JWT_SECRET);
    return payload as unknown as SessionPayload;
  } catch {
    return null;
  }
}

export async function getSession(): Promise<SessionPayload | null> {
  const cookieStore = await cookies();
  const token = cookieStore.get(COOKIE_NAME)?.value;
  if (!token) return null;
  return verifySession(token);
}
