import { NextRequest, NextResponse } from 'next/server';
import { timingSafeEqual } from 'node:crypto';
import { sql } from 'drizzle-orm';

import { db } from '@/lib/db';
import { redis } from '@/lib/redis';
import { env } from '@/lib/env';
import { logger } from '@/lib/logger';

/**
 * GET /api/public/health
 *
 * Liveness + readiness probe. Two response shapes:
 *
 *   1. **Anonymous (no header):** minimal `{status:'ok'}` so uptime
 *      monitors can poll without leaking deployment fingerprints.
 *
 *   2. **Authenticated (`X-Intake-Secret`, timing-safe compared):** full
 *      payload including env + dependency check results. This is what
 *      the marketing site uses on startup AND what k8s readiness
 *      probes should hit, because it returns 503 on hard dep failures.
 *
 * The dep checks (DB SELECT 1, Redis PING) run on every request - they
 * are <5ms each. If either fails, the response is 503 so a load balancer
 * stops routing to this instance.
 */

type HealthCheck = { ok: true; latencyMs: number } | { ok: false; error: string };

async function checkDb(): Promise<HealthCheck> {
  const start = Date.now();
  try {
    await db.execute(sql`SELECT 1`);
    return { ok: true, latencyMs: Date.now() - start };
  } catch (err) {
    return { ok: false, error: err instanceof Error ? err.message : 'unknown' };
  }
}

async function checkRedis(): Promise<HealthCheck> {
  const start = Date.now();
  try {
    const pong = await redis.ping();
    if (pong !== 'PONG') return { ok: false, error: `unexpected: ${pong}` };
    return { ok: true, latencyMs: Date.now() - start };
  } catch (err) {
    return { ok: false, error: err instanceof Error ? err.message : 'unknown' };
  }
}

export async function GET(req: NextRequest): Promise<Response> {
  const expected = env.WEBSITE_INTAKE_SECRET;
  const provided = req.headers.get('x-intake-secret');
  const matched =
    !!expected &&
    !!provided &&
    provided.length === expected.length &&
    (() => {
      try {
        return timingSafeEqual(Buffer.from(provided), Buffer.from(expected));
      } catch {
        return false;
      }
    })();

  // Anonymous probe: no dep checks, never 503. Uptime monitors that
  // can't carry the secret keep working.
  if (!matched) {
    return NextResponse.json(
      { status: 'ok', timestamp: new Date().toISOString() },
      { headers: { 'cache-control': 'no-store' } },
    );
  }

  // Authenticated probe: run dep checks in parallel and surface a 503
  // when anything required is down.
  const [dbCheck, redisCheck] = await Promise.all([checkDb(), checkRedis()]);
  const allOk = dbCheck.ok && redisCheck.ok;

  if (!allOk) {
    logger.warn({ db: dbCheck, redis: redisCheck }, 'Health probe found an unhealthy dependency');
  }

  return NextResponse.json(
    {
      status: allOk ? 'ok' : 'degraded',
      env: env.NODE_ENV,
      appUrl: env.APP_URL,
      timestamp: new Date().toISOString(),
      checks: { db: dbCheck, redis: redisCheck },
    },
    { status: allOk ? 200 : 503, headers: { 'cache-control': 'no-store' } },
  );
}
