// Copyright: (c) 2026 TWWIM UG. All rights reserved.
import { useEffect, useState } from 'react';
import { useNavigate, useSearch } from '@tanstack/react-router';
import { authenticatedUserStore } from '@/infrastructure/storage/AuthenticatedUserStore';
import { useForm } from 'react-hook-form';
import { zodResolver } from '@hookform/resolvers/zod';
import { z } from 'zod';
import { useMutation, useQueryClient } from '@tanstack/react-query';
import {
  Tag, CheckCircle2, AlertCircle, ArrowLeft, CreditCard,
  ShieldCheck, Lock, Sparkles, Receipt, Package,
} from 'lucide-react';
import { PageLayout } from '@/components/shared';
import { useTranslation } from '@/i18n/TranslationProvider';
import { useSubscription, useAvailablePlans } from '@/features/subscription/hooks/useSubscription';
import { useValidateCode } from './hooks/useValidateCode';
import { useApplyCheckoutCode } from './hooks/useApplyCheckoutCode';
import { PaymentPanel } from '@/features/subscription/components/PaymentPanel';
import { subscriptionApi } from '@/infrastructure/http/api/subscription';
import { membersApi } from '@/infrastructure/http/api/members/api';
import { queryKeys } from '@/lib/query-keys';
import type { ValidateCodeResponse } from '@archer/api-interface/schemas/customer-api/response';
import type { AvailablePlanResponse } from '@/infrastructure/http/api/subscription';
import { resolveCheckoutBreakdown, resolveCurrency } from './lib/checkoutBreakdown';
import { useAuthenticatedUser } from '@/features/auth/hooks/useAuthenticatedUser';

const codeSchema = z.object({
  code: z.string().min(3).max(30).regex(/^[A-Z0-9_-]+$/i, 'Code must be alphanumeric'),
});
type CodeForm = z.infer<typeof codeSchema>;

export function CheckoutPage() {
  const { t, locale } = useTranslation();
  const navigate = useNavigate();
  const search = useSearch({ strict: false }) as { planId?: string; txId?: string; commandSize?: number; commandQty?: number; seatEmail?: string; seatRole?: string; seatAmount?: number; seatCurrency?: string };
  const { data: subscription } = useSubscription();
  const { data: plans } = useAvailablePlans();
  const queryClient = useQueryClient();

  const validateCode = useValidateCode();
  const applyCode = useApplyCheckoutCode();

  // Defense-in-depth for deep-links, Back/Forward, and legacy Stripe redirects.
  // The plan-selection modal already blocks unready users from reaching here,
  // but the page is URL-addressable — anyone landing directly must bounce
  // back to /dashboard/subscription where ReadinessGateModal will open.
  // Pure client read, matches the subscription-page gate exactly.
  useEffect(() => {
    const account = authenticatedUserStore.get()?.account;
    if (!account || !account.isProfileComplete || !account.emailVerified) {
      navigate({ to: '/dashboard/subscription', replace: true });
    }
  // Run only on mount — the modal flow already prevents render-time arrival
  // in non-ready state; subsequent state flips to "not ready" mid-session
  // shouldn't kick users out of checkout (shouldn't happen anyway).
  // eslint-disable-next-line react-hooks/exhaustive-deps
  }, []);

  const [codePreview, setCodePreview] = useState<ValidateCodeResponse | null>(null);
  const [codeApplied, setCodeApplied] = useState(false);
  const [showPayment, setShowPayment] = useState(false);
  const [commandClientSecret, setCommandClientSecret] = useState<string | null>(null);
  const [commandTxId, setCommandTxId] = useState<string | null>(null);
  // Seat-purchase clientSecret is created on the Pay click and held in STATE —
  // never in the URL.
  const [seatClientSecret, setSeatClientSecret] = useState<string | null>(null);

  // ── Mode detection ──
  const isSeatMode = !!search.seatEmail;
  const isCommandMode = !!search.commandSize;
  const commandSize = (search.commandSize === 100 || search.commandSize === 1000) ? search.commandSize : null;
  const commandQuantity = (() => {
    const q = Number(search.commandQty ?? 1);
    if (!Number.isInteger(q) || q < 1 || q > 100) return 1;
    return q;
  })();
  const commandPackage = isCommandMode
    ? subscription?.commandPackages?.find((p: any) => p.size === commandSize)
    : null;

  const planId = search.planId ?? subscription?.pendingSubscription?.planId;
  const transactionId = search.txId;
  const plan = !isCommandMode ? plans?.find((p: AvailablePlanResponse) => p.id === planId) : null;
  const pendingTx = !isCommandMode ? subscription?.pendingTransaction : null;

  const { register, handleSubmit, formState: { errors } } = useForm<CodeForm>({
    resolver: zodResolver(codeSchema),
  });

  // ── Price calculation ──────────────────────────────────────────────
  // resolvedCurrency = user's preferredCurrency, falling back to the
  // API-returned plan/sub currency (post-fix already preferredCurrency-aware).
  // planNetMajor reads the per-currency cents from plan.prices map; falls
  // back to scalar plan.price (EUR-primary, derived) only when the map lacks
  // the resolved currency. Command packs already arrive in preferredCurrency
  // via GetSubscriptionUseCase (post-fix).
  const authed = useAuthenticatedUser();
  const preferredCurrency = authed?.preferredCurrency ?? undefined;
  const sourceCurrencyString = isSeatMode
    ? search.seatCurrency
    : isCommandMode
      ? subscription?.subscription?.plan?.currency
      : plan?.currency;
  const resolvedCurrency = preferredCurrency ?? resolveCurrency(sourceCurrencyString);

  const planNetMajor = (() => {
    if (!plan) return 0;
    const cents = plan.prices?.[resolvedCurrency];
    if (typeof cents === 'number') return Number((cents / 100).toFixed(2));
    return Number(plan.price);
  })();

  const originalAmount = isSeatMode
    ? Number(search.seatAmount ?? 0)
    : isCommandMode
      ? (commandPackage ? Number((commandPackage.price * commandQuantity).toFixed(2)) : 0)
      : planNetMajor;

  const existingDiscount = !isCommandMode && pendingTx && pendingTx.discountAmount > 0;
  const activeDiscount = codePreview?.valid
    ? { amount: codePreview.discountAmount, total: codePreview.discountedAmount, label: codePreview.campaignName?.[locale] ?? codePreview.campaignName?.['en'] ?? '', pct: codePreview.discountUnit === 'percentage' ? codePreview.discountValue : undefined }
    : existingDiscount
      ? { amount: pendingTx!.discountAmount, total: Number(pendingTx!.amount), label: (pendingTx!.appliedCampaigns?.[0] as any)?.name?.[locale] ?? (pendingTx!.appliedCampaigns?.[0] as any)?.name?.en ?? '' }
      : null;
  const netAmount = activeDiscount ? activeDiscount.total : originalAmount;
  // Currency + VAT mirror the backend: preferredCurrency wins, falls back to
  // the API-returned plan.currency / sub.plan.currency. Lookup-table VAT
  // (EUR 19%, USD 0%) matches Price.applyTax() in @archer/domain \u2014 so gross
  // displayed here is byte-identical to what Stripe will actually charge.
  const breakdown = resolveCheckoutBreakdown(netAmount, resolvedCurrency);
  const vatAmount = breakdown.vat;
  const grossAmount = breakdown.gross;
  const currency = breakdown.currencySymbol;

  // ── Command purchase mutation ──
  const purchaseCommandsMutation = useMutation({
    mutationFn: ({ size, quantity }: { size: 100 | 1000; quantity: number }) =>
      subscriptionApi.purchaseCommands(size, quantity),
    onSuccess: (data) => {
      setCommandClientSecret(data.clientSecret);
      setCommandTxId(data.transactionId);
      setShowPayment(true);
    },
  });

  // ── Seat purchase mutation — creates the PI on Pay click; clientSecret stays
  // in state (never the URL). On a free outcome the invite was created → /members.
  const seatInviteMutation = useMutation({
    mutationFn: () =>
      membersApi.seatInvite(authed?.companyId ?? '', {
        email: search.seatEmail ?? '',
        role: (search.seatRole ?? 'operator') as 'admin' | 'manager' | 'worker' | 'operator',
      }),
    onSuccess: (data) => {
      if (data.paid && data.clientSecret) {
        setSeatClientSecret(data.clientSecret);
        setShowPayment(true);
      } else {
        queryClient.invalidateQueries({ queryKey: queryKeys.companies.all });
        navigate({ to: '/dashboard/members' });
      }
    },
  });

  // ── Handlers ──
  const onValidate = (data: CodeForm) => {
    if (!planId) return;
    setCodePreview(null);
    setCodeApplied(false);
    validateCode.mutate({ code: data.code, planId }, {
      onSuccess: (res) => setCodePreview(res),
    });
  };

  const onApplyAndPay = () => {
    if (isSeatMode) {
      seatInviteMutation.mutate();
      return;
    }
    if (isCommandMode && commandSize) {
      purchaseCommandsMutation.mutate({ size: commandSize, quantity: commandQuantity });
      return;
    }

    if (codePreview?.valid && !codeApplied) {
      const code = (document.getElementById('checkout-code') as HTMLInputElement)?.value;
      if (code) {
        applyCode.mutate(code, {
          onSuccess: () => { setCodeApplied(true); setShowPayment(true); },
          onError: () => setShowPayment(true),
        });
        return;
      }
    }
    setShowPayment(true);
  };

  const onPaymentSuccess = () => {
    queryClient.invalidateQueries({ queryKey: queryKeys.subscription.all });
    navigate({ to: '/dashboard/subscription' });
  };

  // ── Item info ──
  const itemTitle = isSeatMode
    ? t('checkout.seat.title')
    : isCommandMode
      ? t('checkout.commandPackage', { count: commandSize ?? 0 })
      : (plan?.title?.[locale] ?? plan?.title?.en ?? plan?.slug ?? '');
  const itemDescription = isSeatMode
    ? `${t('checkout.seat.description')}${search.seatEmail ? ` — ${search.seatEmail}` : ''}`
    : isCommandMode
      ? t('checkout.commandDescription')
      : (plan?.displayConfig?.description?.[locale] ?? plan?.displayConfig?.description?.en ?? '');
  const billingLabel = (isCommandMode || isSeatMode) ? t('checkout.oneTime') : (plan?.billingCycle === 'monthly' ? t('checkout.month') : plan?.billingCycle ?? '');
  const ItemIcon = isCommandMode ? Package : Sparkles;

  // ── Validation ──
  if (!isCommandMode && !isSeatMode && !plan) {
    return (
      <PageLayout title={t('checkout.title')} subtitle="">
        <div className="text-center py-16 text-muted-foreground">{t('checkout.noPlan')}</div>
      </PageLayout>
    );
  }
  if (isCommandMode && !commandPackage) {
    return (
      <PageLayout title={t('checkout.title')} subtitle="">
        <div className="text-center py-16 text-muted-foreground">{t('checkout.noPackage')}</div>
      </PageLayout>
    );
  }

  const validateError = validateCode.error
    ? extractError(validateCode.error)
    : codePreview && !codePreview.valid ? codePreview.error : null;

  const isPaying = isSeatMode ? seatInviteMutation.isPending : isCommandMode ? purchaseCommandsMutation.isPending : applyCode.isPending;

  const onSeatPaymentSuccess = () => {
    queryClient.invalidateQueries({ queryKey: queryKeys.companies.all });
    navigate({ to: '/dashboard/members' });
  };

  // ── Payment overlay ──
  const paymentOverlay = showPayment ? (
    isSeatMode && seatClientSecret
      ? <PaymentPanel directClientSecret={seatClientSecret} displayAmount={grossAmount} onClose={() => setShowPayment(false)} onSuccess={onSeatPaymentSuccess} />
    : isCommandMode && commandClientSecret
      ? <PaymentPanel directClientSecret={commandClientSecret} displayAmount={grossAmount} onClose={() => setShowPayment(false)} onSuccess={onPaymentSuccess} />
      : transactionId
        ? <PaymentPanel transactionId={transactionId} onClose={() => setShowPayment(false)} onSuccess={onPaymentSuccess} />
        : plan
          ? <PaymentPanel plan={plan} onClose={() => setShowPayment(false)} onSuccess={onPaymentSuccess} />
          : undefined
  ) : undefined;

  return (
    <PageLayout
      title={t('checkout.title')}
      subtitle={t('checkout.subtitle')}
      icon={<Receipt size={24} />}
      gradient={true}
      overlay={paymentOverlay}
    >
      {/* Back navigation */}
      <button
        onClick={() => navigate({ to: '/dashboard/subscription' })}
        className="inline-flex items-center gap-1.5 text-sm text-muted-foreground hover:text-foreground transition-colors mb-2"
      >
        <ArrowLeft className="h-3.5 w-3.5" />
        {t('checkout.backToSubscription')}
      </button>

      <div className="grid lg:grid-cols-5 gap-6">
        {/* Left column: Order details (3/5) */}
        <div className="lg:col-span-3 space-y-5">

          {/* Item card */}
          <div className="bg-card rounded-xl border border-border shadow-sm overflow-hidden">
            <div className="px-6 py-4 bg-muted/30 border-b border-border">
              <h2 className="text-sm font-semibold text-foreground uppercase tracking-wider">
                {(isCommandMode || isSeatMode) ? t('checkout.package') : t('checkout.plan')}
              </h2>
            </div>
            <div className="p-6">
              <div className="flex items-start justify-between">
                <div className="flex items-center gap-3">
                  <div className="p-2.5 rounded-xl bg-primary/10">
                    <ItemIcon className="h-5 w-5 text-primary" />
                  </div>
                  <div>
                    <h3 className="text-lg font-bold text-foreground">{itemTitle}</h3>
                    <p className="text-sm text-muted-foreground mt-0.5">{itemDescription}</p>
                  </div>
                </div>
                <div className="text-right shrink-0 ml-4">
                  <span className="text-2xl font-bold text-foreground">{currency}{originalAmount}</span>
                  {billingLabel && <span className="text-sm text-muted-foreground">/{billingLabel}</span>}
                </div>
              </div>

              {/* Plan features preview (plan mode only) */}
              {!isCommandMode && !isSeatMode && plan?.features && plan.features.length > 0 && (
                <div className="mt-5 pt-4 border-t border-border">
                  <div className="grid grid-cols-2 gap-x-4 gap-y-1.5">
                    {plan.features
                      .slice()
                      .sort((a, b) => a.sortOrder - b.sortOrder)
                      .slice(0, 6)
                      .map((f, i) => (
                        <div key={i} className="flex items-center gap-2 text-sm text-muted-foreground">
                          <CheckCircle2 className="h-3.5 w-3.5 text-primary/60 shrink-0" />
                          <span className="truncate">{f.description?.[locale] ?? f.description?.en ?? ''}</span>
                        </div>
                      ))}
                  </div>
                </div>
              )}
            </div>
          </div>

          {/* Promo code card (plan mode only — command/seat purchases use existing campaign discounts automatically) */}
          {!isCommandMode && !isSeatMode && (
            <div className="bg-card rounded-xl border border-border shadow-sm overflow-hidden">
              <div className="px-6 py-4 bg-muted/30 border-b border-border">
                <h2 className="text-sm font-semibold text-foreground uppercase tracking-wider flex items-center gap-2">
                  <Tag className="h-4 w-4 text-primary" />
                  {t('checkout.codeLabel')}
                </h2>
              </div>
              <div className="p-6">
                <form onSubmit={handleSubmit(onValidate)}>
                  <div className="flex gap-2">
                    <input
                      id="checkout-code"
                      {...register('code')}
                      placeholder={t('checkout.codePlaceholder')}
                      disabled={validateCode.isPending || codeApplied}
                      className="flex-1 rounded-lg border border-input bg-background px-4 py-2.5 text-sm text-foreground placeholder:text-muted-foreground focus:outline-none focus:ring-2 focus:ring-primary/40 focus:border-primary uppercase tracking-wider disabled:opacity-50 transition-all"
                    />
                    <button
                      type="submit"
                      disabled={validateCode.isPending || codeApplied}
                      className="px-5 py-2.5 bg-muted text-foreground border border-border rounded-lg text-sm font-medium hover:bg-muted/80 disabled:opacity-50 transition-colors"
                    >
                      {validateCode.isPending ? '...' : t('checkout.validate')}
                    </button>
                  </div>
                  {errors.code && <p className="mt-2 text-xs text-destructive">{errors.code.message}</p>}
                </form>

                {validateError && (
                  <div className="mt-4 flex items-center gap-2.5 p-3 bg-destructive/5 border border-destructive/15 rounded-lg">
                    <AlertCircle className="h-4 w-4 text-destructive shrink-0" />
                    <p className="text-sm text-destructive">{t(`checkout.error.${validateError}`, undefined as any) || validateError}</p>
                  </div>
                )}

                {activeDiscount && (
                  <div className="mt-4 flex items-center justify-between p-3.5 bg-emerald-50 dark:bg-emerald-950/30 border border-emerald-200 dark:border-emerald-800/50 rounded-lg">
                    <div className="flex items-center gap-2.5">
                      <div className="p-1 rounded-full bg-emerald-100 dark:bg-emerald-900/50">
                        <CheckCircle2 className="h-4 w-4 text-emerald-600 dark:text-emerald-400" />
                      </div>
                      <div>
                        <p className="text-sm font-medium text-emerald-900 dark:text-emerald-100">{activeDiscount.label}</p>
                        {activeDiscount.pct && (
                          <p className="text-xs text-emerald-600 dark:text-emerald-400">{activeDiscount.pct}% {t('checkout.discount').toLowerCase()}</p>
                        )}
                      </div>
                    </div>
                    <span className="text-sm font-bold text-emerald-700 dark:text-emerald-300">
                      -{currency}{activeDiscount.amount.toFixed(2)}
                    </span>
                  </div>
                )}
              </div>
            </div>
          )}
        </div>

        {/* Right column: Summary + Pay (2/5) */}
        <div className="lg:col-span-2">
          <div className="bg-card rounded-xl border border-border shadow-sm overflow-hidden lg:sticky lg:top-6">
            <div className="px-6 py-4 bg-muted/30 border-b border-border">
              <h2 className="text-sm font-semibold text-foreground uppercase tracking-wider">{t('checkout.orderSummary')}</h2>
            </div>

            <div className="p-6 space-y-4">
              {/* Line items */}
              <div className="space-y-3">
                <div className="flex justify-between text-sm">
                  <span className="text-muted-foreground">{itemTitle}</span>
                  <span className="text-foreground font-medium">{currency}{originalAmount.toFixed(2)}</span>
                </div>

                {activeDiscount && (
                  <div className="flex justify-between text-sm text-emerald-600 dark:text-emerald-400">
                    <span>{activeDiscount.label}</span>
                    <span>-{currency}{activeDiscount.amount.toFixed(2)}</span>
                  </div>
                )}
              </div>

              <div className="border-t border-border" />

              {/* Net + VAT */}
              <div className="space-y-2">
                <div className="flex justify-between text-sm">
                  <span className="text-muted-foreground">{t('checkout.netAmount')}</span>
                  <span className="text-foreground">{currency}{netAmount.toFixed(2)}</span>
                </div>
                <div className="flex justify-between text-sm">
                  <span className="text-muted-foreground">{t('checkout.vat')}</span>
                  <span className="text-foreground">{currency}{vatAmount.toFixed(2)}</span>
                </div>
              </div>

              <div className="border-t border-border" />

              {/* Gross total */}
              <div className="flex justify-between items-baseline">
                <span className="text-base font-semibold text-foreground">{t('checkout.total')}</span>
                <div className="text-right">
                  <span className="text-2xl font-bold text-foreground">{currency}{grossAmount.toFixed(2)}</span>
                  {billingLabel && <p className="text-xs text-muted-foreground">/{billingLabel}</p>}
                </div>
              </div>

              {/* Pay button */}
              <button
                onClick={onApplyAndPay}
                data-testid="checkout-pay"
                disabled={isPaying}
                className="w-full flex items-center justify-center gap-2.5 bg-primary text-primary-foreground py-3.5 rounded-xl font-semibold text-sm hover:bg-primary/90 active:scale-[0.98] disabled:opacity-50 transition-all shadow-sm"
              >
                <Lock className="h-4 w-4" />
                {isPaying ? t('common.loading') : `${t('checkout.proceedToPayment')} ${currency}${grossAmount.toFixed(2)}`}
              </button>

              {/* Trust signals */}
              <div className="pt-2 space-y-2">
                <div className="flex items-center gap-2 text-xs text-muted-foreground">
                  <ShieldCheck className="h-3.5 w-3.5 shrink-0" />
                  <span>{t('checkout.securePayment')}</span>
                </div>
                <div className="flex items-center gap-2 text-xs text-muted-foreground">
                  <CreditCard className="h-3.5 w-3.5 shrink-0" />
                  <span>{t('checkout.stripeProcessed')}</span>
                </div>
              </div>
            </div>
          </div>
        </div>
      </div>
    </PageLayout>
  );
}

function extractError(error: unknown): string {
  const err = error as { response?: { data?: { error?: { message?: string } } } };
  return err?.response?.data?.error?.message ?? 'UNKNOWN_ERROR';
}
