import { NextRequest, NextResponse } from "next/server"; import { activateProPlan, adminResetUserCredits, grantExtraCredits, markFreeTopUpPurchased, } from "@/lib/billing"; import { FREE_TOP_UP_CREDITS } from "@/lib/credits"; import { isBillingDevMock } from "@/lib/stripe"; import { getSessionUser } from "@/lib/session"; /** * Local-only billing helpers (no Stripe CLI required). * Enabled when NODE_ENV=development (unless BILLING_DEV_MOCK=false) or BILLING_DEV_MOCK=true. */ function assertDev() { if (!isBillingDevMock()) { return NextResponse.json({ error: "Not available outside development mock mode" }, { status: 404 }); } return null; } export async function POST(req: NextRequest) { const blocked = assertDev(); if (blocked) return blocked; const user = await getSessionUser(); if (!user) { return NextResponse.json({ error: "Unauthorized" }, { status: 401 }); } let body: { action?: string; credits?: number; plan?: "FREE" | "PREMIUM"; }; try { body = await req.json(); } catch { return NextResponse.json({ error: "Invalid JSON" }, { status: 400 }); } const action = body.action ?? "grant-credits"; switch (action) { case "grant-credits": { const credits = Math.floor(Number(body.credits ?? FREE_TOP_UP_CREDITS)); if (!Number.isFinite(credits) || credits <= 0) { return NextResponse.json({ error: "Invalid credits" }, { status: 400 }); } await grantExtraCredits(user.id, credits); return NextResponse.json({ ok: true, granted: credits }); } case "free-top-up": { await markFreeTopUpPurchased(user.id); return NextResponse.json({ ok: true, granted: FREE_TOP_UP_CREDITS }); } case "set-pro": { await activateProPlan(user.id, { stripeSubscriptionId: `dev_sub_${Date.now()}`, cardLast4: "4242", }); return NextResponse.json({ ok: true, plan: "PREMIUM" }); } case "set-free": { await adminResetUserCredits(user.id, { plan: "FREE", creditsUsed: 0 }); return NextResponse.json({ ok: true, plan: "FREE" }); } case "reset-cycle": { await adminResetUserCredits(user.id, { plan: body.plan, creditsUsed: 0, }); return NextResponse.json({ ok: true, reset: true }); } default: return NextResponse.json({ error: `Unknown action: ${action}` }, { status: 400 }); } } /** Convenience GET for quick browser testing: /api/dev/grant-credits?action=set-pro */ export async function GET(req: NextRequest) { const blocked = assertDev(); if (blocked) return blocked; const action = req.nextUrl.searchParams.get("action") ?? "grant-credits"; const credits = Number(req.nextUrl.searchParams.get("credits") ?? FREE_TOP_UP_CREDITS); const fake = new NextRequest(req.url, { method: "POST", headers: { "content-type": "application/json", cookie: req.headers.get("cookie") ?? "" }, body: JSON.stringify({ action, credits }), }); return POST(fake); }