/**
 * Server-side check of a TV link token (same HS256 secret the game server uses). The TV page uses
 * it to decide which room it may describe before any socket connects; the game server still makes
 * the final decision on every connection. Server-only: never import from client components.
 */
import { jwtVerify, errors as joseErrors } from 'jose';
import { JWT_AUDIENCE, JWT_ISSUER, TvClaimsSchema, type TvClaims } from '@pintrush/protocol';
import { formSecret } from '../server-env';

/** Verified TV claims, or null for a missing, malformed, foreign or non-TV token. */
export async function verifyTvToken(token: string | null | undefined, secret: string = formSecret()): Promise<TvClaims | null> {
  if (!token || token.length > 4096) return null;
  try {
    const { payload } = await jwtVerify(token, new TextEncoder().encode(secret), {
      issuer: JWT_ISSUER,
      audience: JWT_AUDIENCE,
      algorithms: ['HS256'],
    });
    const parsed = TvClaimsSchema.safeParse(payload);
    return parsed.success ? parsed.data : null;
  } catch (err) {
    if (err instanceof joseErrors.JOSEError) return null;
    throw err;
  }
}

/** First value of a search param (`?t=a&t=b` → "a"). */
export function firstParam(value: string | string[] | undefined): string | null {
  if (Array.isArray(value)) return value[0] ?? null;
  return value ?? null;
}
