"use client";

import { useEffect, useState } from "react";
import { Elements, PaymentElement, useElements, useStripe } from "@stripe/react-stripe-js";
import { loadStripe, Stripe as StripeJS } from "@stripe/stripe-js";
import type { PublicRegion, PublicTier } from "@/types/public";

interface Props {
  region: PublicRegion;
  tier: PublicTier | undefined;
  onClose: () => void;
}

let stripePromise: Promise<StripeJS | null> | null = null;
function getStripe(): Promise<StripeJS | null> {
  if (!stripePromise) {
    const key = process.env.NEXT_PUBLIC_STRIPE_PUBLIC_KEY;
    stripePromise = key ? loadStripe(key) : Promise.resolve(null);
  }
  return stripePromise;
}

function formatUSD(cents: number): string {
  const d = cents / 100;
  return Number.isInteger(d)
    ? `$${d.toLocaleString("en-US")}`
    : `$${d.toLocaleString("en-US", { minimumFractionDigits: 2 })}`;
}

export default function DonateModal({ region, tier, onClose }: Props) {
  const [step, setStep] = useState<"form" | "pay" | "submitting">("form");
  const [clientSecret, setClientSecret] = useState<string | null>(null);
  const [donationId, setDonationId] = useState<string | null>(null);
  const [err, setErr] = useState<string | null>(null);

  // Form state
  const [message, setMessage] = useState("");
  const [name, setName] = useState("");
  const [email, setEmail] = useState("");
  const [website, setWebsite] = useState("");
  const [anonymous, setAnonymous] = useState(false);
  const [agreed, setAgreed] = useState(false);

  // Validation
  const messageOk = message.trim().length >= 1 && message.trim().length <= 60;
  const nameOk = anonymous || name.trim().length >= 1;
  const emailOk = /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email);
  const websiteOk =
    !website.trim() ||
    /^https?:\/\/[^\s]+$/i.test(website.trim());
  const formOk = messageOk && nameOk && emailOk && websiteOk && agreed;

  async function handleStartPayment() {
    setErr(null);
    setStep("submitting");
    try {
      const res = await fetch("/api/checkout", {
        method: "POST",
        headers: { "content-type": "application/json" },
        body: JSON.stringify({
          regionId: region.id,
          tierId: region.tier,
          message: message.trim(),
          donorName: anonymous ? null : name.trim(),
          donorEmail: email.trim(),
          websiteUrl: website.trim() || null,
          isAnonymous: anonymous,
        }),
      });
      const data = await res.json();
      if (!res.ok) {
        setErr(data.error || "Could not start payment");
        setStep("form");
        return;
      }
      setClientSecret(data.clientSecret);
      setDonationId(data.donationId);
      setStep("pay");
    } catch (e) {
      setErr("Network error");
      setStep("form");
    }
  }

  // Close on Esc
  useEffect(() => {
    const onKey = (e: KeyboardEvent) => {
      if (e.key === "Escape") onClose();
    };
    window.addEventListener("keydown", onKey);
    return () => window.removeEventListener("keydown", onKey);
  }, [onClose]);

  if (!tier) return null;

  return (
    <div
      className="fixed inset-0 z-50 flex items-end justify-center bg-black/40 p-0 md:items-center md:p-6"
      onClick={onClose}
    >
      <div
        className="w-full max-w-lg rounded-t-2xl bg-white p-6 shadow-xl md:rounded-2xl"
        onClick={(e) => e.stopPropagation()}
      >
        <div className="flex items-start justify-between">
          <div>
            <div className="text-xs uppercase tracking-wider text-textmuted">
              {tier.label}
            </div>
            <div className="font-display text-2xl font-bold text-text">
              Dedicate this piece — {formatUSD(region.priceCents)}
            </div>
          </div>
          <button
            type="button"
            onClick={onClose}
            className="rounded-full p-2 text-textmuted hover:bg-surface"
            aria-label="Close"
          >
            ✕
          </button>
        </div>

        {step === "form" || step === "submitting" ? (
          <div className="mt-5 space-y-4">
            <Field
              label="Your dedication message (max 60 chars)"
              hint={`${message.length}/60`}
            >
              <input
                type="text"
                maxLength={60}
                value={message}
                onChange={(e) => setMessage(e.target.value)}
                placeholder="In memory of Mary Smith"
                className="input"
              />
            </Field>

            {!anonymous && (
              <Field label="Your name or organization">
                <input
                  type="text"
                  value={name}
                  onChange={(e) => setName(e.target.value)}
                  placeholder="Joe's Plumbing & Heating"
                  className="input"
                />
              </Field>
            )}

            <Field label="Email (for tax receipt)">
              <input
                type="email"
                value={email}
                onChange={(e) => setEmail(e.target.value)}
                placeholder="you@example.com"
                className="input"
              />
            </Field>

            <Field label="Website URL (optional)">
              <input
                type="url"
                value={website}
                onChange={(e) => setWebsite(e.target.value)}
                placeholder="https://yourcompany.com"
                className="input"
              />
            </Field>

            <label className="flex items-center gap-2 text-sm text-text">
              <input
                type="checkbox"
                checked={anonymous}
                onChange={(e) => setAnonymous(e.target.checked)}
              />
              Donate anonymously (your name will not be displayed publicly,
              but PIFF will retain it for receipt and audit purposes)
            </label>

            <label className="flex items-start gap-2 text-sm text-text">
              <input
                type="checkbox"
                checked={agreed}
                onChange={(e) => setAgreed(e.target.checked)}
                className="mt-1"
              />
              <span>
                I agree to the{" "}
                <a
                  href="/donate/terms"
                  target="_blank"
                  rel="noopener noreferrer"
                  className="text-primary underline"
                >
                  Terms of Donation
                </a>
                .
              </span>
            </label>

            {/* Live preview */}
            <div className="rounded-lg border border-border bg-surface p-3 text-sm">
              <div className="text-xs uppercase tracking-wider text-textmuted">
                Preview
              </div>
              <div className="mt-1 italic text-text">
                &ldquo;{message || "Your dedication will appear here"}&rdquo;
              </div>
              {!anonymous && name && (
                <div className="text-xs text-textmuted">— {name}</div>
              )}
              {anonymous && (
                <div className="text-xs text-textmuted">— Anonymous</div>
              )}
            </div>

            {err && (
              <div className="rounded-md bg-red-50 p-3 text-sm text-red-700">
                {err}
              </div>
            )}

            <button
              type="button"
              disabled={!formOk || step === "submitting"}
              onClick={handleStartPayment}
              className="w-full rounded-full bg-primary py-3 font-medium text-white hover:bg-primaryDark disabled:cursor-not-allowed disabled:opacity-50"
            >
              {step === "submitting"
                ? "Preparing payment…"
                : `Donate ${formatUSD(region.priceCents)}`}
            </button>
            {!formOk && (
              <ul className="space-y-1 text-xs text-textmuted">
                {!messageOk && <li>· Message must be 1–60 characters.</li>}
                {!nameOk && <li>· Name is required (or check Anonymous).</li>}
                {!emailOk && <li>· A valid email is required.</li>}
                {!websiteOk && <li>· Website URL must be a valid http/https URL.</li>}
                {!agreed && <li>· You must agree to the Terms of Donation.</li>}
              </ul>
            )}
          </div>
        ) : null}

        {step === "pay" && clientSecret && donationId ? (
          <div className="mt-5">
            <Elements
              stripe={getStripe()}
              options={{ clientSecret, appearance: { theme: "stripe" } }}
            >
              <PaymentForm
                amountCents={region.priceCents}
                donationId={donationId}
                onError={(m) => setErr(m)}
              />
            </Elements>
            {err && (
              <div className="mt-3 rounded-md bg-red-50 p-3 text-sm text-red-700">
                {err}
              </div>
            )}
          </div>
        ) : null}
      </div>

      <style jsx>{`
        .input {
          width: 100%;
          border: 1px solid #d4d1ca;
          border-radius: 0.5rem;
          padding: 0.625rem 0.75rem;
          background: white;
          font-size: 0.95rem;
          color: #28251d;
        }
        .input:focus {
          outline: 2px solid #01696f;
          outline-offset: 1px;
        }
      `}</style>
    </div>
  );
}

function Field({
  label,
  hint,
  children,
}: {
  label: string;
  hint?: string;
  children: React.ReactNode;
}) {
  return (
    <label className="block">
      <div className="mb-1 flex items-baseline justify-between">
        <span className="text-sm font-medium text-text">{label}</span>
        {hint && <span className="text-xs text-textmuted">{hint}</span>}
      </div>
      {children}
    </label>
  );
}

function PaymentForm({
  amountCents,
  donationId,
  onError,
}: {
  amountCents: number;
  donationId: string;
  onError: (m: string) => void;
}) {
  const stripe = useStripe();
  const elements = useElements();
  const [submitting, setSubmitting] = useState(false);

  async function handleSubmit(e: React.FormEvent) {
    e.preventDefault();
    if (!stripe || !elements) return;
    setSubmitting(true);
    onError("");
    const { error } = await stripe.confirmPayment({
      elements,
      confirmParams: {
        return_url: `${window.location.origin}/donate/success?donation=${donationId}`,
      },
    });
    if (error) {
      onError(error.message ?? "Payment failed");
      setSubmitting(false);
    }
  }

  return (
    <form onSubmit={handleSubmit} className="space-y-4">
      <PaymentElement />
      <button
        type="submit"
        disabled={!stripe || submitting}
        className="w-full rounded-full bg-primary py-3 font-medium text-white hover:bg-primaryDark disabled:opacity-50"
      >
        {submitting ? "Processing…" : `Pay ${formatUSD(amountCents)}`}
      </button>
    </form>
  );
}
