import { NextRequest, NextResponse } from "next/server";
import {
  forbidden,
  requireAdmin,
  requireRole,
  unauthorized,
} from "@/lib/admin-auth";
import { logAdminActivity } from "@/lib/admin-activity";
import { query } from "@/lib/db";
import { requestMeta } from "@/lib/request-meta";

type BlockRow = {
  id: number;
  client_ip: string;
  reason: string;
  source: string;
  expires_at: string | null;
  created_by_admin_id: number | null;
  created_at: string;
};

export async function GET(req: NextRequest) {
  const admin = await requireAdmin();
  if (!admin) return unauthorized();

  const meta = requestMeta(req);
  const rows = await query<BlockRow[]>(
    `SELECT id, client_ip, reason, source, expires_at, created_by_admin_id, created_at
     FROM network_blocklist
     ORDER BY created_at DESC
     LIMIT 200`,
  );

  await logAdminActivity({
    adminId: admin.id,
    username: admin.username,
    action: "view_blocklist",
    resource: "network/blocklist",
    outcome: "success",
    ip: meta.ip,
    userAgent: meta.userAgent,
  });

  return NextResponse.json({ ok: true, blocklist: rows });
}

export async function POST(req: NextRequest) {
  const loggedIn = await requireAdmin();
  if (!loggedIn) return unauthorized();
  const admin = await requireRole(["superadmin", "operator"]);
  if (!admin) return forbidden();

  const meta = requestMeta(req);
  try {
    const body = (await req.json()) as {
      client_ip?: string;
      reason?: string;
      expires_at?: string | null;
    };

    const clientIp = body.client_ip?.trim();
    const reason = body.reason?.trim() || "Manual block from admin";
    if (!clientIp) {
      return NextResponse.json(
        { ok: false, error: "client_ip required" },
        { status: 400 },
      );
    }

    await query(
      `INSERT INTO network_blocklist
        (client_ip, reason, source, expires_at, created_by_admin_id)
       VALUES
        (:client_ip, :reason, 'admin_manual', :expires_at, :admin_id)`,
      {
        client_ip: clientIp.slice(0, 64),
        reason: reason.slice(0, 200),
        expires_at: body.expires_at || null,
        admin_id: admin.id,
      },
    );

    await logAdminActivity({
      adminId: admin.id,
      username: admin.username,
      action: "block_ip",
      resource: "network/blocklist",
      outcome: "success",
      ip: meta.ip,
      userAgent: meta.userAgent,
      meta: { client_ip: clientIp, reason },
    });

    return NextResponse.json({ ok: true });
  } catch (e) {
    console.error("blocklist add failed", e);
    return NextResponse.json(
      { ok: false, error: "Could not add block" },
      { status: 500 },
    );
  }
}

export async function DELETE(req: NextRequest) {
  const loggedIn = await requireAdmin();
  if (!loggedIn) return unauthorized();
  const admin = await requireRole(["superadmin", "operator"]);
  if (!admin) return forbidden();

  const meta = requestMeta(req);
  try {
    const sp = req.nextUrl.searchParams;
    const id = Number(sp.get("id") || 0);
    const clientIp = sp.get("client_ip")?.trim();

    if (!id && !clientIp) {
      return NextResponse.json(
        { ok: false, error: "id or client_ip required" },
        { status: 400 },
      );
    }

    if (id) {
      await query(`DELETE FROM network_blocklist WHERE id = :id`, { id });
    } else {
      await query(`DELETE FROM network_blocklist WHERE client_ip = :client_ip`, {
        client_ip: clientIp,
      });
    }

    await logAdminActivity({
      adminId: admin.id,
      username: admin.username,
      action: "unblock_ip",
      resource: "network/blocklist",
      outcome: "success",
      ip: meta.ip,
      userAgent: meta.userAgent,
      meta: { id: id || null, client_ip: clientIp || null },
    });

    return NextResponse.json({ ok: true });
  } catch (e) {
    console.error("blocklist delete failed", e);
    return NextResponse.json(
      { ok: false, error: "Could not remove block" },
      { status: 500 },
    );
  }
}
