import { NextRequest, NextResponse } from 'next/server';
import { getDb } from '@/lib/db';
import bcrypt from 'bcryptjs';
import { authenticator } from 'otplib';
import { randomUUID } from 'crypto';
import {
  ADMIN_SESSION_COOKIE_NAME,
  getAdminSessionSecret,
  signSessionId,
} from '@/lib/admin-session-cookie';
import { loginSchema, parseBody } from '@/lib/validation';
import { checkRateLimit } from '@/lib/rate-limit';
import type { AdminUserRow } from '@/lib/db-types';

// Dummy-Hash, um bei unbekanntem Benutzernamen dennoch einen bcrypt-Vergleich
// auszufuehren. Das gleicht die Antwortzeit zwischen existierenden und nicht
// existierenden Benutzern an und verhindert Username-Enumeration ueber Timing.
const DUMMY_HASH = '$2a$10$cJnSMuUPGOui7mL8/tuqqevjuBJdt8A9J7ruAAer1hIgxAfhG3Tba';

export async function POST(req: NextRequest) {
  const limit = checkRateLimit(req, 'admin-login', 5, 300);
  if (!limit.allowed) {
    return NextResponse.json(
      { error: 'Zu viele Login-Versuche. Bitte spaeter erneut versuchen.' },
      { status: 429, headers: { 'Retry-After': String(limit.retryAfter) } }
    );
  }

  const parsed = await parseBody(req, loginSchema);
  if (!parsed.success) return parsed.response;

  const { username, password, totpCode } = parsed.data;
  const db = getDb();

  const admin = db.prepare('SELECT * FROM admin_users WHERE username = ?').get(username) as AdminUserRow | undefined;

  let passwordOk = false;
  if (admin) {
    passwordOk = await bcrypt.compare(password, admin.password_hash);
  } else {
    // Nur Timing angleichen, Ergebnis wird unten verworfen.
    await bcrypt.compare(password, DUMMY_HASH);
  }

  if (!admin || !passwordOk) {
    return NextResponse.json({ error: 'Ungueltige Zugangsdaten' }, { status: 401 });
  }

  if (admin.totp_enabled) {
    if (!totpCode) {
      return NextResponse.json({ requiresTotp: true }, { status: 200 });
    }
    if (!admin.totp_secret) {
      return NextResponse.json({ error: '2FA ist aktiviert, aber kein Secret hinterlegt' }, { status: 401 });
    }
    const valid = authenticator.check(totpCode, admin.totp_secret);
    if (!valid) {
      return NextResponse.json({ error: 'Ungueltiger 2FA-Code' }, { status: 401 });
    }
  }

  const sessionId = randomUUID();
  const expiresAt = new Date(Date.now() + 1000 * 60 * 60 * 8).toISOString();

  db.prepare('INSERT INTO admin_sessions (id, admin_user_id, expires_at) VALUES (?, ?, ?)')
    .run(sessionId, admin.id, expiresAt);
  db.prepare("UPDATE admin_users SET last_login_at = datetime('now') WHERE id = ?").run(admin.id);

  const signedSessionId = signSessionId(sessionId, getAdminSessionSecret());

  const res = NextResponse.json({ success: true });
  res.cookies.set(ADMIN_SESSION_COOKIE_NAME, signedSessionId, {
    httpOnly: true,
    secure: true,
    sameSite: 'lax',
    path: '/',
    expires: new Date(expiresAt),
  });
  return res;
}
