import { redirect } from "next/navigation";
import Link from "next/link";

import { auth } from "@/lib/auth";
import { db } from "@/lib/db";
import { hasPaypalSubscriptions } from "@/lib/env";
import { getSubscription } from "@/lib/paypal";
import { reverseLookupPaypalPlan } from "@/lib/subscription-plans";
import { Card, CardContent } from "@/components/ui/card";
import { Button } from "@/components/ui/button";

export const dynamic = "force-dynamic";

// Pulled out of render so react-hooks/purity doesn't trip on `Date.now()`.
function derivePeriodEnd(nextBillingTime: string | undefined, interval: "MONTHLY" | "YEARLY") {
  if (nextBillingTime) return new Date(nextBillingTime);
  const days = interval === "YEARLY" ? 365 : 30;
  return new Date(Date.now() + days * 24 * 60 * 60 * 1000);
}

/**
 * PayPal subscription return target. PayPal redirects buyers here with
 * `?subscription_id=<id>` after they approve the subscription.
 *
 * We verify the subscription status server-side, then upsert the local
 * Subscription row. The webhook acts as a safety net for users who close
 * the tab between approval and this redirect (BILLING.SUBSCRIPTION.ACTIVATED).
 */
export default async function PaypalSubscriptionReturnPage({
  searchParams,
}: {
  searchParams: Promise<{ subscription_id?: string; ba_token?: string; token?: string }>;
}) {
  const session = await auth();
  if (!session?.user?.id) {
    redirect("/sign-in?callbackUrl=/dashboard/billing");
  }

  const { subscription_id: subscriptionId } = await searchParams;
  if (!subscriptionId) {
    return <ReturnError message="Missing PayPal subscription id." />;
  }
  if (!hasPaypalSubscriptions) {
    return <ReturnError message="PayPal subscriptions are not configured on this site." />;
  }

  let resource;
  try {
    resource = await getSubscription(subscriptionId);
  } catch (err) {
    const message = err instanceof Error ? err.message : "Couldn't verify the PayPal subscription.";
    return <ReturnError message={message} />;
  }

  // custom_id was set to userId in createSubscription — guard against a buyer
  // hitting the return URL of someone else's subscription.
  if (resource.custom_id && resource.custom_id !== session.user.id) {
    return <ReturnError message="This subscription belongs to a different account." />;
  }

  if (resource.status === "APPROVAL_PENDING" || resource.status === "APPROVED") {
    return (
      <ReturnError message="Your subscription is still being processed by PayPal. Refresh in a moment, or open billing to retry." />
    );
  }

  if (resource.status !== "ACTIVE") {
    return (
      <ReturnError
        message={`Subscription is not active (status: ${resource.status}). If you completed the PayPal flow, try refreshing in a minute or contact support.`}
      />
    );
  }

  const mapped = reverseLookupPaypalPlan(resource.plan_id);
  if (!mapped) {
    return (
      <ReturnError message="Subscription plan doesn't match a configured Trovo plan. Contact support." />
    );
  }

  const periodEnd = derivePeriodEnd(resource.next_billing_time, mapped.interval);

  await db.subscription.upsert({
    where: { userId: session.user.id },
    update: {
      plan: mapped.plan,
      billingInterval: mapped.interval,
      status: "ACTIVE",
      paypalSubscriptionId: subscriptionId,
      currentPeriodEnd: periodEnd,
      cancelAtPeriodEnd: false,
    },
    create: {
      userId: session.user.id,
      plan: mapped.plan,
      billingInterval: mapped.interval,
      status: "ACTIVE",
      paypalSubscriptionId: subscriptionId,
      currentPeriodEnd: periodEnd,
    },
  });

  redirect("/dashboard/billing?status=success");
}

function ReturnError({ message }: { message: string }) {
  return (
    <div className="mx-auto flex max-w-md flex-col gap-4 px-4 py-16">
      <Card>
        <CardContent className="flex flex-col gap-4 p-6 text-center">
          <h1 className="font-display text-2xl font-semibold">
            Subscription couldn&apos;t be activated
          </h1>
          <p className="text-sm text-muted-foreground">{message}</p>
          <div className="flex flex-col gap-2">
            <Button asChild>
              <Link href="/dashboard/billing">Back to billing</Link>
            </Button>
            <Button asChild variant="outline">
              <Link href="/dashboard">Go to dashboard</Link>
            </Button>
          </div>
        </CardContent>
      </Card>
    </div>
  );
}
