import { BadRequestException } from '@nestjs/common';
import type { Request, Response } from 'express';

export function normalizeFedcmOrigin(origin?: string) {
  return origin?.trim().replace(/\/+$/, '') || undefined;
}

export function applyFedcmCorsHeaders(res: Response, origin?: string) {
  const normalized = normalizeFedcmOrigin(origin);
  if (!normalized) {
    return;
  }
  res.setHeader('Access-Control-Allow-Origin', normalized);
  res.setHeader('Access-Control-Allow-Credentials', 'true');
  res.setHeader('Vary', 'Origin');
}

export function requireFedcmCorsOrigin(origin?: string) {
  const normalized = normalizeFedcmOrigin(origin);
  if (!normalized) {
    throw new BadRequestException('FedCM требует заголовок Origin');
  }
  return normalized;
}

export function applyFedcmPreflightHeaders(res: Response, origin?: string) {
  applyFedcmCorsHeaders(res, origin);
  res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS');
  res.setHeader(
    'Access-Control-Allow-Headers',
    'Content-Type, Authorization, Sec-Fetch-Dest, Sec-Fetch-Mode, Sec-Fetch-Site'
  );
  res.setHeader('Access-Control-Max-Age', '86400');
}

/**
 * FedCM-запросы должны иметь Sec-Fetch-Dest: webidentity (или empty, если прокси
 * не пробрасывает заголовок). Блокируем только явно «не-FedCM» dest (document,
 * script, image…) — иначе well-known/config отдают 400 и One Tap ломается.
 */
const BLOCKED_FEDCM_FETCH_DEST = new Set([
  'document',
  'embed',
  'frame',
  'iframe',
  'object',
  'script',
  'style',
  'image',
  'font',
  'audio',
  'video',
  'track',
  'worker',
  'serviceworker',
  'sharedworker',
  'manifest',
  'xslt'
]);

export function assertFedcmWebIdentityRequest(req: Request) {
  const dest = String(req.headers['sec-fetch-dest'] ?? '').toLowerCase();
  if (dest && BLOCKED_FEDCM_FETCH_DEST.has(dest)) {
    throw new BadRequestException('Недопустимый Sec-Fetch-Dest для FedCM');
  }
}

export function applyFedcmLoginStatus(res: Response, loggedIn: boolean) {
  res.setHeader('Set-Login', loggedIn ? 'logged-in' : 'logged-out');
}
