/**
 * GET /api/theia-auth
 *
 * Traefik ForwardAuth endpoint for Theia IDE domains.
 *
 * Handles two cases:
 *   1. theia.vibnai.com        — shared IDE: any authenticated user may access
 *   2. {slug}.ide.vibnai.com   — per-project IDE: only the project owner may access
 *
 * Traefik calls this URL for every request to those Theia domains, forwarding
 * the user's Cookie header via authRequestHeaders. We validate the NextAuth
 * database session directly in Postgres (avoids Prisma / authOptions build-time
 * issues under --network host).
 *
 * Returns:
 *   200  — valid session (and owner check passed), Traefik lets the request through
 *   302  — no/expired session, redirect browser to Vibn login
 *   403  — authenticated but not the project owner
 */

import { NextRequest, NextResponse } from 'next/server';
import { query } from '@/lib/db-postgres';

export const dynamic = 'force-dynamic';

const APP_URL   = process.env.NEXTAUTH_URL ?? 'https://vibnai.com';
const THEIA_URL = 'https://theia.vibnai.com';
const IDE_SUFFIX = '.ide.vibnai.com';

const SESSION_COOKIE_NAMES = [
  '__Secure-next-auth.session-token',
  'next-auth.session-token',
];

export async function GET(request: NextRequest) {
  // ── 1. Extract session token ──────────────────────────────────────────────
  let sessionToken: string | null = null;
  for (const name of SESSION_COOKIE_NAMES) {
    const val = request.cookies.get(name)?.value;
    if (val) { sessionToken = val; break; }
  }

  if (!sessionToken) return redirectToLogin(request);

  // ── 2. Validate session in Postgres ──────────────────────────────────────
  let userEmail: string | null = null;
  let userName:  string | null = null;
  let userId:    string | null = null;

  try {
    const rows = await query<{ email: string; name: string; user_id: string }>(
      `SELECT u.email, u.name, s.user_id
         FROM sessions s
         JOIN users u ON u.id = s.user_id
        WHERE s.session_token = $1
          AND s.expires > NOW()
        LIMIT 1`,
      [sessionToken],
    );
    if (rows.length > 0) {
      userEmail = rows[0].email;
      userName  = rows[0].name;
      userId    = rows[0].user_id;
    }
  } catch (err) {
    console.error('[theia-auth] DB error:', err);
    return redirectToLogin(request);
  }

  if (!userEmail || !userId) return redirectToLogin(request);

  // ── 3. Per-project ownership check for *.ide.vibnai.com ──────────────────
  const forwardedHost = request.headers.get('x-forwarded-host') ?? '';

  if (forwardedHost.endsWith(IDE_SUFFIX)) {
    const slug = forwardedHost.slice(0, -IDE_SUFFIX.length);

    try {
      const rows = await query<{ user_id: string }>(
        `SELECT user_id FROM fs_projects WHERE slug = $1 LIMIT 1`,
        [slug],
      );

      if (rows.length === 0) {
        // Unknown project slug — deny
        return new NextResponse('Workspace not found', { status: 403 });
      }

      const ownerUserId = rows[0].user_id;
      if (ownerUserId !== userId) {
        // Authenticated but not the owner
        return new NextResponse('Access denied — this workspace belongs to another user', { status: 403 });
      }
    } catch (err) {
      console.error('[theia-auth] project ownership check error:', err);
      return redirectToLogin(request);
    }
  }

  // ── 4. Allow — pass user identity headers to Theia ───────────────────────
  return new NextResponse(null, {
    status: 200,
    headers: {
      'X-Auth-Email': userEmail,
      'X-Auth-Name':  userName ?? '',
    },
  });
}

function redirectToLogin(request: NextRequest): NextResponse {
  // Use THEIA_URL as the callbackUrl so the user lands back on Theia after login.
  // (X-Forwarded-Host points to vibnai.com via Traefik, not the original Theia domain.)
  const loginUrl = `${APP_URL}/auth?callbackUrl=${encodeURIComponent(THEIA_URL)}`;
  return NextResponse.redirect(loginUrl, { status: 302 });
}
