/**
 * POST /api/admin/set-all-plans
 *
 * One-time bulk plan upgrade. Sets every brand on a free / unset
 * plan (trial / growth / null / "") to enterprise / annual.
 *
 * Optional body to scope or override:
 *   {
 *     fromPlans?: string[];   // default: ["trial", "growth", "", null-cast-to-empty]
 *     toPlan?:    string;     // default: "enterprise"
 *     billingCycle?: string;  // default: "annual"
 *   }
 *
 * Idempotent — running twice on the same brand is a no-op since the
 * second call's WHERE clause won't match. Logs to ComplianceEvent so
 * the regulatory trail records who flipped what.
 *
 * Superadmin-only.
 */

import { NextResponse } from "next/server";
import { prisma } from "@/lib/prisma";
import { getSuperadmin, requireSuperadmin, withAdminTiming } from "@/lib/admin-auth";
import type { Prisma } from "@prisma/client";

export const dynamic = "force-dynamic";
export const maxDuration = 60;

const VALID_PLANS = ["trial", "growth", "professional", "agency", "agency_pro", "enterprise"];
const VALID_CYCLES = ["monthly", "annual"];

export async function POST(req: Request) {
  const denied = await requireSuperadmin();
  if (denied) return denied;
  const admin = await getSuperadmin();
  if (!admin) return NextResponse.json({ error: "Forbidden" }, { status: 403 });

  const body = await req.json().catch(() => ({})) as {
    fromPlans?: string[];
    toPlan?: string;
    billingCycle?: string;
    orgId?: string;
  };

  // Default scope: any brand still on a "free or unset" plan. Empty
  // string covers brands created before plan: "trial" became the
  // default (Prisma backfilled them as ""). Null is impossible —
  // the column is non-null with default "trial" — but the IN list
  // is harmless if it slips in.
  const fromPlans = Array.isArray(body.fromPlans) && body.fromPlans.length > 0
    ? body.fromPlans
    : ["trial", "growth", ""];
  const toPlan = typeof body.toPlan === "string" && VALID_PLANS.includes(body.toPlan)
    ? body.toPlan
    : "enterprise";
  const billingCycle = typeof body.billingCycle === "string" && VALID_CYCLES.includes(body.billingCycle)
    ? body.billingCycle
    : "annual";

  const orgId = typeof body.orgId === "string" && body.orgId.trim() ? body.orgId.trim() : undefined;

  return NextResponse.json(await withAdminTiming("admin.set-all-plans", async () => {
    const where: Prisma.BrandWhereInput = {
      plan: { in: fromPlans },
      ...(orgId ? { orgId } : {}),
    };

    // Capture which brand ids are about to be flipped — useful for
    // the audit row + lets us skip the update entirely if nothing
    // matches (avoids a needless write).
    const targets = await prisma.brand.findMany({
      where,
      select: { id: true, plan: true, billingCycle: true },
    });
    if (targets.length === 0) {
      console.info("[admin] set-all-plans: nothing to update", { fromPlans, toPlan });
      return { ok: true as const, count: 0, fromPlans, toPlan, billingCycle, brandIds: [] as string[] };
    }

    const result = await prisma.brand.updateMany({
      where,
      data: { plan: toPlan, billingCycle },
    });

    console.info("[admin] set all brands to enterprise:", result.count);

    await prisma.complianceEvent.create({
      data: {
        action: "bulk_plan_change",
        details: {
          fromPlans,
          toPlan,
          billingCycle,
          count: result.count,
          ...(orgId ? { orgId } : {}),
          brandIds: targets.slice(0, 200).map((t) => t.id),
        } as object,
        requestedBy: admin.userId,
      },
    }).catch(() => {});

    return {
      ok: true as const,
      count: result.count,
      fromPlans,
      toPlan,
      billingCycle,
      brandIds: targets.map((t) => t.id),
    };
  }));
}
