import { getDb } from '@pintrush/db';
import { isBot, MAX_BEACON_BYTES, parseBeacon, prefersNoTracking } from '@/lib/analytics';
import { clientIp, hashIp, SlidingWindowLimiter, utcDay } from '@/lib/rate-limit';
import { analyticsSalt } from '@/lib/server-env';
import { siteUrl } from '@/lib/site';

/**
 * Cookie-less page-view beacon. Stores {kind: PAGE_VIEW, path, referrer host}; never cookies, never
 * IPs, nothing at all for bots or visitors sending DNT / Sec-GPC. Always answers 204 for valid
 * requests so the response reveals nothing about what was recorded.
 */

// Keyed by a salted hash held only in memory; caps how fast one client can inflate counts.
const limiter = new SlidingWindowLimiter(60, 10 * 60 * 1000);

function noContent(): Response {
  return new Response(null, { status: 204, headers: { 'Cache-Control': 'no-store' } });
}

export async function POST(request: Request): Promise<Response> {
  const headers = request.headers;
  if (prefersNoTracking(headers) || isBot(headers.get('user-agent'))) return noContent();

  // Browsers mark cross-site beacons; only count views sent from our own pages.
  const fetchSite = headers.get('sec-fetch-site');
  if (fetchSite && fetchSite !== 'same-origin') return noContent();

  const declaredLength = Number(headers.get('content-length') ?? '0');
  if (declaredLength > MAX_BEACON_BYTES) return new Response(null, { status: 413 });

  const view = parseBeacon(await request.text(), siteUrl.hostname);
  if (!view) return new Response(null, { status: 400 });

  const now = Date.now();
  if (!limiter.hit(hashIp(clientIp(headers), analyticsSalt(), utcDay(now)), now).allowed) return noContent();

  try {
    await getDb().analyticsEvent.create({ data: { kind: 'PAGE_VIEW', path: view.path, referrer: view.referrer } });
  } catch (error) {
    // Analytics must never surface errors to visitors.
    console.error('[analytics] Could not record page view:', error instanceof Error ? error.message : error);
  }
  return noContent();
}
