import React from 'react';
import { useNavigate, useLocation } from 'react-router-dom';
import { Receipt, ShieldCheck, ArrowRight, ArrowLeft, CreditCard, AlertTriangle, Loader2 } from 'lucide-react';
import {
  TenantWelcomeLayout,
  WelcomeStepCard,
  OnboardingCTAList,
  useOnboardingProgress,
} from '..';
import { Alert, AlertDescription, AlertTitle } from '@/components/ui/alert';
import { Badge } from '@/components/ui/badge';
import { Button } from '@/components/ui/button';
import { ADMIN_BILLING_PATH, ADMIN_WELCOME_EVENT_PATH, ADMIN_WELCOME_PACKAGES_PATH } from '../../constants';
import { useTenantPackages } from '../hooks/useTenantPackages';
import {
  assignFreeTenantPackage,
  completeTenantPackagePurchase,
  createTenantPackagePaymentIntent,
  createTenantPayPalOrder,
  captureTenantPayPalOrder,
} from '../../api';
import { Elements, PaymentElement, useElements, useStripe } from '@stripe/react-stripe-js';
import { loadStripe } from '@stripe/stripe-js';
import { PayPalScriptProvider, PayPalButtons } from '@paypal/react-paypal-js';

const stripePublishableKey = import.meta.env.VITE_STRIPE_PUBLISHABLE_KEY ?? '';
const paypalClientId = import.meta.env.VITE_PAYPAL_CLIENT_ID ?? '';
const stripePromise = stripePublishableKey ? loadStripe(stripePublishableKey) : null;

type StripeCheckoutProps = {
  clientSecret: string;
  packageId: number;
  onSuccess: () => void;
};

function StripeCheckoutForm({ clientSecret, packageId, onSuccess }: StripeCheckoutProps) {
  const stripe = useStripe();
  const elements = useElements();
  const [submitting, setSubmitting] = React.useState(false);
  const [error, setError] = React.useState<string | null>(null);

  const handleSubmit = async (event: React.FormEvent) => {
    event.preventDefault();
    if (!stripe || !elements) {
      setError('Zahlungsmodul noch nicht bereit. Bitte lade die Seite neu.');
      return;
    }

    setSubmitting(true);
    setError(null);

    const result = await stripe.confirmPayment({
      elements,
      confirmParams: {
        return_url: window.location.href,
      },
      redirect: 'if_required',
    });

    if (result.error) {
      setError(result.error.message ?? 'Zahlung fehlgeschlagen. Bitte erneut versuchen.');
      setSubmitting(false);
      return;
    }

    const paymentIntent = result.paymentIntent;
    const paymentMethodId =
      typeof paymentIntent?.payment_method === 'string'
        ? paymentIntent.payment_method
        : typeof paymentIntent?.id === 'string'
          ? paymentIntent.id
          : null;

    if (!paymentMethodId) {
      setError('Zahlung konnte nicht bestätigt werden (fehlende Zahlungs-ID).');
      setSubmitting(false);
      return;
    }

    try {
      await completeTenantPackagePurchase({
        packageId,
        paymentMethodId,
      });
      onSuccess();
    } catch (purchaseError) {
      console.error('[Onboarding] Purchase completion failed', purchaseError);
      setError(
        purchaseError instanceof Error
          ? purchaseError.message
          : 'Der Kauf wurde bei uns noch nicht verbucht. Bitte kontaktiere den Support mit deiner Zahlungsbestätigung.'
      );
      setSubmitting(false);
    }
  };

  return (
    <form onSubmit={handleSubmit} className="space-y-6 rounded-2xl border border-brand-rose-soft bg-brand-card p-6 shadow-brand-primary">
      <div className="space-y-3">
        <p className="text-sm font-medium text-brand-slate">Kartenzahlung</p>
        <PaymentElement id="payment-element" />
      </div>
      {error && (
        <Alert variant="destructive">
          <AlertTitle>Zahlung fehlgeschlagen</AlertTitle>
          <AlertDescription>{error}</AlertDescription>
        </Alert>
      )}
      <Button
        type="submit"
        disabled={submitting || !stripe || !elements}
        className="w-full rounded-full bg-brand-rose text-white shadow-lg shadow-rose-400/40 hover:bg-[var(--brand-rose-strong)] disabled:opacity-60"
      >
        {submitting ? (
          <>
            <Loader2 className="mr-2 size-4 animate-spin" />
            Zahlung wird bestätigt ...
          </>
        ) : (
          <>
            <CreditCard className="mr-2 size-4" />
            Jetzt bezahlen
          </>
        )}
      </Button>
      <p className="text-xs text-brand-navy/70">
        Sicherer Checkout über Stripe. Du erhältst eine Bestätigung, sobald der Kauf verbucht wurde.
      </p>
      <input type="hidden" value={clientSecret} />
    </form>
  );
}

type PayPalCheckoutProps = {
  packageId: number;
  onSuccess: () => void;
  currency?: string;
};

function PayPalCheckout({ packageId, onSuccess, currency = 'EUR' }: PayPalCheckoutProps) {
  const [status, setStatus] = React.useState<'idle' | 'creating' | 'capturing' | 'error' | 'success'>('idle');
  const [error, setError] = React.useState<string | null>(null);

  const handleCreateOrder = React.useCallback(async () => {
    try {
      setStatus('creating');
      const orderId = await createTenantPayPalOrder(packageId);
      setStatus('idle');
      setError(null);
      return orderId;
    } catch (err) {
      console.error('[Onboarding] PayPal create order failed', err);
      setStatus('error');
      setError(
        err instanceof Error
          ? err.message
          : 'PayPal-Bestellung konnte nicht erstellt werden. Bitte versuche es erneut.'
      );
      throw err;
    }
  }, [packageId]);

  const handleApprove = React.useCallback(
    async (orderId: string) => {
      try {
        setStatus('capturing');
        await captureTenantPayPalOrder(orderId);
        setStatus('success');
        setError(null);
        onSuccess();
      } catch (err) {
        console.error('[Onboarding] PayPal capture failed', err);
        setStatus('error');
        setError(
          err instanceof Error
            ? err.message
            : 'PayPal-Zahlung konnte nicht abgeschlossen werden. Bitte kontaktiere den Support, falls der Betrag bereits abgebucht wurde.'
        );
        throw err;
      }
    },
    [onSuccess]
  );

  return (
    <div className="space-y-3 rounded-2xl border border-brand-rose-soft bg-white/85 p-6 shadow-inner">
      <p className="text-sm font-medium text-brand-slate">PayPal</p>
      {error && (
        <Alert variant="destructive">
          <AlertTitle>PayPal-Fehler</AlertTitle>
          <AlertDescription>{error}</AlertDescription>
        </Alert>
      )}
      <PayPalButtons
        style={{ layout: 'vertical' }}
        forceReRender={[packageId, currency]}
        createOrder={async () => handleCreateOrder()}
        onApprove={async (data) => {
          if (!data.orderID) {
            setError('PayPal hat keine Order-ID geliefert.');
            setStatus('error');
            return;
          }
          await handleApprove(data.orderID);
        }}
        onError={(err) => {
          console.error('[Onboarding] PayPal onError', err);
          setStatus('error');
          setError('PayPal hat ein Problem gemeldet. Bitte versuche es in wenigen Minuten erneut.');
        }}
        onCancel={() => {
          setStatus('idle');
          setError('PayPal-Zahlung wurde abgebrochen.');
        }}
        disabled={status === 'creating' || status === 'capturing'}
      />
      <p className="text-xs text-brand-navy/70">
        PayPal leitet dich ggf. kurz weiter, um die Zahlung zu bestätigen. Anschließend wirst du automatisch zum Setup
        zurückgebracht.
      </p>
    </div>
  );
}

export default function WelcomeOrderSummaryPage() {
  const navigate = useNavigate();
  const location = useLocation();
  const { progress, markStep } = useOnboardingProgress();
  const packagesState = useTenantPackages();

  const packageIdFromState = typeof location.state === 'object' ? (location.state as any)?.packageId : undefined;
  const selectedPackageId = progress.selectedPackage?.id ?? packageIdFromState ?? null;

  React.useEffect(() => {
    if (!selectedPackageId && packagesState.status !== 'loading') {
      navigate(ADMIN_WELCOME_PACKAGES_PATH, { replace: true });
    }
  }, [selectedPackageId, packagesState.status, navigate]);

  React.useEffect(() => {
    markStep({ lastStep: 'summary' });
  }, [markStep]);

  const packageDetails =
    packagesState.status === 'success' && selectedPackageId
      ? packagesState.catalog.find((pkg) => pkg.id === selectedPackageId)
      : null;

  const activePackage =
    packagesState.status === 'success'
      ? packagesState.purchasedPackages.find((pkg) => pkg.package_id === selectedPackageId)
      : null;

  const isSubscription = Boolean(packageDetails?.features?.subscription);
  const requiresPayment = Boolean(packageDetails && packageDetails.price > 0);

  const [clientSecret, setClientSecret] = React.useState<string | null>(null);
  const [intentStatus, setIntentStatus] = React.useState<'idle' | 'loading' | 'error' | 'ready'>('idle');
  const [intentError, setIntentError] = React.useState<string | null>(null);
  const [freeAssignStatus, setFreeAssignStatus] = React.useState<'idle' | 'loading' | 'success' | 'error'>('idle');
  const [freeAssignError, setFreeAssignError] = React.useState<string | null>(null);

  React.useEffect(() => {
    if (!requiresPayment || !packageDetails) {
      setClientSecret(null);
      setIntentStatus('idle');
      setIntentError(null);
      return;
    }

    if (!stripePromise) {
      setIntentError('Stripe Publishable Key fehlt. Bitte konfiguriere VITE_STRIPE_PUBLISHABLE_KEY.');
      setIntentStatus('error');
      return;
    }

    let cancelled = false;
    setIntentStatus('loading');
    setIntentError(null);
    createTenantPackagePaymentIntent(packageDetails.id)
      .then((secret) => {
        if (cancelled) return;
        setClientSecret(secret);
        setIntentStatus('ready');
      })
      .catch((error) => {
        console.error('[Onboarding] Failed to create payment intent', error);
        if (cancelled) return;
        setIntentError(
          error instanceof Error
            ? error.message
            : 'PaymentIntent konnte nicht erstellt werden. Bitte später erneut versuchen.'
        );
        setIntentStatus('error');
      });

    return () => {
      cancelled = true;
    };
  }, [requiresPayment, packageDetails?.id]);

  const priceText =
    progress.selectedPackage?.priceText ??
    (packageDetails && typeof packageDetails.price === 'number'
      ? new Intl.NumberFormat('de-DE', {
          style: 'currency',
          currency: 'EUR',
          minimumFractionDigits: 0,
        }).format(packageDetails.price)
      : null);

  return (
    <TenantWelcomeLayout
      eyebrow="Schritt 3"
      title="Bestellübersicht"
      subtitle="Prüfe Paket, Preis und Abrechnung bevor du zum Event-Setup wechselst."
      footer={
        <button
          type="button"
          className="inline-flex items-center gap-2 text-sm font-medium text-brand-rose hover:text-rose-600"
          onClick={() => navigate(ADMIN_WELCOME_PACKAGES_PATH)}
        >
          <ArrowLeft className="size-4" />
          Zurück zur Paketauswahl
        </button>
      }
    >
      <WelcomeStepCard
        step={3}
        totalSteps={4}
        title="Deine Auswahl im Überblick"
        description="Du kannst sofort an die Abrechnung übergeben oder das Setup fortsetzen und später bezahlen."
        icon={Receipt}
      >
        {packagesState.status === 'loading' && (
          <div className="flex items-center gap-3 rounded-2xl bg-slate-50 p-6 text-sm text-brand-navy/80">
            <CreditCard className="size-5 text-brand-rose" />
            Wir prüfen verfügbare Pakete …
          </div>
        )}

        {packagesState.status === 'error' && (
          <Alert variant="destructive">
            <AlertTriangle className="size-4" />
            <AlertTitle>Paketdaten derzeit nicht verfügbar</AlertTitle>
            <AlertDescription>
              {packagesState.message} Du kannst das Event trotzdem vorbereiten und später zurückkehren.
            </AlertDescription>
          </Alert>
        )}

        {packagesState.status === 'success' && !packageDetails && (
          <Alert>
            <AlertTitle>Keine Paketauswahl gefunden</AlertTitle>
            <AlertDescription>
              Bitte wähle zuerst ein Paket aus oder aktualisiere die Seite, falls sich die Daten geändert haben.
            </AlertDescription>
          </Alert>
        )}

        {packagesState.status === 'success' && packageDetails && (
          <div className="grid gap-4">
            <div className="rounded-3xl border border-brand-rose-soft bg-brand-card p-6 shadow-md shadow-rose-100/40">
              <div className="flex flex-col gap-3 md:flex-row md:items-center md:justify-between">
                <div>
                  <p className="text-xs uppercase tracking-[0.35em] text-brand-rose">
                    {isSubscription ? 'Abo' : 'Credit-Paket'}
                  </p>
                  <h3 className="text-2xl font-semibold text-brand-slate">{packageDetails.name}</h3>
                </div>
                {priceText && (
                  <Badge className="rounded-full bg-rose-100 px-4 py-2 text-base font-semibold text-rose-600">
                    {priceText}
                  </Badge>
                )}
              </div>
              <dl className="mt-6 grid gap-3 text-sm text-brand-navy/80 md:grid-cols-2">
                <div>
                  <dt className="font-semibold text-brand-slate">Fotos & Galerie</dt>
                  <dd>
                    {packageDetails.max_photos
                      ? `Bis zu ${packageDetails.max_photos} Fotos, Galerie ${packageDetails.gallery_days ?? '∞'} Tage`
                      : 'Unbegrenzte Fotos, flexible Galerie'}
                  </dd>
                </div>
                <div>
                  <dt className="font-semibold text-brand-slate">Gäste & Team</dt>
                  <dd>
                    {packageDetails.max_guests
                      ? `${packageDetails.max_guests} Gäste inklusive, Co-Hosts frei planbar`
                      : 'Unbegrenzte Gästeliste'}
                  </dd>
                </div>
                <div>
                  <dt className="font-semibold text-brand-slate">Highlights</dt>
                  <dd>
                    {Object.entries(packageDetails.features ?? {})
                      .filter(([, enabled]) => enabled)
                      .map(([feature]) => feature.replace(/_/g, ' '))
                      .join(', ') || 'Standard'}
                  </dd>
                </div>
                <div>
                  <dt className="font-semibold text-brand-slate">Status</dt>
                  <dd>{activePackage ? 'Bereits gebucht' : 'Noch nicht gebucht'}</dd>
                </div>
              </dl>
            </div>

            {!activePackage && (
              <Alert className="rounded-2xl border-brand-rose-soft bg-brand-rose-soft/60 text-rose-700">
                <ShieldCheck className="size-4" />
                <AlertTitle>Abrechnung steht noch aus</AlertTitle>
                <AlertDescription>
                  Du kannst das Event bereits vorbereiten. Spätestens zur Veröffentlichung benötigst du ein aktives Paket.
                </AlertDescription>
              </Alert>
            )}

            {packageDetails.price === 0 && (
              <div className="rounded-2xl border border-emerald-200 bg-emerald-50/40 p-6">
                <p className="text-sm text-emerald-700">
                  Dieses Paket ist kostenlos. Du kannst es sofort deinem Tenant zuweisen und direkt mit dem Setup
                  weitermachen.
                </p>
                {freeAssignStatus === 'success' ? (
                  <Alert className="mt-4 border-emerald-200 bg-white text-emerald-600">
                    <AlertTitle>Gratis-Paket aktiviert</AlertTitle>
                    <AlertDescription>
                      Deine Credits wurden hinzugefügt. Weiter geht&apos;s mit dem Event-Setup.
                    </AlertDescription>
                  </Alert>
                ) : (
                  <Button
                    onClick={async () => {
                      if (!packageDetails) {
                        return;
                      }
                      setFreeAssignStatus('loading');
                      setFreeAssignError(null);
                      try {
                        await assignFreeTenantPackage(packageDetails.id);
                        setFreeAssignStatus('success');
                        markStep({ packageSelected: true });
                        navigate(ADMIN_WELCOME_EVENT_PATH, { replace: true });
                      } catch (error) {
                        console.error('[Onboarding] Free package assignment failed', error);
                        setFreeAssignStatus('error');
                        setFreeAssignError(
                          error instanceof Error ? error.message : 'Kostenloses Paket konnte nicht aktiviert werden.'
                        );
                      }
                    }}
                    disabled={freeAssignStatus === 'loading'}
                    className="mt-4 rounded-full bg-brand-teal text-white shadow-md shadow-emerald-300/40 hover:opacity-90"
                  >
                    {freeAssignStatus === 'loading' ? (
                      <>
                        <Loader2 className="mr-2 size-4 animate-spin" />
                        Aktivierung läuft ...
                      </>
                    ) : (
                      'Gratis-Paket aktivieren'
                    )}
                  </Button>
                )}
                {freeAssignStatus === 'error' && freeAssignError && (
                  <Alert variant="destructive" className="mt-3">
                    <AlertTitle>Aktivierung fehlgeschlagen</AlertTitle>
                    <AlertDescription>{freeAssignError}</AlertDescription>
                  </Alert>
                )}
              </div>
            )}

            {requiresPayment && (
              <div className="space-y-6">
                <div className="space-y-4">
                  <h4 className="text-lg font-semibold text-brand-slate">Kartenzahlung (Stripe)</h4>
                  {intentStatus === 'loading' && (
                    <div className="flex items-center gap-3 rounded-2xl border border-brand-rose-soft bg-brand-card p-6 text-sm text-brand-navy/80">
                      <Loader2 className="size-4 animate-spin text-brand-rose" />
                      Zahlungsdetails werden geladen …
                    </div>
                  )}
                  {intentStatus === 'error' && (
                    <Alert variant="destructive">
                      <AlertTitle>Stripe nicht verfügbar</AlertTitle>
                      <AlertDescription>{intentError}</AlertDescription>
                    </Alert>
                  )}
                  {intentStatus === 'ready' && clientSecret && stripePromise && (
                    <Elements stripe={stripePromise} options={{ clientSecret }}>
                      <StripeCheckoutForm
                        clientSecret={clientSecret}
                        packageId={packageDetails.id}
                        onSuccess={() => {
                          markStep({ packageSelected: true });
                          navigate(ADMIN_WELCOME_EVENT_PATH, { replace: true });
                        }}
                      />
                    </Elements>
                  )}
                </div>

                {paypalClientId ? (
                  <div className="space-y-4">
                    <h4 className="text-lg font-semibold text-brand-slate">PayPal</h4>
                    <PayPalScriptProvider
                      options={{ 'client-id': paypalClientId, currency: 'EUR', intent: 'CAPTURE' }}
                    >
                      <PayPalCheckout
                        packageId={packageDetails.id}
                        onSuccess={() => {
                          markStep({ packageSelected: true });
                          navigate(ADMIN_WELCOME_EVENT_PATH, { replace: true });
                        }}
                      />
                    </PayPalScriptProvider>
                  </div>
                ) : (
                  <Alert variant="default" className="border-amber-200 bg-amber-50 text-amber-700">
                    <AlertTitle>PayPal nicht konfiguriert</AlertTitle>
                    <AlertDescription>
                      Hinterlege `VITE_PAYPAL_CLIENT_ID`, damit Gastgeber optional mit PayPal bezahlen können.
                    </AlertDescription>
                  </Alert>
                )}
              </div>
            )}

            <div className="flex flex-col gap-3 rounded-2xl bg-brand-card p-6 shadow-inner shadow-rose-100/40">
              <h4 className="text-lg font-semibold text-brand-slate">Nächste Schritte</h4>
              <ol className="list-decimal space-y-2 pl-5 text-sm text-brand-navy/80">
                <li>Optional: Abrechnung abschließen (Stripe/PayPal) im Billing-Bereich.</li>
                <li>Event-Setup durchlaufen und Aufgaben, Team & Galerie konfigurieren.</li>
                <li>Vor dem Go-Live Credits prüfen und Gäste-Link teilen.</li>
              </ol>
            </div>
          </div>
        )}
      </WelcomeStepCard>

      <OnboardingCTAList
        actions={[
          {
            id: 'checkout',
            label: 'Abrechnung starten',
            description: 'Öffnet den Billing-Bereich mit allen Kaufoptionen (Stripe, PayPal, Credits).',
            buttonLabel: 'Zu Billing & Zahlung',
            href: ADMIN_BILLING_PATH,
            icon: CreditCard,
            variant: 'secondary',
          },
          {
            id: 'continue-to-setup',
            label: 'Mit Event-Setup fortfahren',
            description: 'Du kannst später jederzeit zur Abrechnung zurückkehren.',
            buttonLabel: 'Weiter zum Setup',
            onClick: () => {
              markStep({ lastStep: 'event-setup' });
              navigate(ADMIN_WELCOME_EVENT_PATH);
            },
            icon: ArrowRight,
          },
        ]}
      />
    </TenantWelcomeLayout>
  );
}









