'use client';

import { useEffect, useRef, useState } from 'react';
import { motion, AnimatePresence } from 'framer-motion';
import { loadStripe } from '@stripe/stripe-js';
import type { Stripe, StripeElements } from '@stripe/stripe-js';
import { Loader2, CheckCircle2, AlertTriangle, X } from 'lucide-react';

interface PaymentSetupFormProps {
  onSuccess: (paymentMethodId: string) => void;
  onCancel: () => void;
}

export default function CardSetupForm({ onSuccess, onCancel }: PaymentSetupFormProps) {
  const mountRef = useRef<HTMLDivElement>(null);
  const stripeRef = useRef<Stripe | null>(null);
  const elementsRef = useRef<StripeElements | null>(null);

  const [ready, setReady] = useState(false);
  const [submitting, setSubmitting] = useState(false);
  const [error, setError] = useState<string | null>(null);

  useEffect(() => {
    let cancelled = false;

    async function init() {
      const [configRes, intentRes] = await Promise.all([
        fetch('/api/billing/config'),
        fetch('/api/billing/setup-intent', { method: 'POST', credentials: 'include' }),
      ]);

      if (!configRes.ok || !intentRes.ok || cancelled) return;

      const [{ publishableKey }, { clientSecret }] = await Promise.all([
        configRes.json(),
        intentRes.json(),
      ]);

      const stripe = await loadStripe(publishableKey);
      if (!stripe || cancelled) return;
      stripeRef.current = stripe;

      const elements = stripe.elements({ clientSecret });
      elementsRef.current = elements;

      const paymentElement = elements.create('payment', {
        layout: {
          type: 'accordion',
          defaultCollapsed: false,
        },
        wallets: { applePay: 'auto', googlePay: 'auto' },
      });

      if (mountRef.current && !cancelled) {
        paymentElement.mount(mountRef.current);
        paymentElement.on('ready', () => { if (!cancelled) setReady(true); });
        paymentElement.on('change', (e) => {
          const err = 'error' in e ? (e as { error?: { message?: string } }).error : undefined;
          setError(err?.message ?? null);
        });
      }
    }

    init().catch((e) => setError(e?.message ?? 'Failed to load payment form'));

    return () => {
      cancelled = true;
    };
  }, []);

  const handleSubmit = async (e: React.FormEvent) => {
    e.preventDefault();
    if (!stripeRef.current || !elementsRef.current) return;

    setSubmitting(true);
    setError(null);

    const returnUrl = `${window.location.origin}${window.location.pathname}?billing_return=1`;

    const result = await stripeRef.current.confirmSetup({
      elements: elementsRef.current,
      confirmParams: { return_url: returnUrl },
      redirect: 'if_required',
    });

    if (result.error) {
      setError(result.error.message ?? 'Payment method setup failed');
      setSubmitting(false);
      return;
    }

    const pmId = result.setupIntent?.payment_method;
    if (typeof pmId !== 'string') {
      // Redirect-based method: page will reload on return and loadBilling() will refresh
      setSubmitting(false);
      return;
    }

    const attachRes = await fetch('/api/billing/payment-method', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      credentials: 'include',
      body: JSON.stringify({ paymentMethodId: pmId }),
    });

    if (!attachRes.ok) {
      const d = await attachRes.json();
      setError(d.error ?? 'Failed to save payment method');
      setSubmitting(false);
      return;
    }

    onSuccess(pmId);
  };

  return (
    <motion.div
      initial={{ opacity: 0, height: 0 }}
      animate={{ opacity: 1, height: 'auto' }}
      exit={{ opacity: 0, height: 0 }}
      className="overflow-hidden"
    >
      <form onSubmit={handleSubmit} className="glass-light rounded-xl p-5 space-y-4 mt-2">
        <div className="flex items-center justify-between">
          <p className="text-sm font-medium text-foreground">Add payment method</p>
          <button type="button" onClick={onCancel} className="text-muted hover:text-foreground cursor-pointer transition-colors">
            <X className="w-4 h-4" />
          </button>
        </div>

        <div>
          <div
            ref={mountRef}
            className="bg-surface rounded-lg px-3 py-3 border border-border focus-within:border-accent/40 transition-colors min-h-[44px]"
          />
          {!ready && (
            <div className="flex items-center gap-2 mt-2">
              <Loader2 className="w-3 h-3 animate-spin text-muted" />
              <span className="text-[11px] text-muted">Loading…</span>
            </div>
          )}
          {ready && (
            <p className="text-[10px] text-muted mt-2">
              Supported: card, Apple Pay, Google Pay, PayPal, SEPA Direct Debit, Link — availability depends on your Stripe account settings.
            </p>
          )}
        </div>

        <AnimatePresence>
          {error && (
            <motion.div
              initial={{ opacity: 0, height: 0 }}
              animate={{ opacity: 1, height: 'auto' }}
              exit={{ opacity: 0, height: 0 }}
              className="flex items-center gap-2 px-3 py-2 rounded-lg bg-danger/10 border border-danger/25 text-danger text-xs"
            >
              <AlertTriangle className="w-3.5 h-3.5 shrink-0" />
              {error}
            </motion.div>
          )}
        </AnimatePresence>

        <div className="flex items-center justify-between">
          <p className="text-[11px] text-muted flex items-center gap-1.5">
            <CheckCircle2 className="w-3.5 h-3.5 text-success shrink-0" />
            Secured by Stripe
          </p>
          <div className="flex gap-2">
            <button
              type="button"
              onClick={onCancel}
              className="px-4 py-2 rounded-lg border border-border text-sm text-muted hover:text-foreground hover:bg-surface-light transition-colors cursor-pointer"
            >
              Cancel
            </button>
            <button
              type="submit"
              disabled={!ready || submitting}
              className="px-4 py-2 rounded-lg gradient-accent text-white text-sm font-semibold hover:opacity-90 transition-opacity cursor-pointer disabled:opacity-50 flex items-center gap-2"
            >
              {submitting ? <Loader2 className="w-3.5 h-3.5 animate-spin" /> : null}
              {submitting ? 'Saving…' : 'Save'}
            </button>
          </div>
        </div>
      </form>
    </motion.div>
  );
}
