import { NextRequest, NextResponse } from "next/server";
import Stripe from "stripe";
import { eq } from "drizzle-orm";
import { getCurrentUser } from "@/lib/auth/session";
import { requireCsrf } from "@/lib/auth/csrf";
import { db, isDatabaseAvailable, schema } from "@/lib/db";

const stripe = process.env.STRIPE_SECRET_KEY
  ? new Stripe(process.env.STRIPE_SECRET_KEY, {
      apiVersion: "2025-01-27.acacia" as any,
      maxNetworkRetries: 2,
    })
  : null;

export const runtime = "nodejs";

export async function POST(req: NextRequest) {
  try {
    const csrfBlocked = requireCsrf(req);
    if (csrfBlocked) return csrfBlocked;

    const user = await getCurrentUser(req);
    if (!user) {
      return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
    }

    const hasDb = await isDatabaseAvailable().catch(() => false);

    // A recurring Stripe subscription is cancelled at period end, so Pro
    // access (and the Pro badge) continues for whatever the user already
    // paid for. A plan with no subscription behind it (lifetime, or a plan
    // granted without Stripe) has no period to run out, so it downgrades
    // immediately instead.
    if (user.stripeSubscriptionId && stripe) {
      try {
        await stripe.subscriptions.update(user.stripeSubscriptionId, {
          cancel_at_period_end: true,
        });
      } catch (stripeErr: any) {
        console.warn("Could not schedule Stripe subscription cancellation (may already be cancelled):", stripeErr?.message);
      }

      if (hasDb) {
        try {
          // Optimistic UI flag — the authoritative sync happens via the
          // customer.subscription.updated webhook, which may lag behind.
          await db
            .update(schema.users)
            .set({
              cancelAtPeriodEnd: true,
              updatedAt: new Date(),
            })
            .where(eq(schema.users.id, user.id));
        } catch (dbErr) {
          console.error("Database error while scheduling subscription cancellation:", dbErr);
        }
      }

      return NextResponse.json({
        success: true,
        scheduled: true,
        expiresAt: user.expiresAt ? user.expiresAt.toISOString() : null,
        message: "Subscription will cancel at the end of the current billing period.",
      });
    }

    // No Stripe subscription behind the plan — downgrade immediately.
    if (hasDb) {
      try {
        await db
          .update(schema.users)
          .set({
            plan: "free",
            stripeSubscriptionId: null,
            expiresAt: null,
            cancelAtPeriodEnd: false,
            updatedAt: new Date(),
          })
          .where(eq(schema.users.id, user.id));
      } catch (dbErr) {
        console.error("Database error while cancelling subscription:", dbErr);
      }
    }

    return NextResponse.json({
      success: true,
      scheduled: false,
      plan: "free",
      message: "Subscription cancelled and downgraded to Free successfully.",
    });
  } catch (error: any) {
    console.error("Subscription cancel error:", error);
    return NextResponse.json(
      { error: error?.message || "Fehler beim Kündigen des Abonnements." },
      { status: 500 }
    );
  }
}
