import { NextRequest, NextResponse } from "next/server";
import { requireAuth, getAdminAuditContext } from "@/lib/admin/auth";
import { userHasPermission } from "@/lib/admin/permissions";
import { db } from "@/lib/admin/db";
import { saveUploadedMedia } from "@/lib/media-storage";
import { CloudinaryMediaCategory } from "@/lib/cloudinary";

export const runtime = "nodejs";
export const dynamic = "force-dynamic";

/**
 * GET /api/admin/media
 * Returns media library items with optional search filter.
 */
export async function GET(req: NextRequest) {
  try {
    const ctx = await requireAuth(req);

    const { searchParams } = new URL(req.url);
    const search = searchParams.get("search") || undefined;
    const limit = Math.min(100, Math.max(1, parseInt(searchParams.get("limit") || "60", 10)));

    const items = await db.getMedia(search, limit);
    return NextResponse.json({ items });
  } catch (err: any) {
    console.error("[GET /api/admin/media] Error:", err);
    return NextResponse.json(
      { error: err.message || "Failed to fetch media assets" },
      { status: err.status || 500 }
    );
  }
}

/**
 * POST /api/admin/media
 * Handles file upload with strict magic-byte validation, safe WebP storage, and audit logging.
 */
export async function POST(req: NextRequest) {
  try {
    const auditCtx = await getAdminAuditContext(req);
    const canUpload =
      userHasPermission(auditCtx.user, "media.manage") ||
      userHasPermission(auditCtx.user, "posts.create") ||
      userHasPermission(auditCtx.user, "posts.edit");
    if (!canUpload) {
      return NextResponse.json(
        { error: "Forbidden: Missing required media upload permission." },
        { status: 403 }
      );
    }
    const formData = await req.formData();
    const file = formData.get("file");
    const altText = (formData.get("alt") as string) || "";
    const category = (formData.get("category") as CloudinaryMediaCategory) || "general";
    const replaceMediaId = (formData.get("replaceMediaId") as string) || undefined;
    const uploadId = (formData.get("uploadId") as string) || undefined;
    const batchId = (formData.get("batchId") as string) || undefined;
    const batchTotal = parseInt((formData.get("batchTotal") as string) || "1", 10);

    if (!file || !(file instanceof File)) {
      return NextResponse.json(
        { error: "No valid file attached to upload request." },
        { status: 400 }
      );
    }

    let existingMediaToReplace = null;
    if (replaceMediaId) {
      existingMediaToReplace = await db.getMediaById(replaceMediaId);
    }

    const mediaItem = await saveUploadedMedia(
      file,
      auditCtx.user.email,
      altText,
      category,
      replaceMediaId,
      uploadId
    );

    // If this was an idempotent replay of an already processed upload, return immediately without duplicate audit logs
    if (mediaItem.isDuplicate) {
      return NextResponse.json({ media: mediaItem, deduplicated: true }, { status: 200 });
    }

    if (replaceMediaId && existingMediaToReplace) {
      await db.logContentEvent({
        actorId: auditCtx.user.id,
        actorName: auditCtx.user.name,
        actorEmail: auditCtx.user.email,
        actorRole: auditCtx.user.role,
        postId: null,
        postTitle: null,
        postSlug: null,
        action: "MEDIA_REPLACED",
        details: {
          assetId: mediaItem.id,
          oldAsset: {
            id: existingMediaToReplace.id,
            filename: existingMediaToReplace.filename,
            url: existingMediaToReplace.url,
            publicId: existingMediaToReplace.publicId,
          },
          newAsset: {
            id: mediaItem.id,
            filename: mediaItem.filename,
            url: mediaItem.url,
            publicId: mediaItem.publicId,
            size: mediaItem.size,
            mimeType: mediaItem.mimeType,
          },
        },
        location: auditCtx.location,
      });
    } else if (batchTotal <= 1) {
      // Single file upload: emit MEDIA_UPLOADED
      // For multi-upload batches (batchTotal > 1), the batch-complete endpoint emits MEDIA_BULK_UPLOADED
      await db.logContentEvent({
        actorId: auditCtx.user.id,
        actorName: auditCtx.user.name,
        actorEmail: auditCtx.user.email,
        actorRole: auditCtx.user.role,
        postId: null,
        postTitle: null,
        postSlug: null,
        action: "MEDIA_UPLOADED",
        details: {
          assetId: mediaItem.id,
          filename: mediaItem.filename,
          size: mediaItem.size,
          mimeType: mediaItem.mimeType,
          publicId: mediaItem.publicId,
          url: mediaItem.url,
          uploadId,
        },
        location: auditCtx.location,
      });
    }

    return NextResponse.json({ media: mediaItem }, { status: 201 });
  } catch (err: any) {
    console.error("[POST /api/admin/media] Error:", err);
    return NextResponse.json(
      { error: err.message || "Upload failed." },
      { status: err.status || 400 }
    );
  }
}
