import { NextRequest, NextResponse } from "next/server";
import { requirePermission, getAdminAuditContext } from "@/lib/admin/auth";
import { db } from "@/lib/admin/db";

export const dynamic = "force-dynamic";

/**
 * GET /api/admin/redirects
 * Lists all active 301/308 redirects.
 */
export async function GET(req: NextRequest) {
  try {
    await requirePermission("seo.manage", req);
    const redirects = await db.getRedirects();
    return NextResponse.json({ redirects });
  } catch (err: any) {
    return NextResponse.json(
      { error: err.message || "Failed to fetch redirects" },
      { status: err.status || 500 }
    );
  }
}

/**
 * POST /api/admin/redirects
 * Creates a new redirect rule.
 */
export async function POST(req: NextRequest) {
  try {
    const ctx = await requirePermission("seo.manage", req);
    const body = await req.json();

    const source = typeof body.source === "string" ? body.source.trim().toLowerCase() : "";
    const destination = typeof body.destination === "string" ? body.destination.trim() : "";
    const rawMethod = Number(body.method);
    const method: 301 | 302 | 307 | 308 = [301, 302, 307, 308].includes(rawMethod)
      ? (rawMethod as 301 | 302 | 307 | 308)
      : body.permanent === false
      ? 302
      : 301;

    if (!source || !destination) {
      return NextResponse.json(
        { error: "Both source path and destination path are required." },
        { status: 400 }
      );
    }

    if (!source.startsWith("/")) {
      return NextResponse.json(
        { error: "Source path must begin with a forward slash (/)." },
        { status: 400 }
      );
    }

    if (!destination.startsWith("/") && !/^https?:\/\//i.test(destination)) {
      return NextResponse.json(
        { error: "Destination path must begin with a forward slash (/) or a valid URL (https://...)." },
        { status: 400 }
      );
    }

    if (source === destination.toLowerCase()) {
      return NextResponse.json(
        { error: "Source and destination cannot be identical (causes an infinite self-redirect loop)." },
        { status: 400 }
      );
    }

    // Check for direct redirect loop (e.g. if destination redirects to source)
    const reverseRedirect = await db.getRedirectBySource(destination.toLowerCase());
    if (reverseRedirect && reverseRedirect.destination.toLowerCase() === source) {
      return NextResponse.json(
        { error: `Redirect loop detected: "${destination}" already redirects to "${source}".` },
        { status: 400 }
      );
    }

    const auditCtx = await getAdminAuditContext(req);
    const item = await db.createRedirect({
      id: crypto.randomUUID(),
      source,
      destination,
      method,
      permanent: method === 301 || method === 308,
      createdAt: new Date().toISOString(),
      createdBy: ctx.user.email,
    });

    await db.logContentEvent({
      actorId: ctx.user.id,
      actorName: ctx.user.name,
      actorEmail: ctx.user.email,
      actorRole: ctx.user.role,
      location: auditCtx.location || null,
      postId: null,
      postTitle: null,
      postSlug: null,
      action: "REDIRECT_CREATED",
      details: { source, destination },
    });

    return NextResponse.json({ redirect: item }, { status: 201 });
  } catch (err: any) {
    return NextResponse.json(
      { error: err.message || "Failed to create redirect" },
      { status: err.status || 500 }
    );
  }
}

/**
 * DELETE /api/admin/redirects
 * Deletes a redirect rule by ID (?id=...).
 */
export async function DELETE(req: NextRequest) {
  try {
    const ctx = await requirePermission("seo.manage", req);
    const { searchParams } = new URL(req.url);
    const id = searchParams.get("id");

    if (!id) {
      return NextResponse.json({ error: "Redirect ID is required" }, { status: 400 });
    }

    const auditCtx = await getAdminAuditContext(req);
    const deleted = await db.deleteRedirect(id);

    await db.logContentEvent({
      actorId: ctx.user.id,
      actorName: ctx.user.name,
      actorEmail: ctx.user.email,
      actorRole: ctx.user.role,
      location: auditCtx.location || null,
      postId: null,
      postTitle: null,
      postSlug: null,
      action: "REDIRECT_DELETED",
      details: { redirectId: id },
    });

    return NextResponse.json({ success: deleted });
  } catch (err: any) {
    return NextResponse.json(
      { error: err.message || "Failed to delete redirect" },
      { status: err.status || 500 }
    );
  }
}
