import { useState, useCallback } from 'react';
import { CreditCard, XCircle, ArrowUpRight, AlertTriangle, ShoppingCart } from 'lucide-react';
import { useNavigate } from '@tanstack/react-router';
import { PageLayout } from '@/components/shared';
import { useSubscription, useAvailablePlans, useInvoices } from './hooks';
import { useCancelSubscription, useResumeSubscription } from './hooks';
import { UsageBar } from './components/UsageBar';
import { InvoiceList } from './components/InvoiceList';
import { ActiveCampaignList } from './components/ActiveCampaignList';
import { PendingPaymentBanner } from './components/PendingPaymentBanner';
import { PaymentPanel } from './components/PaymentPanel';
import { CommandPurchasePanel } from './components/CommandPurchasePanel';
import { ConfiguratorPanel } from './components/ConfiguratorPanel';
import { PlanSelectionModal } from './components/PlanSelectionModal';
import { ReadinessGateModal } from './components/ReadinessGateModal';
import { LUCIDE_ICON_MAP } from '@archer/ui/utils';
import type { AvailablePlanResponse } from '@/infrastructure/http/api/subscription';
import { useSetAutoBuy, useReadinessGate } from './hooks';
import type { MappedPricingPlan } from '@archer/ui/utils';
import { useTranslation } from '@/i18n/TranslationProvider';
import { useAuthenticatedUser } from '@/features/auth/hooks/useAuthenticatedUser';
import { formatPlanPrice } from '@/features/checkout/lib/checkoutBreakdown';

export function SubscriptionPage() {
  const { t, locale } = useTranslation();
  const navigate = useNavigate();
  // Billing currency is sourced from the global AuthenticatedUser snapshot —
  // seeded at login, patched by the company-update mutation. Avoids a
  // dedicated /companies/:id fetch purely for currency display.
  const authed = useAuthenticatedUser();
  const readinessGate = useReadinessGate();
  const preferredCurrency = authed?.preferredCurrency ?? null;
  const [invoicePage, setInvoicePage] = useState(1);
  const { data, isLoading, error } = useSubscription();
  const { data: plans, isLoading: plansLoading } = useAvailablePlans();
  const { data: invoicesData, isLoading: invoicesLoading } = useInvoices(invoicePage);
  const cancelMutation = useCancelSubscription();
  const resumeMutation = useResumeSubscription();

  const autoBuyMutation = useSetAutoBuy();

  const [showCancelConfirm, setShowCancelConfirm] = useState(false);
  const [selectedPlan, setSelectedPlan] = useState<AvailablePlanResponse | null>(null);
  const [showPlansModal, setShowPlansModal] = useState(false);
  const [showReadinessModal, setShowReadinessModal] = useState(false);
  const [showPurchasePanel, setShowPurchasePanel] = useState(false);
  const [showConfigurator, setShowConfigurator] = useState(false);
  const [pendingTransactionId, setPendingTransactionId] = useState<string | null>(null);

  const subscription = data?.subscription;
  const quota = data?.quota;
  const pending = data?.pendingSubscription;
  const autoBuyCommands = data?.autoBuyCommands ?? false;
  const commandPackages = data?.commandPackages ?? [];
  const activeCampaigns = data?.activeCampaigns ?? [];
  const quotaBreakdown = data?.quotaBreakdown;

  const currentPlanId = subscription?.planId;
  const hasStripeSubscription = !!subscription?.paymentProvider && subscription.paymentProvider === 'stripe';

  const handleCancel = () => {
    cancelMutation.mutate(undefined, {
      onSuccess: () => setShowCancelConfirm(false),
    });
  };

  const handleSelectPlan = (plan: AvailablePlanResponse) => {
    if (plan.id === currentPlanId) return;

    // Switching to free plan → cancel current Stripe subscription (takes effect at period end)
    if (plan.price === 0 && hasStripeSubscription) {
      setShowPlansModal(false);
      cancelMutation.mutate();
      return;
    }

    // Paid plan requires a fully-provisioned account: billing profile filled
    // AND email confirmed. Both flags live on AuthenticatedUser.account and
    // are patched immediately after the relevant mutation, so this gate is a
    // pure client read — no network call at decision time. Surface a modal
    // with the recovery affordances instead of teleporting the user away:
    // they keep the plan-selection context and can resolve from one place.
    // Server-side 409 (PROFILE_INCOMPLETE / EMAIL_NOT_VERIFIED) remains
    // defense-in-depth for tampered clients.
    readinessGate.attempt(
      () => {
        // Paid plan (new or switch): always route through checkout. The old
        // plan stays active until the new plan's payment succeeds; the
        // webhook then cancels the superseded Stripe sub and flips local state.
        setShowPlansModal(false);
        navigate({ to: '/dashboard/checkout', search: { planId: plan.id } });
      },
      () => {
        setShowPlansModal(false);
        setShowReadinessModal(true);
      },
    );
  };

  const handleCardAction = (mapped: MappedPricingPlan) => {
    const plan = plans?.find((p) => p.slug === mapped.slug);
    if (plan) {
      handleSelectPlan(plan);
      setShowPlansModal(false);
    }
  };

  const handlePaymentSuccess = useCallback(() => {
    setSelectedPlan(null);
  }, []);

  const handlePanelClose = useCallback(() => {
    setSelectedPlan(null);
  }, []);

  const handleCompletePending = (transactionId: string) => {
    // Same readiness gate as handleSelectPlan — silently failing to pay
    // a pending tx because the profile is incomplete was the bug. Both
    // paths funnel through useReadinessGate so the modal copy and the
    // missing-fields list stay in one place.
    readinessGate.attempt(
      () => {
        const pendingPlanId = pending?.planId;
        navigate({
          to: '/dashboard/checkout',
          search: { planId: pendingPlanId, txId: transactionId },
        });
      },
      () => setShowReadinessModal(true),
    );
  };

  // Resolve current plan data from plans list
  const currentPlanData = plans?.find((p) => p.id === currentPlanId);
  const iconKey = currentPlanData?.displayConfig?.icon;
  const PlanIcon = iconKey ? (LUCIDE_ICON_MAP[iconKey] ?? CreditCard) : CreditCard;

  const currentPlanFeatures = (currentPlanData?.features ?? [])
    .slice()
    .sort((a, b) => a.sortOrder - b.sortOrder)
    .map((f) => ({
      text: f.description?.[locale] ?? f.capability?.name?.[locale] ?? '',
      included: f.enabled,
    }))
    .filter((f) => f.text);

  const overlayContent = (
    <>
      {showPlansModal && plans && authed && (
        <PlanSelectionModal
          plans={plans}
          currentPlanId={currentPlanId}
          pendingPlanId={pending?.planId}
          preferredCurrency={preferredCurrency}
          onSelect={handleCardAction}
          onClose={() => setShowPlansModal(false)}
        />
      )}
      {showReadinessModal && (
        <ReadinessGateModal onClose={() => setShowReadinessModal(false)} />
      )}
      {selectedPlan && (
        <PaymentPanel
          plan={selectedPlan}
          onClose={handlePanelClose}
          onSuccess={handlePaymentSuccess}
        />
      )}
      {pendingTransactionId && (
        <PaymentPanel
          transactionId={pendingTransactionId}
          onClose={() => setPendingTransactionId(null)}
          onSuccess={() => { setPendingTransactionId(null); handlePaymentSuccess(); }}
        />
      )}
      {showPurchasePanel && commandPackages.length > 0 && (
        <CommandPurchasePanel
          packages={commandPackages}
          currency={subscription?.plan?.currency ?? 'EUR'}
          onClose={() => setShowPurchasePanel(false)}
          onSuccess={() => setShowPurchasePanel(false)}
        />
      )}
      {showConfigurator && (
        <ConfiguratorPanel onClose={() => setShowConfigurator(false)} />
      )}
    </>
  );

  return (
    <PageLayout
      title={t('subscription.title')}
      subtitle={t('subscription.subtitle')}
      icon={<CreditCard size={24} />}
      gradient={true}
      overlay={overlayContent}
    >
        {error && (
          <div className="bg-destructive/10 border border-destructive/20 rounded-lg p-4">
            <p className="text-sm text-destructive">{t('subscription.errorLoading', { error: (error as Error).message })}</p>
          </div>
        )}

        {/* Pending Payment Banner */}
        {pending && pending.plan && (
          <PendingPaymentBanner planName={pending.plan.name} variant="subscription" />
        )}

        {/* Cancellation Notice */}
        {subscription?.cancelAtPeriodEnd && (
          <div className="bg-yellow-50 border border-yellow-200 rounded-lg p-4 flex items-start gap-3">
            <AlertTriangle className="h-5 w-5 text-yellow-600 mt-0.5 shrink-0" />
            <div className="flex-1">
              <p className="text-sm font-medium text-yellow-800">
                {t('subscription.cancelNotice', { date: new Date(subscription.currentPeriodEnd).toLocaleDateString(locale) })}
              </p>
              <p className="text-sm text-yellow-700 mt-0.5">
                {t('subscription.cancelNoticeDetail')}
              </p>
            </div>
            <button
              onClick={() => resumeMutation.mutate()}
              disabled={resumeMutation.isPending}
              className="shrink-0 text-sm font-medium text-yellow-800 hover:text-yellow-900 bg-yellow-200 hover:bg-yellow-300 px-3 py-1.5 rounded-md transition-colors"
            >
              {resumeMutation.isPending ? t('subscription.resuming') : t('subscription.continueSubscription')}
            </button>
          </div>
        )}

        {/* Section 1: Current Plan */}
        <div className="bg-card rounded-xl border border-border p-6 shadow-sm">
          <div className="flex items-center justify-between mb-4">
            <div className="flex items-center gap-3">
              <div className="p-2 rounded-lg bg-primary/10">
                <PlanIcon className="h-5 w-5 text-primary" />
              </div>
              <h2 className="text-lg font-semibold text-foreground">{t('subscription.currentPlan')}</h2>
            </div>
            <button
              onClick={() => setShowPlansModal(true)}
              className="flex items-center gap-1 text-sm font-medium text-primary hover:text-primary/80 transition-colors"
            >
              {t('subscription.changePlan')} <ArrowUpRight className="h-4 w-4" />
            </button>
          </div>

          {isLoading ? (
            <div className="space-y-3">
              <div className="h-8 bg-muted animate-pulse rounded w-48" />
              <div className="h-4 bg-muted animate-pulse rounded w-64" />
            </div>
          ) : subscription ? (
            <div className="space-y-4">
              <div className="flex items-center gap-3">
                <h3 className="text-2xl font-bold text-foreground">{subscription.plan.name}</h3>
                <span className={`text-xs font-medium px-2.5 py-1 rounded-full ${
                  subscription.status === 'active'
                    ? 'bg-green-100 text-green-700'
                    : subscription.status === 'pending_payment'
                      ? 'bg-yellow-100 text-yellow-700'
                      : 'bg-gray-100 text-gray-700'
                }`}>
                  {subscription.status.replace('_', ' ')}
                </span>
              </div>

              <div className="grid grid-cols-2 sm:grid-cols-4 gap-4 text-sm">
                <div>
                  <p className="text-muted-foreground">{t('subscription.price')}</p>
                  <p className="font-medium text-foreground">
                    {subscription.plan.monthlyPrice === 0
                      ? t('common.free')
                      : `${formatPlanPrice(subscription.plan.monthlyPrice, subscription.plan.currency)}${t('subscription.perMonth')}`}
                  </p>
                </div>
                <div>
                  <p className="text-muted-foreground">{t('subscription.billingCycle')}</p>
                  <p className="font-medium text-foreground capitalize">
                    {currentPlanData?.billingCycle || 'monthly'}
                  </p>
                </div>
                <div>
                  <p className="text-muted-foreground">{t('subscription.currentPeriod')}</p>
                  <p className="font-medium text-foreground">
                    {new Date(subscription.currentPeriodStart).toLocaleDateString(locale)} — {new Date(subscription.currentPeriodEnd).toLocaleDateString(locale)}
                  </p>
                </div>
                <div>
                  <p className="text-muted-foreground">{t('subscription.renewal')}</p>
                  <p className="font-medium text-foreground">
                    {subscription.cancelAtPeriodEnd ? t('subscription.cancelsAtPeriodEnd') : t('common.active')}
                  </p>
                </div>
              </div>

              {/* Plan Features */}
              {currentPlanFeatures.length > 0 && (
                <div className="pt-2 border-t border-border">
                  <p className="text-sm text-muted-foreground mb-2">{t('subscription.planFeatures')}</p>
                  <div className="grid grid-cols-1 sm:grid-cols-2 gap-x-6 gap-y-1">
                    {currentPlanFeatures.map((f, i) => (
                      <div key={i} className="flex items-center gap-2 text-sm">
                        <div className={`w-1.5 h-1.5 rounded-full ${f.included ? 'bg-green-500' : 'bg-gray-300'}`} />
                        <span className={f.included ? 'text-foreground' : 'text-muted-foreground line-through'}>
                          {f.text}
                        </span>
                      </div>
                    ))}
                  </div>
                </div>
              )}

              {/* Active Campaigns */}
              {activeCampaigns.length > 0 && (
                <ActiveCampaignList campaigns={activeCampaigns} />
              )}

              {/* Cancel button */}
              {subscription.plan.slug !== 'free' && !subscription.cancelAtPeriodEnd && (
                <div className="pt-2">
                  {showCancelConfirm ? (
                    <div className="flex items-center gap-3">
                      <p className="text-sm text-muted-foreground">{t('subscription.cancelConfirm')}</p>
                      <button
                        onClick={handleCancel}
                        disabled={cancelMutation.isPending}
                        className="text-sm font-medium text-destructive hover:text-destructive/80"
                      >
                        {cancelMutation.isPending ? t('subscription.cancelling') : t('subscription.yesCancel')}
                      </button>
                      <button
                        onClick={() => setShowCancelConfirm(false)}
                        className="text-sm font-medium text-muted-foreground hover:text-foreground"
                      >
                        {t('subscription.keepPlan')}
                      </button>
                    </div>
                  ) : (
                    <button
                      onClick={() => setShowCancelConfirm(true)}
                      className="flex items-center gap-1 text-sm text-muted-foreground hover:text-destructive transition-colors"
                    >
                      <XCircle className="h-4 w-4" />
                      {t('subscription.cancelSubscription')}
                    </button>
                  )}
                </div>
              )}
            </div>
          ) : null}
        </div>

        {/* Section 2: Usage */}
        {quota && (
          <div className="bg-card rounded-xl border border-border p-6 shadow-sm">
            <h2 className="text-lg font-semibold text-foreground mb-4">{t('subscription.usage')}</h2>
            <UsageBar
              label={t('subscription.planCommands')}
              used={quota.includedUsed}
              limit={quota.includedLimit}
              basePlanLimit={quotaBreakdown?.basePlanLimit}
              boosts={quotaBreakdown?.capBoosts}
            />
            {quota.extraLimit > 0 && (
              <div className="mt-4">
                <UsageBar label={t('subscription.purchasedCommands')} used={quota.extraUsed} limit={quota.extraLimit} />
              </div>
            )}

            {/* Customize plan (configurator) */}
            <div className="mt-6 pt-4 border-t border-border flex items-center justify-between gap-4">
              <div>
                <p className="text-sm font-medium text-foreground">Customize your plan</p>
                <p className="text-xs text-muted-foreground">Add extra seats, sites or commands to your subscription.</p>
              </div>
              <button
                onClick={() => setShowConfigurator(true)}
                className="shrink-0 rounded-lg border border-primary px-4 py-2 text-sm font-semibold text-primary hover:bg-primary/5 transition-colors"
                data-testid="open-configurator"
              >
                Anpassen
              </button>
            </div>

            {/* Buy Commands + Auto-buy */}
            {commandPackages.length > 0 && (
              <div className="mt-6 pt-4 border-t border-border flex items-center justify-between gap-4">
                <div className="flex items-center gap-2">
                  <ShoppingCart className="h-4 w-4 text-primary" />
                  {commandPackages.map((pkg: any) => (
                    <button
                      key={pkg.size}
                      onClick={() => navigate({ to: '/dashboard/checkout', search: { commandSize: pkg.size } })}
                      className="text-sm font-medium text-primary hover:text-primary/80 transition-colors"
                    >
                      {t('subscription.buyNCommands', { count: pkg.size })}
                    </button>
                  ))}
                </div>

                <div className="flex items-center gap-3">
                  <span className="text-sm text-muted-foreground">{t('subscription.autoBuy')}</span>
                  <button
                    role="switch"
                    aria-checked={autoBuyCommands}
                    onClick={() => autoBuyMutation.mutate(!autoBuyCommands)}
                    disabled={autoBuyMutation.isPending}
                    className={[
                      'relative inline-flex h-6 w-11 shrink-0 cursor-pointer rounded-full border-2 border-transparent transition-colors duration-200 ease-in-out',
                      'focus:outline-none focus:ring-2 focus:ring-primary focus:ring-offset-2',
                      autoBuyCommands ? 'bg-primary' : 'bg-muted',
                      autoBuyMutation.isPending ? 'opacity-50 cursor-not-allowed' : '',
                    ].join(' ')}
                  >
                    <span
                      className={[
                        'pointer-events-none inline-block h-5 w-5 rounded-full bg-white shadow-lg ring-0 transition-transform duration-200 ease-in-out',
                        autoBuyCommands ? 'translate-x-5' : 'translate-x-0',
                      ].join(' ')}
                    />
                  </button>
                </div>
              </div>
            )}
          </div>
        )}

        {/* Section 3: Payment History */}
        <div className="bg-card rounded-xl border border-border p-6 shadow-sm">
          <h2 className="text-lg font-semibold text-foreground mb-4">{t('subscription.paymentHistory')}</h2>
          <InvoiceList
            invoices={invoicesData?.data || []}
            meta={invoicesData?.meta}
            isLoading={invoicesLoading}
            onPageChange={setInvoicePage}
            onPayNow={handleCompletePending}
          />
        </div>
    </PageLayout>
  );
}
