"use client";

import { useRouter } from "next/navigation";
import { useEffect, useState } from "react";

import { Button } from "@/components/ui/button";
import { toast } from "sonner";
import { siteConfig } from "@/lib/constants/site";
import { useCartStore } from "@/store/cart-store";

type RazorpayCheckoutInstance = {
  open: () => void;
  on: (event: string, handler: (response: { error?: { description?: string } }) => void) => void;
};

declare global {
  interface Window {
    Razorpay?: new (options: Record<string, unknown>) => RazorpayCheckoutInstance;
  }
}

type Props = {
  /** Checkout email — session email or guest field. */
  email: string;
};

/**
 * Loads Razorpay Checkout, creates an order server-side, verifies signature,
 * and falls back to local demo completion when keys are missing (development).
 */
export function RazorpayCheckout({ email }: Props) {
  const router = useRouter();
  const lines = useCartStore((s) => s.lines);
  const coupon = useCartStore((s) => s.coupon);
  const clear = useCartStore((s) => s.clear);
  const [loading, setLoading] = useState(false);
  const [scriptReady, setScriptReady] = useState(
    () => typeof window !== "undefined" && Boolean(window.Razorpay),
  );

  useEffect(() => {
    if (window.Razorpay) {
      return;
    }
    const existing = document.querySelector<HTMLScriptElement>(
      'script[src="https://checkout.razorpay.com/v1/checkout.js"]',
    );
    if (existing) {
      existing.addEventListener("load", () => setScriptReady(true), { once: true });
      return;
    }
    const s = document.createElement("script");
    s.src = "https://checkout.razorpay.com/v1/checkout.js";
    s.async = true;
    s.onload = () => setScriptReady(true);
    document.body.appendChild(s);
  }, []);

  async function pay() {
    if (!lines.length) {
      toast.error("Your cart is empty.");
      return;
    }
    if (!email.trim()) {
      toast.error("Enter a valid email for receipts.");
      return;
    }
    setLoading(true);
    try {
      const res = await fetch("/api/razorpay/create-order", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ lines, coupon, email }),
      });
      const data = (await res.json()) as Record<string, unknown>;
      if (!res.ok) {
        toast.error(typeof data.error === "string" ? data.error : "Could not start checkout.");
        return;
      }

      if (data.mode === "test") {
        toast.message("Sandbox payment — use Razorpay test UPI/card details.");
      }

      if (data.demo) {
        toast.message("Demo mode — completing order locally.");
        const demoRes = await fetch("/api/checkout/demo-complete", {
          method: "POST",
          headers: { "Content-Type": "application/json" },
          body: JSON.stringify({ orderId: data.orderId }),
        });
        if (!demoRes.ok) {
          const demoData = (await demoRes.json().catch(() => ({}))) as {
            error?: string;
          };
          toast.error(
            typeof demoData.error === "string"
              ? demoData.error
              : "Demo checkout could not be completed.",
          );
          return;
        }
        clear();
        router.push(`/dashboard?order=${String(data.orderId)}&paid=1`);
        router.refresh();
        return;
      }

      if (!window.Razorpay || !scriptReady) {
        toast.error("Payment script still loading — try again in a second.");
        return;
      }

      const checkoutKey =
        (typeof data.key === "string" ? data.key : undefined) ??
        process.env.NEXT_PUBLIC_RAZORPAY_KEY_ID;

      if (!checkoutKey) {
        toast.error("Payment key missing — check Razorpay configuration.");
        return;
      }

      const options = {
        key: checkoutKey,
        amount: data.amount,
        currency: data.currency,
        order_id: data.razorpayOrderId,
        name: siteConfig.name,
        description: "Digital products & coaching",
        prefill: { email },
        theme: { color: "#ef4444" },
        modal: {
          ondismiss: () => toast.message("Payment cancelled."),
        },
        handler: async (response: {
          razorpay_payment_id: string;
          razorpay_order_id: string;
          razorpay_signature: string;
        }) => {
          const verify = await fetch("/api/razorpay/verify", {
            method: "POST",
            headers: { "Content-Type": "application/json" },
            body: JSON.stringify({
              orderId: data.orderId,
              razorpay_order_id: response.razorpay_order_id,
              razorpay_payment_id: response.razorpay_payment_id,
              razorpay_signature: response.razorpay_signature,
            }),
          });
          if (!verify.ok) {
            const verifyData = (await verify.json().catch(() => ({}))) as { error?: string };
            toast.error(
              typeof verifyData.error === "string"
                ? verifyData.error
                : "Payment verification failed.",
            );
            router.push("/checkout/failure");
            return;
          }
          clear();
          router.push(`/dashboard?order=${String(data.orderId)}&paid=1`);
          router.refresh();
        },
      };

      const rz = new window.Razorpay(options);
      rz.on("payment.failed", (response: { error?: { description?: string } }) => {
        toast.error(response.error?.description ?? "Payment failed. Please try again.");
      });
      rz.open();
    } catch {
      toast.error("Unexpected error starting checkout.");
    } finally {
      setLoading(false);
    }
  }

  return (
    <>
      <Button
        type="button"
        disabled={loading}
        onClick={pay}
        className="neon-edge w-full rounded-full py-6 text-base font-semibold"
      >
        {loading ? "Processing…" : "Pay with Razorpay"}
      </Button>
    </>
  );
}
