import { createFileRoute, useNavigate } from "@tanstack/react-router";
import { useEffect, useMemo, useState } from "react";
import { PageHeader } from "@/components/common/PageHeader";
import { Button } from "@/components/ui/button";
import { CheckCircle2, Loader2 } from "lucide-react";
import { toast } from "sonner";
import { useCheckoutStore } from "@/store/checkout";
import { useAuthStore } from "@/store/auth";
import { checkoutService, computeTotals } from "@/services/api/checkout";
import { PromoCodeInput } from "@/components/common/PromoCodeInput";
import type { PromoApplyResult } from "@/services/api/promo";
import { Badge } from "@/components/ui/badge";
import { formatGEL, toWGC, LariMark, WGCMark } from "@/lib/currency";
import { Package, Crown, Star, Wallet, ArrowLeftRight, Gift } from "lucide-react";
import {
  CheckoutItemDetails, CheckoutServerSelector, CheckoutDurationSelector,
  CheckoutRecipient, CheckoutPaymentMethod, CheckoutTerms, SubscriptionPlanSummary,
  PrivilegeDetails, BalanceTopUpPreview, MarketplaceDetails, ProductOptions,
} from "@/features/checkout/CheckoutSections";
import { products } from "@/features/_mock/data";
import type { PurchaseContext } from "@/types";

export const Route = createFileRoute("/_public/checkout/")({
  head: () => ({ meta: [
    { title: "Checkout — Purple Zone" },
    { name: "description", content: "Universal checkout for products, privileges, subscription, balance and marketplace." },
  ] }),
  component: CheckoutPage,
});

function CheckoutPage() {
  const ctxFromStore = useCheckoutStore((s) => s.ctx);
  const user = useAuthStore((s) => s.user);
  const navigate = useNavigate();

  const [ctx, setCtx] = useState<PurchaseContext>(() => ctxFromStore ?? {
    purchaseType: "product",
    itemId: products[0].id, itemName: products[0].name, price: products[0].price,
    quantity: 1, duration: products[0].duration, metadata: { category: products[0].category },
  });
  useEffect(() => { if (ctxFromStore) setCtx(ctxFromStore); }, [ctxFromStore]);

  const [serverId, setServerId] = useState<string | undefined>(ctx.serverId);
  const [duration, setDuration] = useState<string | undefined>(ctx.duration);
  const [quantity, setQuantity] = useState(ctx.quantity ?? 1);
  const [giftEnabled, setGiftEnabled] = useState(!!ctx.recipientId);
  const [recipientId, setRecipientId] = useState<string | undefined>(ctx.recipientId);
  const [payment, setPayment] = useState<string>("balance");
  const [terms, setTerms] = useState(false);
  const [autoRenew, setAutoRenew] = useState(true);
  const [promo, setPromo] = useState<PromoApplyResult | null>(null);
  const [submitting, setSubmitting] = useState(false);
  const [orderId, setOrderId] = useState<string | null>(null);

  const effectiveCtx = useMemo<PurchaseContext>(() => ({
    ...ctx, quantity, duration, serverId: serverId === "all" ? undefined : serverId,
    recipientId: giftEnabled ? recipientId : undefined,
  }), [ctx, quantity, duration, serverId, giftEnabled, recipientId]);

  const totals = computeTotals(effectiveCtx, promo?.ok ? promo.discountAmount : 0);

  const meta = purchaseMeta(ctx.purchaseType);

  async function submit() {
    if (!terms) { toast.error("Please accept the terms"); return; }
    if (giftEnabled && !recipientId) { toast.error("Choose a recipient"); return; }
    if (payment === "balance" && (user?.balance ?? 0) < totals.total) { toast.error("Insufficient balance"); return; }
    setSubmitting(true);
    try {
      const res = await checkoutService.submit(effectiveCtx, { promoCode: promo?.ok ? promo.code.code : undefined, paymentMethod: payment, recipientId });
      setOrderId(res.orderId);
      toast.success("Purchase complete");
    } catch { toast.error("Payment failed. Try again."); } finally { setSubmitting(false); }
  }

  if (orderId) {
    return (
      <div className="mx-auto max-w-xl px-4 py-16 text-center">
        <CheckCircle2 className="mx-auto h-14 w-14 text-success" />
        <h1 className="mt-4 font-display text-2xl font-bold">Purchase complete</h1>
        <p className="mt-2 text-sm text-muted-foreground">Order <span className="font-mono">{orderId}</span> has been recorded.</p>
        <div className="mt-6 flex justify-center gap-2">
          <Button variant="outline" onClick={() => navigate({ to: "/account/orders" })}>View orders</Button>
          <Button className="gradient-primary text-primary-foreground" onClick={() => navigate({ to: "/store" })}>Back to store</Button>
        </div>
      </div>
    );
  }

  const showServer = ctx.purchaseType === "product" || ctx.purchaseType === "privilege";
  const showDuration = !!ctx.duration && ctx.purchaseType !== "subscription" && ctx.purchaseType !== "balance";
  const showRecipient = ctx.purchaseType !== "balance" && ctx.purchaseType !== "marketplace";
  const showQuantity = ctx.purchaseType === "product" || ctx.purchaseType === "marketplace";

  return (
    <div className="mx-auto max-w-5xl px-4 py-6">
      <PageHeader
        title="Checkout"
        description="One universal checkout for every purchasable item."
      />
      <div className={`mb-4 flex items-start gap-3 rounded-xl border ${meta.border} ${meta.bg} p-4`}>
        <div className={`grid h-10 w-10 shrink-0 place-items-center rounded-lg ${meta.iconBg}`}>
          <meta.icon className="h-5 w-5 text-primary-foreground" />
        </div>
        <div className="min-w-0 flex-1">
          <div className="flex flex-wrap items-center gap-2">
            <Badge className="gradient-primary text-primary-foreground uppercase tracking-wider">{meta.tag}</Badge>
            <span className="truncate font-display text-sm font-semibold">{ctx.itemName}</span>
          </div>
          <div className="mt-0.5 text-xs text-muted-foreground">{meta.blurb}</div>
        </div>
        <div className="text-right">
          <div className="flex items-baseline gap-1 font-display text-lg font-bold text-secondary">
            <LariMark className="h-4 w-4" /> {formatGEL(totals.total, { withSymbol: false })}
          </div>
          <div className="text-[11px] text-muted-foreground">or {toWGC(totals.total).toLocaleString()} WGC</div>
        </div>
      </div>
      <div className="grid gap-6 lg:grid-cols-[1fr_400px]">
        <div className="space-y-4">
          <CheckoutItemDetails ctx={effectiveCtx} />

          {ctx.purchaseType === "subscription" && (
            <SubscriptionPlanSummary planId={ctx.metadata?.planId as string | undefined} autoRenew={autoRenew} onAutoRenew={setAutoRenew} />
          )}
          {ctx.purchaseType === "privilege" && <PrivilegeDetails ctx={effectiveCtx} />}
          {ctx.purchaseType === "balance" && <BalanceTopUpPreview ctx={effectiveCtx} currentBalance={user?.balance ?? 0} />}
          {ctx.purchaseType === "marketplace" && <MarketplaceDetails ctx={effectiveCtx} fee={totals.fee} />}
          {ctx.purchaseType === "product" && <ProductOptions ctx={effectiveCtx} quantity={quantity} onQuantity={setQuantity} />}

          <div className="rounded-xl border border-border bg-card p-4 space-y-3">
            <h3 className="font-semibold">Delivery</h3>
            {showServer && <CheckoutServerSelector value={serverId ?? "all"} onChange={(v) => setServerId(v === "all" ? undefined : v)} />}
            {showDuration && <CheckoutDurationSelector options={[duration!]} value={duration} onChange={setDuration} />}
            {showRecipient && <CheckoutRecipient enabled={giftEnabled} onToggle={setGiftEnabled} value={recipientId} onChange={setRecipientId} />}
            {!showServer && !showDuration && !showRecipient && !showQuantity && (
              <p className="text-xs text-muted-foreground">Nothing to configure for this purchase.</p>
            )}
          </div>

          <div className="rounded-xl border border-border bg-card p-4 space-y-3">
            <h3 className="font-semibold">Promo code</h3>
            <PromoCodeInput ctx={effectiveCtx} subtotal={totals.subtotal} applied={promo} onApply={setPromo} onRemove={() => setPromo(null)} />
          </div>
        </div>

        <aside className="h-fit rounded-xl border border-border bg-card p-4">
          <h3 className="font-semibold">Payment</h3>
          <div className="mt-3 space-y-2 text-sm">
            <div className="flex justify-between"><span className="text-muted-foreground">Subtotal</span><span className="font-mono">{formatGEL(totals.subtotal)}</span></div>
            {totals.fee > 0 && <div className="flex justify-between"><span className="text-muted-foreground">Fee</span><span className="font-mono">{formatGEL(totals.fee)}</span></div>}
            <div className="flex justify-between"><span className="text-muted-foreground">Discount</span><span className="font-mono text-success">−{formatGEL(totals.discount)}</span></div>
            <div className="border-t border-border pt-2 flex justify-between font-semibold"><span>Total</span><span className="font-mono text-secondary">{formatGEL(totals.total)}</span></div>
            <div className="flex items-center justify-between text-[11px] text-muted-foreground">
              <span className="flex items-center gap-1"><WGCMark className="h-3 w-3" /> or pay in coins</span>
              <span className="font-mono">{toWGC(totals.total).toLocaleString()} WGC</span>
            </div>
          </div>
          <div className="mt-4"><CheckoutPaymentMethod value={payment} onChange={setPayment} balance={user?.balance ?? 0} /></div>
          <div className="mt-4"><CheckoutTerms checked={terms} onChange={setTerms} /></div>
          <Button onClick={submit} disabled={submitting || !terms} className="mt-4 w-full gradient-primary text-primary-foreground shadow-glow hover:opacity-95">
            {submitting ? <><Loader2 className="mr-2 h-4 w-4 animate-spin" /> Processing…</> : `Pay ${formatGEL(totals.total)}`}
          </Button>
          <p className="mt-2 text-[11px] text-muted-foreground">Final total, promo eligibility and availability are validated by the backend before charging.</p>
        </aside>
      </div>
    </div>
  );
}

function purchaseMeta(type: PurchaseContext["purchaseType"]) {
  switch (type) {
    case "product":     return { tag: "Store product",  icon: Package,        blurb: "Digital item added to your account after purchase.", border: "border-primary/30", bg: "bg-primary/5",  iconBg: "gradient-primary" };
    case "privilege":   return { tag: "Privilege",      icon: Star,           blurb: "Server privileges applied once payment clears.",     border: "border-primary/30", bg: "bg-primary/5",  iconBg: "gradient-primary" };
    case "subscription":return { tag: "Subscription",   icon: Crown,          blurb: "Platform-wide benefits, applied instantly.",         border: "border-secondary/40", bg: "bg-secondary/5", iconBg: "gradient-primary" };
    case "balance":     return { tag: "Balance top-up", icon: Wallet,         blurb: "Funds added to your ₾ GEL wallet.",                  border: "border-success/40", bg: "bg-success/5",  iconBg: "gradient-primary" };
    case "marketplace": return { tag: "Marketplace",    icon: ArrowLeftRight, blurb: "Peer-to-peer purchase. Small platform fee applies.", border: "border-warning/40", bg: "bg-warning/5",  iconBg: "gradient-primary" };
    case "gift":        return { tag: "Gift",           icon: Gift,           blurb: "Delivered to the recipient once paid.",              border: "border-info/40",    bg: "bg-info/5",     iconBg: "gradient-primary" };
    default:            return { tag: "Purchase",       icon: Package,        blurb: "",                                                   border: "border-border",     bg: "bg-card",       iconBg: "gradient-primary" };
  }
}
