import { NextRequest, NextResponse } from 'next/server';
import { createServerClient } from '@supabase/ssr';
import { createClient as createAdminClient } from '@supabase/supabase-js';

// ── In-memory rate limiter ─────────────────────────────────────────────────
const attempts = new Map<string, { count: number; resetAt: number }>();
const RATE_LIMIT = 5;
const WINDOW_MS = 15 * 60 * 1000; // 15-minute window

function getRealIp(req: NextRequest): string {
  return (
    req.headers.get('x-forwarded-for')?.split(',')[0].trim() ??
    req.headers.get('x-real-ip') ??
    'unknown'
  );
}

function isRateLimited(ip: string): boolean {
  const now = Date.now();
  const entry = attempts.get(ip);
  if (!entry || now > entry.resetAt) {
    attempts.set(ip, { count: 1, resetAt: now + WINDOW_MS });
    return false;
  }
  if (entry.count >= RATE_LIMIT) return true;
  entry.count += 1;
  return false;
}

export async function POST(req: NextRequest) {
  const ip = getRealIp(req);

  // ── 1. Rate limiting ──────────────────────────────────────────────────────
  if (isRateLimited(ip)) {
    return NextResponse.json(
      { error: 'Too many attempts. Please wait 15 minutes.' },
      { status: 429 }
    );
  }

  // ── 2. Parse body ──────────────────────────────────────────────────────────
  let email: string;
  let password: string;

  try {
    const body = await req.json();
    email    = typeof body.email    === 'string' ? body.email.trim().toLowerCase()    : '';
    password = typeof body.password === 'string' ? body.password : '';
  } catch {
    return NextResponse.json({ error: 'Invalid request body' }, { status: 400 });
  }

  if (!email || !password) {
    return NextResponse.json({ error: 'Email and password are required' }, { status: 400 });
  }

  // ── 3. Authenticate via Supabase ──────────────────────────────────────────
  const response = NextResponse.json({ success: true });

  const supabase = createServerClient(
    process.env.NEXT_PUBLIC_SUPABASE_URL!,
    process.env.NEXT_PUBLIC_SUPABASE_PUBLISHABLE_KEY!,
    {
      cookies: {
        getAll() {
          return req.cookies.getAll();
        },
        setAll(cookiesToSet) {
          cookiesToSet.forEach(({ name, value, options }) =>
            response.cookies.set(name, value, {
              ...options,
              httpOnly: true,
              secure: process.env.NODE_ENV === 'production',
              sameSite: 'lax',
            })
          );
        },
      },
    }
  );

  const { data: authData, error: authError } = await supabase.auth.signInWithPassword({
    email,
    password,
  });

  if (authError || !authData.user) {
    return NextResponse.json({ error: 'Invalid credentials' }, { status: 401 });
  }

  // ── 4. Check role in profiles table ──────────────────────────────────────
  // Use service-role client to bypass RLS and reliably fetch the profile
  const supabaseAdmin = createAdminClient(
    process.env.NEXT_PUBLIC_SUPABASE_URL!,
    process.env.SUPABASE_SERVICE_ROLE_KEY!,
    { auth: { autoRefreshToken: false, persistSession: false } }
  );

  const { data: profile, error: profileError } = await supabaseAdmin
    .from('profiles')
    .select('role')
    .eq('id', authData.user.id)
    .single();

  if (profileError || !profile) {
    // No profile found — sign them out and reject
    await supabase.auth.signOut();
    return NextResponse.json(
      { error: 'Account not found. Please contact an administrator.' },
      { status: 403 }
    );
  }

  if (profile.role !== 'admin') {
    // Account exists but role is not admin — sign them out
    await supabase.auth.signOut();
    return NextResponse.json(
      { error: 'Your account does not have admin access. Contact an administrator to be promoted.' },
      { status: 403 }
    );
  }

  // ── 5. Success: clear rate-limit counter ──────────────────────────────────
  attempts.delete(ip);

  return response;
}