"use client";

import { useState } from "react";
import { useRouter } from "next/navigation";
import { Check, Loader2, CreditCard, ExternalLink } from "lucide-react";
import { toast } from "sonner";
import { Button } from "@/components/ui/button";
import { Badge } from "@/components/ui/badge";
import { Card, CardContent } from "@/components/ui/card";
import { cn, formatPrice } from "@/lib/utils";
import { PLAN_ORDER, PLANS, type PlanKey } from "@/lib/billing/plans";
import type { BillingInterval } from "@/lib/billing/catalog";
import {
  startStripeCheckoutAction,
  startPaypalCheckoutAction,
  openStripePortalAction,
  cancelSubscriptionAction,
} from "@/app/(app)/billing/actions";

interface SubInfo {
  provider: string;
  status: string;
  cancelAtPeriodEnd: boolean | null;
  periodEnd: string | null;
}

export function BillingClient({
  currentPlan,
  subscription,
  stripeConfigured,
  paypalConfigured,
}: {
  currentPlan: PlanKey;
  subscription: SubInfo | null;
  stripeConfigured: boolean;
  paypalConfigured: boolean;
}) {
  const router = useRouter();
  const [interval, setInterval] = useState<BillingInterval>("month");
  const [busy, setBusy] = useState<string | null>(null);

  async function go(action: () => Promise<{ ok: boolean; url?: string; error?: string }>, tag: string) {
    setBusy(tag);
    const res = await action();
    if (res.ok && res.url) {
      window.location.href = res.url;
      return;
    }
    setBusy(null);
    if (res.ok) {
      toast.success("Done");
      router.refresh();
    } else {
      toast.error(res.error ?? "Something went wrong");
    }
  }

  return (
    <div className="space-y-8">
      {subscription && currentPlan !== "free" && (
        <Card>
          <CardContent className="flex flex-col gap-4 py-6 sm:flex-row sm:items-center sm:justify-between">
            <div>
              <div className="flex items-center gap-2">
                <span className="font-semibold capitalize">{PLANS[currentPlan].name} plan</span>
                <Badge variant={subscription.status === "active" ? "success" : "warning"}>
                  {subscription.cancelAtPeriodEnd ? "Cancels at period end" : subscription.status}
                </Badge>
                <Badge variant="outline" className="capitalize">{subscription.provider}</Badge>
              </div>
              {subscription.periodEnd && (
                <p className="mt-1 text-sm text-muted-foreground">
                  {subscription.cancelAtPeriodEnd ? "Access until" : "Renews"}{" "}
                  {new Date(subscription.periodEnd).toLocaleDateString()}
                </p>
              )}
            </div>
            <div className="flex gap-2">
              {subscription.provider === "stripe" && (
                <Button variant="outline" onClick={() => go(openStripePortalAction, "portal")} disabled={busy === "portal"}>
                  {busy === "portal" ? <Loader2 className="h-4 w-4 animate-spin" /> : <ExternalLink className="h-4 w-4" />}
                  Manage
                </Button>
              )}
              {!subscription.cancelAtPeriodEnd && (
                <Button
                  variant="ghost"
                  className="text-destructive"
                  onClick={() => {
                    if (confirm("Cancel your subscription at the end of the period?")) {
                      go(cancelSubscriptionAction, "cancel");
                    }
                  }}
                  disabled={busy === "cancel"}
                >
                  {busy === "cancel" && <Loader2 className="h-4 w-4 animate-spin" />}
                  Cancel
                </Button>
              )}
            </div>
          </CardContent>
        </Card>
      )}

      <div className="flex items-center justify-center gap-2">
        <IntervalToggle interval={interval} onChange={setInterval} />
      </div>

      <div className="grid gap-4 lg:grid-cols-4">
        {PLAN_ORDER.map((key) => {
          const plan = PLANS[key];
          const isCurrent = key === currentPlan;
          const price = interval === "year" ? plan.priceYearly : plan.priceMonthly;
          return (
            <Card key={key} className={cn("relative", plan.highlight && "ring-2 ring-brand")}>
              {plan.highlight && (
                <Badge className="absolute -top-3 left-1/2 -translate-x-1/2 bg-brand text-brand-foreground shadow-sm">
                  Most popular
                </Badge>
              )}
              <CardContent className="space-y-4 p-5">
                <div>
                  <h3 className="font-semibold">{plan.name}</h3>
                  <p className="mt-1 text-xs text-muted-foreground">{plan.tagline}</p>
                </div>
                <div className="flex items-baseline gap-1">
                  <span className="font-display text-3xl font-extrabold tracking-tight">{formatPrice(price)}</span>
                  <span className="text-xs text-muted-foreground">/{interval === "year" ? "yr" : "mo"}</span>
                </div>

                {isCurrent ? (
                  <Button variant="secondary" className="w-full" disabled>
                    <Check className="h-4 w-4" /> Current plan
                  </Button>
                ) : key === "free" ? (
                  <Button variant="outline" className="w-full" disabled>
                    Free
                  </Button>
                ) : (
                  <div className="space-y-2">
                    {stripeConfigured && (
                      <Button
                        className="w-full"
                        onClick={() => go(() => startStripeCheckoutAction(key, interval), `stripe-${key}`)}
                        disabled={busy === `stripe-${key}`}
                      >
                        {busy === `stripe-${key}` ? (
                          <Loader2 className="h-4 w-4 animate-spin" />
                        ) : (
                          <CreditCard className="h-4 w-4" />
                        )}
                        Pay with card
                      </Button>
                    )}
                    {paypalConfigured && (
                      <Button
                        variant="outline"
                        className="w-full"
                        onClick={() => go(() => startPaypalCheckoutAction(key), `paypal-${key}`)}
                        disabled={busy === `paypal-${key}`}
                      >
                        {busy === `paypal-${key}` ? <Loader2 className="h-4 w-4 animate-spin" /> : null}
                        PayPal
                      </Button>
                    )}
                    {!stripeConfigured && !paypalConfigured && (
                      <p className="text-center text-xs text-muted-foreground">Billing not configured</p>
                    )}
                  </div>
                )}

                <ul className="space-y-1.5 pt-2 text-xs">
                  {plan.bullets.slice(0, 5).map((b) => (
                    <li key={b} className="flex gap-1.5">
                      <Check className="mt-0.5 h-3.5 w-3.5 shrink-0 text-brand" />
                      <span className="text-muted-foreground">{b}</span>
                    </li>
                  ))}
                </ul>
              </CardContent>
            </Card>
          );
        })}
      </div>
    </div>
  );
}

function IntervalToggle({
  interval,
  onChange,
}: {
  interval: BillingInterval;
  onChange: (i: BillingInterval) => void;
}) {
  return (
    <div className="inline-flex rounded-full border border-border bg-secondary p-1">
      {(["month", "year"] as const).map((i) => (
        <button
          key={i}
          onClick={() => onChange(i)}
          className={cn(
            "rounded-full px-4 py-1.5 text-sm font-medium transition-colors",
            interval === i ? "bg-background text-foreground shadow-sm" : "text-muted-foreground"
          )}
        >
          {i === "month" ? "Monthly" : "Yearly"}
          {i === "year" && <span className="ml-1 text-xs opacity-80">(2 mo free)</span>}
        </button>
      ))}
    </div>
  );
}
