import 'server-only';
import {cookies} from 'next/headers';
import {findUserById} from '@/features/auth/mock/users.mock';
import {
  SESSION_COOKIE,
  verifySessionToken,
} from '@/features/auth/services/sessionToken';
import type {AuthSession} from '@/features/auth/types/auth';

/**
 * Resolve the session on the server, from the signed cookie.
 *
 * Used in two places:
 *   • the root layout, to SEED the client provider — so a full page load
 *     paints the signed-in shell immediately instead of flashing a spinner
 *     while the browser asks who it is
 *   • route handlers, to authorise a request before it touches data
 *
 * `import 'server-only'` is load-bearing: this module reads cookies and the
 * user directory, and importing it from a client component would be a build
 * error rather than a silent leak of the fixture into the browser bundle.
 */
export async function getServerSession(): Promise<AuthSession | null> {
  const store = await cookies();
  const payload = verifySessionToken(store.get(SESSION_COOKIE)?.value);
  if (!payload) return null;

  // Re-resolved from the directory rather than trusted off the token, so a
  // role change or a deactivation takes effect on the next request instead of
  // whenever the cookie happens to expire.
  const user = findUserById(payload.sub);
  if (!user) return null;

  return {user, expiresAt: new Date(payload.exp * 1000).toISOString()};
}

/**
 * Guard for route handlers that must not answer an anonymous request.
 *
 * Returns the session, or a ready-made 401 to return early with:
 *
 *   const auth = await requireSession();
 *   if ('response' in auth) return auth.response;
 *   // auth.session is now available
 */
export async function requireSession(): Promise<
  {session: AuthSession} | {response: Response}
> {
  const session = await getServerSession();
  if (session) return {session};

  return {
    response: Response.json(
      {error: {code: 'unauthorized', message: 'Sign in to continue.'}},
      {status: 401, headers: {'cache-control': 'no-store'}},
    ),
  };
}
