import { NextRequest, NextResponse } from "next/server";
import { requirePermission, getAdminAuditContext } from "@/lib/admin/auth";
import { db } from "@/lib/admin/db";
import {
  getMediaReferences,
  getMediaUsageInPosts,
  getAssetUsage,
  deletePhysicalMediaFile,
} from "@/lib/media-storage";
import { deleteAssetFromCloudinary } from "@/lib/cloudinary";

export const dynamic = "force-dynamic";

/**
 * GET /api/admin/media/[id]
 * Fetches media item metadata and referencing articles.
 */
export async function GET(
  req: NextRequest,
  context: { params: Promise<{ id: string }> }
) {
  try {
    await requirePermission("media.manage", req);
    const { id } = await context.params;

    const item = await db.getMediaById(id);
    if (!item) {
      return NextResponse.json({ error: "Media item not found" }, { status: 404 });
    }

    const usage = await getAssetUsage(item);
    return NextResponse.json({
      media: item,
      referencingPosts: usage.referencingEntities.articles.map((a) => a.title),
      usage,
    });
  } catch (err: any) {
    return NextResponse.json(
      { error: err.message || "Failed to fetch media item" },
      { status: err.status || 500 }
    );
  }
}

/**
 * PATCH /api/admin/media/[id]
 * Updates alt text or caption for a media item.
 */
export async function PATCH(
  req: NextRequest,
  context: { params: Promise<{ id: string }> }
) {
  try {
    const auditCtx = await getAdminAuditContext(req, { permission: "media.manage" });
    const { id } = await context.params;
    const body = await req.json();

    const updated = await db.updateMedia(id, {
      alt: typeof body.alt === "string" ? body.alt : undefined,
      caption: typeof body.caption === "string" ? body.caption : undefined,
    });

    if (updated) {
      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_METADATA_UPDATED",
        details: {
          assetId: updated.id,
          filename: updated.filename,
          alt: updated.alt,
          caption: updated.caption,
        },
        location: auditCtx.location,
      });
    }

    return NextResponse.json({ media: updated });
  } catch (err: any) {
    return NextResponse.json(
      { error: err.message || "Failed to update media item" },
      { status: err.status || 500 }
    );
  }
}

/**
 * DELETE /api/admin/media/[id]
 * Safely removes a media item. Rejects if referenced in articles or author profiles unless ?force=true.
 */
export async function DELETE(
  req: NextRequest,
  context: { params: Promise<{ id: string }> }
) {
  try {
    const auditCtx = await getAdminAuditContext(req, { permission: "media.manage" });
    const { id } = await context.params;
    const { searchParams } = new URL(req.url);
    const force = searchParams.get("force") === "true";

    const item = await db.getMediaById(id);
    if (!item) {
      return NextResponse.json({ error: "Media item not found" }, { status: 404 });
    }

    const [refsByUrl, refsById] = await Promise.all([
      getMediaReferences(item.url),
      getMediaReferences(item.id),
    ]);
    const allPosts = Array.from(new Set([...refsByUrl.posts, ...refsById.posts]));
    const allAuthors = Array.from(new Set([...refsByUrl.authors, ...refsById.authors]));
    const totalRefs = allPosts.length + allAuthors.length;

    if (totalRefs > 0 && !force) {
      const reasons: string[] = [];
      if (allPosts.length > 0) reasons.push(`${allPosts.length} article(s): "${allPosts.slice(0, 3).join('", "')}"`);
      if (allAuthors.length > 0) reasons.push(`${allAuthors.length} author profile(s): "${allAuthors.slice(0, 3).join('", "')}"`);

      return NextResponse.json(
        {
          error: `Media asset is in use by ${reasons.join(" and ")}. Confirm deletion with force=true to proceed.`,
          referencingPosts: allPosts,
          referencingAuthors: allAuthors,
        },
        { status: 409 }
      );
    }

    // Delete from Cloudinary or local disk
    if (item.provider === "cloudinary" && item.publicId) {
      await deleteAssetFromCloudinary(item.publicId);
    } else if (item.url.startsWith("/")) {
      await deletePhysicalMediaFile(item.url);
    }

    await db.deleteMedia(id);

    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_DELETED",
      details: {
        deletedAssetId: item.id,
        deletedFilename: item.filename,
        publicId: item.publicId,
        size: item.size,
        format: item.mimeType,
        provider: item.provider || "local",
        forced: force,
      },
      location: auditCtx.location,
    });

    return NextResponse.json({ success: true });
  } catch (err: any) {
    console.error("[DELETE /api/admin/media/[id]] Error:", err);
    return NextResponse.json(
      { error: err.message || "Failed to delete media item" },
      { status: err.status || 500 }
    );
  }
}
