import { NextRequest, NextResponse } from "next/server";
import { requirePermission, requireAuth, getAdminAuditContext } from "@/lib/admin/auth";
import { blogService, validatePostPreflight } from "@/lib/blog-service";
import { db } from "@/lib/admin/db";

export const dynamic = "force-dynamic";

/**
 * GET /api/admin/posts/[id]/publish
 * Evaluates preflight status for errors & warnings without mutating post state.
 */
export async function GET(
  req: NextRequest,
  context: { params: Promise<{ id: string }> }
) {
  try {
    const ctx = await requireAuth(req);

    const { id } = await context.params;
    const post = await db.getPostById(id);
    if (!post) {
      return NextResponse.json({ error: "Article not found" }, { status: 404 });
    }

    const preflight = validatePostPreflight(post);
    return NextResponse.json({ preflight });
  } catch (err: any) {
    return NextResponse.json(
      { error: err.message || "Failed to evaluate preflight" },
      { status: err.status || 500 }
    );
  }
}

/**
 * POST /api/admin/posts/[id]/publish
 * Executes state machine transition:
 * - "publish": Publishes immediately with preflight validation
 * - "schedule": Queues for future automated publishing
 * - "cancel-schedule": Reverts scheduled article to draft
 * - "archive": Removes article from public circulation
 */
export async function POST(
  req: NextRequest,
  context: { params: Promise<{ id: string }> }
) {
  try {
    const ctx = await requirePermission("posts.publish", req);
    const { id } = await context.params;
    const body = await req.json();
    const action = body.action;
    const auditCtx = await getAdminAuditContext(req);
    const actor = { ...ctx.user, location: auditCtx.location };

    // Atomically persist any dirty working draft updates before publishing
    if (body.draftUpdates) {
      await blogService.updateDraft(id, body.draftUpdates, actor);
    }

    let post;
    switch (action) {
      case "update-live":
      case "updateLive": {
        post = await blogService.updateLive(id, actor);
        break;
      }
      case "discard-draft":
      case "discardDraft": {
        post = await blogService.discardWorkingDraft(id, actor);
        break;
      }
      case "publish": {
        const existing = await db.getPostById(id);
        if (existing?.status === "PUBLISHED") {
          post = await blogService.updateLive(id, actor);
        } else {
          post = await blogService.publish(id, actor);
        }
        break;
      }
      case "schedule": {
        const scheduledFor = body.scheduledFor;
        if (!scheduledFor) {
          return NextResponse.json(
            { error: "A target publication date & time is required for scheduling." },
            { status: 400 }
          );
        }
        post = await blogService.schedule(id, scheduledFor, actor);
        break;
      }
      case "cancel-schedule": {
        const existing = await db.getPostById(id);
        if (!existing) {
          return NextResponse.json({ error: "Article not found" }, { status: 404 });
        }
        post = await db.updatePost(id, {
          status: "DRAFT",
          scheduledFor: null,
          updatedBy: 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: post.id,
          postTitle: post.title,
          postSlug: post.slug,
          action: "POST_EDITED",
          details: { note: "Schedule cancelled, reverted to DRAFT" },
        });
        break;
      }
      case "archive": {
        post = await blogService.archive(id, actor);
        break;
      }
      default:
        return NextResponse.json(
          {
            error: `Invalid publishing action '${action}'. Must be update-live, discard-draft, publish, schedule, cancel-schedule, or archive.`,
          },
          { status: 400 }
        );
    }

    return NextResponse.json({ post });
  } catch (err: any) {
    console.error("[POST /api/admin/posts/[id]/publish] Error:", err);
    return NextResponse.json(
      { error: err.message || "Publishing operation failed" },
      { status: err.status || 400 }
    );
  }
}
