"use client";

import {
  CardCvcElement,
  CardExpiryElement,
  CardNumberElement,
  Elements,
  useElements,
  useStripe,
} from "@stripe/react-stripe-js";
import { loadStripe, type StripeElementStyle } from "@stripe/stripe-js";
import { Lock } from "lucide-react";
import { useEffect, useMemo, useState, type FormEvent } from "react";
import { useTheme } from "@/context/theme-context";

type Props = {
  clientSecret: string;
  billingName: string;
  billingEmail: string;
  onPaid: (paymentIntentId: string) => void;
  onError: (message: string) => void;
};

function CardFields({
  clientSecret,
  billingName,
  billingEmail,
  onPaid,
  onError,
}: Props) {
  const stripe = useStripe();
  const elements = useElements();
  const [loading, setLoading] = useState(false);
  const { theme } = useTheme();

  const elementStyle: StripeElementStyle = useMemo(
    () => ({
      base: {
        fontSize: "15px",
        color: theme === "dark" ? "#f4f4f5" : "#18181b",
        fontFamily: "Outfit, system-ui, sans-serif",
        "::placeholder": {
          color: theme === "dark" ? "#71717a" : "#a1a1aa",
        },
      },
      invalid: { color: "#e11d2e" },
    }),
    [theme],
  );

  const onSubmit = async (event: FormEvent) => {
    event.preventDefault();
    if (!stripe || !elements) return;

    const cardNumber = elements.getElement(CardNumberElement);
    if (!cardNumber) return;

    setLoading(true);
    const result = await stripe.confirmCardPayment(clientSecret, {
      payment_method: {
        card: cardNumber,
        billing_details: {
          name: billingName,
          email: billingEmail,
        },
      },
    });

    if (result.error) {
      onError(result.error.message ?? "Payment failed");
      setLoading(false);
      return;
    }

    if (result.paymentIntent?.status === "succeeded") {
      onPaid(result.paymentIntent.id);
      return;
    }

    onError("Payment was not completed. Please try again.");
    setLoading(false);
  };

  return (
    <form onSubmit={onSubmit} className="space-y-4">
      <div>
        <p className="mb-1.5 text-sm font-medium">Card number</p>
        <div className="rounded-xl border border-border bg-background px-3 py-3">
          <CardNumberElement options={{ style: elementStyle }} />
        </div>
      </div>
      <div className="grid grid-cols-2 gap-3">
        <div>
          <p className="mb-1.5 text-sm font-medium">Expiry</p>
          <div className="rounded-xl border border-border bg-background px-3 py-3">
            <CardExpiryElement options={{ style: elementStyle }} />
          </div>
        </div>
        <div>
          <p className="mb-1.5 text-sm font-medium">CVC</p>
          <div className="rounded-xl border border-border bg-background px-3 py-3">
            <CardCvcElement options={{ style: elementStyle }} />
          </div>
        </div>
      </div>
      <button
        type="submit"
        disabled={!stripe || loading}
        className="inline-flex h-12 w-full items-center justify-center gap-2 rounded-full bg-foreground text-sm font-semibold text-background transition hover:opacity-90 disabled:opacity-60"
      >
        <Lock className="h-4 w-4" />
        {loading ? "Processing…" : "Pay now"}
      </button>
    </form>
  );
}

/** Self-hosted Stripe card fields on BhoFit checkout. */
export function StripeCardForm(props: Props) {
  const [publishableKey, setPublishableKey] = useState(
    process.env.NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY ?? "",
  );

  useEffect(() => {
    void fetch("/api/settings/public")
      .then((res) => res.json())
      .then(
        (data: {
          settings?: { stripePublishableKey?: string; stripeEnabled?: boolean };
        }) => {
          const key = data.settings?.stripePublishableKey?.trim();
          if (key) setPublishableKey(key);
        },
      )
      .catch(() => null);
  }, []);

  const stripePromise = useMemo(
    () => (publishableKey ? loadStripe(publishableKey) : null),
    [publishableKey],
  );

  if (!stripePromise) {
    return (
      <p className="rounded-xl border border-border bg-background px-4 py-3 text-sm text-muted">
        Add Stripe keys in Admin → Stripe payments (or .env) to enable cards.
      </p>
    );
  }

  return (
    <Elements stripe={stripePromise}>
      <CardFields {...props} />
    </Elements>
  );
}

/** Demo card UI when Stripe keys are not configured. */
export function DemoCardForm({ onPaid }: { onPaid: () => void }) {
  const [loading, setLoading] = useState(false);
  const [card, setCard] = useState({
    number: "",
    expiry: "",
    cvc: "",
  });

  const onSubmit = (event: FormEvent) => {
    event.preventDefault();
    setLoading(true);
    window.setTimeout(() => onPaid(), 700);
  };

  return (
    <form onSubmit={onSubmit} className="space-y-4">
      <label className="block text-sm">
        <span className="mb-1.5 block font-medium">Card number</span>
        <input
          required
          inputMode="numeric"
          placeholder="Card number"
          value={card.number}
          onChange={(event) =>
            setCard((current) => ({ ...current, number: event.target.value }))
          }
          className="h-11 w-full rounded-xl border border-border bg-background px-3 outline-none focus:border-foreground"
        />
      </label>
      <div className="grid grid-cols-2 gap-3">
        <label className="block text-sm">
          <span className="mb-1.5 block font-medium">Expiry</span>
          <input
            required
            placeholder="MM / YY"
            value={card.expiry}
            onChange={(event) =>
              setCard((current) => ({ ...current, expiry: event.target.value }))
            }
            className="h-11 w-full rounded-xl border border-border bg-background px-3 outline-none focus:border-foreground"
          />
        </label>
        <label className="block text-sm">
          <span className="mb-1.5 block font-medium">CVC</span>
          <input
            required
            placeholder="123"
            value={card.cvc}
            onChange={(event) =>
              setCard((current) => ({ ...current, cvc: event.target.value }))
            }
            className="h-11 w-full rounded-xl border border-border bg-background px-3 outline-none focus:border-foreground"
          />
        </label>
      </div>
      <button
        type="submit"
        disabled={loading}
        className="inline-flex h-12 w-full items-center justify-center gap-2 rounded-full bg-foreground text-sm font-semibold text-background transition hover:opacity-90 disabled:opacity-60"
      >
        <Lock className="h-4 w-4" />
        {loading ? "Processing…" : "Pay now"}
      </button>
    </form>
  );
}
