'use client';

import { useCallback, useEffect, useMemo, useState } from 'react';
import { useRouter } from 'next/navigation';
import {
  ArrowLeft,
  ArrowRight,
  Bitcoin,
  Bot,
  CheckCircle2,
  ChevronDown,
  CreditCard,
  Crown,
  Loader2,
  Plus,
  ShieldAlert,
  TriangleAlert,
  X,
  Zap,
  type LucideIcon,
} from 'lucide-react';
import ApiErrorAlert from '@/app/components/ApiErrorAlert';
import { getResponseErrorTextWithRequestId } from '@/lib/api-client';
import { formatUsdCents } from '@/lib/billing/currency';
import { trackEvent } from '@/lib/utils';
import { PLAN_ORDER, getPlanCatalogItem } from '@/lib/plans/catalog';
import { formatDateMoscow } from '@/lib/time';
import { getRuntimeClientConfig } from '@/lib/runtime-client-config';
import type { PlanCatalogItem, PlanFeatureKey, PlanId } from '@/lib/plans/types';

type PricingProps = {
  currentPlanId?: string | null;
  currentBillingSource?: 'FREE' | 'PURCHASE' | 'ADMIN_OVERRIDE';
  currentPlanExpiresAt?: string | null;
};

type PlansCatalogResponse = {
  plans?: PlanCatalogItem[];
};

type BillingCycle = 'monthly' | 'yearly';
type BillingInterval = 'MONTHLY' | 'YEARLY';
type BillingInvoiceStatus = 'PENDING' | 'PAID' | 'EXPIRED' | 'CANCELLED' | 'FAILED';
type PaymentMethodId = 'cryptobot' | 'gateway2328' | 'heleket' | 'platega';

const PAYMENT_METHOD_TO_PROVIDER: Record<PaymentMethodId, 'CRYPTOBOT' | 'GATEWAY_2328' | 'HELEKET' | 'PLATEGA'> = {
  cryptobot: 'CRYPTOBOT',
  gateway2328: 'GATEWAY_2328',
  heleket: 'HELEKET',
  platega: 'PLATEGA',
};

type CheckoutInvoice = {
  id: string;
  status: BillingInvoiceStatus;
  amountUsdCents: number;
  invoiceUrl: string | null;
  miniAppInvoiceUrl: string | null;
  webAppInvoiceUrl: string | null;
  expiresAt: string | null;
  paidAt?: string | null;
};

type CheckoutCreateResponse = {
  invoice: CheckoutInvoice;
  reused: boolean;
  quote?: CheckoutQuote;
};

type CheckoutQuote = {
  amountUsdCents: number;
  baseAmountUsdCents: number;
  description: string;
  isUpgradeProration: boolean;
  proration: {
    activePlan: PlanId;
    activeInterval: BillingInterval;
    activePeriodPriceUsdCents: number;
    requestedPeriodPriceUsdCents: number;
    remainingRatio: number;
    remainingPercent: number;
    unusedCreditUsdCents: number;
    requestedForRemainingUsdCents: number;
  } | null;
};

type CheckoutPreviewResponse = {
  preview: CheckoutQuote;
};

type InvoiceStatusResponse = {
  invoice: {
    id: string;
    status: BillingInvoiceStatus;
    expiresAt: string | null;
    paidAt: string | null;
  };
};

type PaymentMethodItem = {
  id: PaymentMethodId;
  label: string;
  description: string;
  icon: LucideIcon;
};

type PaymentMethodsResponse = {
  methods?: Array<{
    id?: string;
    enabled?: boolean;
  }>;
};

const PRIMARY_FEATURE_KEYS: PlanFeatureKey[] = ['customSlug', 'password', 'expiresAt', 'clickLimit', 'telegramClickNotifications'];
const EXTRA_FEATURE_KEYS: PlanFeatureKey[] = [
  'bulkActions',
  'manualOgEditing',
  'csvExport',
  'pdfExport',
];
const POLL_INTERVAL_MS = 5000;

const FEATURE_LABELS: Record<PlanFeatureKey, string> = {
  customSlug: 'Кастомный slug',
  password: 'Пароль на ссылку',
  expiresAt: 'Срок действия',
  clickLimit: 'Лимит кликов',
  telegramClickNotifications: 'Telegram-уведомления о кликах',
  bulkActions: 'Массовые действия',
  csvExport: 'Экспорт в CSV',
  pdfExport: 'Экспорт в HTML',
  manualOgEditing: 'Ручное OG-редактирование',
};

const NO_AVAILABLE_PAYMENT_METHODS_MESSAGE = 'В текущий момент нет доступных способов оплаты';

const PAYMENT_METHODS: PaymentMethodItem[] = [
  {
    id: 'platega',
    label: 'Platega',
    description: 'Карта / СБП / ЕРИП / крипта',
    icon: CreditCard,
  },
  {
    id: 'cryptobot',
    label: 'CryptoBot',
    description: 'Оплата счёта в Telegram',
    icon: Bot,
  },
  {
    id: 'heleket',
    label: 'Heleket',
    description: 'Криптоплатежи через Heleket',
    icon: CreditCard,
  },
  {
    id: 'gateway2328',
    label: '2328.io',
    description: 'Криптоплатежи через шлюз 2328',
    icon: Bitcoin,
  },
];

const PLAN_PRIORITY: Record<PlanId, number> = {
  FREE: 0,
  MINIMAL: 1,
  MEDIUM: 2,
  EXTENDED: 3,
};

const PLAN_CATALOG_CACHE_TTL_MS = 5 * 60_000;
let planCatalogCache: { plans: PlanCatalogItem[]; updatedAt: number } | null = null;
let planCatalogRequest: Promise<PlanCatalogItem[]> | null = null;

const PLAN_STYLES: Record<
  PlanId,
  {
    card: string;
    check: string;
    extra: string;
    cta: string;
  }
> = {
  FREE: {
    card: 'glass-panel rounded-3xl p-8 transition-all duration-300 flex flex-col relative group border border-white/5 hover:border-violet-500/50 hover:-translate-y-2 hover:shadow-2xl hover:shadow-violet-900/40',
    check: 'text-gray-500',
    extra: 'text-gray-400',
    cta: 'bg-white/5 hover:bg-white/10 text-white font-medium border border-white/10',
  },
  MINIMAL: {
    card: 'glass-panel rounded-3xl p-8 flex flex-col relative group transition-all duration-300 border border-white/5 hover:border-violet-500/50 hover:-translate-y-2 hover:shadow-2xl hover:shadow-violet-900/40',
    check: 'text-violet-400',
    extra: 'text-violet-300',
    cta: 'bg-white/5 hover:bg-gray-200 hover:text-black text-white font-medium transition-colors border border-white/10 group-hover:bg-white group-hover:text-black',
  },
  MEDIUM: {
    card: 'glass-panel rounded-3xl p-8 flex flex-col relative group transition-all duration-300 border border-white/5 hover:border-fuchsia-500/50 hover:-translate-y-2 hover:shadow-2xl hover:shadow-fuchsia-900/40',
    check: 'text-fuchsia-400',
    extra: 'text-fuchsia-300',
    cta: 'bg-white/5 hover:bg-gray-200 hover:text-black text-white font-medium transition-colors border border-white/10 group-hover:bg-white group-hover:text-black',
  },
  EXTENDED: {
    card: 'glass-panel rounded-3xl p-8 flex flex-col relative group transition-all duration-300 border border-white/5 hover:border-blue-500/50 hover:-translate-y-2 hover:shadow-2xl hover:shadow-blue-900/40',
    check: 'text-blue-400',
    extra: 'text-blue-300',
    cta: 'bg-white/5 hover:bg-gray-200 hover:text-black text-white font-medium transition-colors border border-white/10 group-hover:bg-white group-hover:text-black',
  },
};

function cn(...classes: Array<string | false | null | undefined>) {
  return classes.filter(Boolean).join(' ');
}

function formatNumber(value: number | undefined) {
  if (typeof value !== 'number' || Number.isNaN(value)) return '0';
  return value.toLocaleString('ru-RU');
}

function formatPeriods(periods: number[]) {
  const ordered = [...periods].sort((a, b) => a - b);
  return `${ordered.join('/')} дн`;
}

function getFallbackPlans() {
  return PLAN_ORDER.map((planId) => getPlanCatalogItem(planId));
}

function orderPlans(plans: PlanCatalogItem[]) {
  const plansById = new Map(plans.map((plan) => [plan.id, plan] as const));
  return PLAN_ORDER.map((planId) => plansById.get(planId) ?? getPlanCatalogItem(planId));
}

function isFreshPlanCatalogCache(updatedAt: number) {
  return Date.now() - updatedAt < PLAN_CATALOG_CACHE_TTL_MS;
}

async function requestPlanCatalog() {
  if (planCatalogRequest) return planCatalogRequest;

  planCatalogRequest = (async () => {
    const response = await fetch('/api/plans/catalog', {
      cache: 'no-store',
    });

    if (!response.ok) {
      throw new Error('Не удалось загрузить каталог тарифов');
    }

    const data = (await response.json()) as PlansCatalogResponse;
    if (!Array.isArray(data.plans) || data.plans.length === 0) {
      throw new Error('Пустой каталог тарифов');
    }

    const nextPlans = orderPlans(data.plans);
    planCatalogCache = {
      plans: nextPlans,
      updatedAt: Date.now(),
    };

    return nextPlans;
  })();

  try {
    return await planCatalogRequest;
  } finally {
    planCatalogRequest = null;
  }
}

function normalizePlanId(value: string | null | undefined): PlanId {
  const normalized = (value ?? '').toUpperCase();
  if (normalized === 'MINIMAL' || normalized === 'MEDIUM' || normalized === 'EXTENDED') {
    return normalized;
  }
  return 'FREE';
}

function getPriceHint(plan: PlanCatalogItem, billingCycle: BillingCycle) {
  if (plan.id === 'FREE' || plan.price.monthlyUsdCents === 0) {
    return 'Базовый уровень без оплаты';
  }

  if (plan.price.yearlyDiscountPercent > 0) {
    return billingCycle === 'yearly'
      ? `Годом выгоднее на ${plan.price.yearlyDiscountPercent}%`
      : `При оплате за год: сэкономьте ${plan.price.yearlyDiscountPercent}%`;
  }

  return 'Гибкий выбор периода оплаты';
}

function getDisplayPrice(plan: PlanCatalogItem, billingCycle: BillingCycle) {
  if (plan.id === 'FREE') return 0;
  if (billingCycle === 'yearly') {
    return plan.price.yearlyUsdCents;
  }
  return plan.price.monthlyUsdCents;
}

function getPriceSuffix(billingCycle: BillingCycle) {
  return billingCycle === 'yearly' ? '/year' : '/month';
}

function toBillingInterval(cycle: BillingCycle): BillingInterval {
  return cycle === 'yearly' ? 'YEARLY' : 'MONTHLY';
}

function getInvoiceStatusLabel(status: BillingInvoiceStatus) {
  if (status === 'PENDING') return 'Ожидает оплаты';
  if (status === 'PAID') return 'Оплачен';
  if (status === 'EXPIRED') return 'Истёк';
  if (status === 'CANCELLED') return 'Отменён';
  return 'Ошибка';
}

function formatDateTime(value: string | null, timeZone: string) {
  if (!value) return '—';
  const date = new Date(value);
  if (Number.isNaN(date.getTime())) return '—';

  try {
    return date.toLocaleString('ru-RU', {
      day: '2-digit',
      month: 'short',
      hour: '2-digit',
      minute: '2-digit',
      timeZone,
    });
  } catch {
    return date.toLocaleString('ru-RU', {
      day: '2-digit',
      month: 'short',
      hour: '2-digit',
      minute: '2-digit',
      timeZone: 'Europe/Moscow',
    });
  }
}

function getIntervalLabel(interval: BillingInterval) {
  return interval === 'YEARLY' ? 'годового' : 'месячного';
}

function isPaymentMethodId(value: string): value is PaymentMethodId {
  return value === 'cryptobot' || value === 'gateway2328' || value === 'heleket' || value === 'platega';
}

type InvoiceModalState = {
  planId: PlanId;
  planLabel: string;
  billingCycle: BillingCycle;
  priceUsdCents: number;
  isUpgrade: boolean;
  isDowngrade: boolean;
};

function getPlanPriority(planId: PlanId) {
  return PLAN_PRIORITY[planId];
}

export default function Pricing({
  currentPlanId,
  currentBillingSource,
  currentPlanExpiresAt,
}: PricingProps) {
  const router = useRouter();
  const runtimeTimeZone = getRuntimeClientConfig().timeZone || 'Europe/Moscow';
  const [billingCycle, setBillingCycle] = useState<BillingCycle>('monthly');
  const [invoiceModal, setInvoiceModal] = useState<InvoiceModalState | null>(null);
  const [showInvoiceModal, setShowInvoiceModal] = useState(false);
  const [billingStep, setBillingStep] = useState<'checkout' | 'invoice'>('checkout');
  const [invoice, setInvoice] = useState<CheckoutInvoice | null>(null);
  const [checkoutQuote, setCheckoutQuote] = useState<CheckoutQuote | null>(null);
  const [isQuoteLoading, setIsQuoteLoading] = useState(false);
  const [quoteError, setQuoteError] = useState('');
  const [paymentMethodsError, setPaymentMethodsError] = useState('');
  const [invoiceError, setInvoiceError] = useState('');
  const [isCreatingInvoice, setIsCreatingInvoice] = useState(false);
  const [isCancellingInvoice, setIsCancellingInvoice] = useState(false);
  const [paymentMethodAvailability, setPaymentMethodAvailability] = useState<Partial<Record<PaymentMethodId, boolean>> | null>(null);
  const [isPaymentMethodsLoading, setIsPaymentMethodsLoading] = useState(false);
  const [selectedPaymentMethodId, setSelectedPaymentMethodId] = useState<PaymentMethodId | null>(null);
  const initialCachedPlans =
    planCatalogCache && isFreshPlanCatalogCache(planCatalogCache.updatedAt)
      ? planCatalogCache.plans
      : null;
  const [plans, setPlans] = useState<PlanCatalogItem[]>(() => initialCachedPlans || []);
  const [isCatalogLoading, setIsCatalogLoading] = useState(!initialCachedPlans);
  const [expandedFeaturePlanIds, setExpandedFeaturePlanIds] = useState<PlanId[]>([]);

  const normalizedCurrentPlan = normalizePlanId(currentPlanId);
  const hasPaidCurrentPlan = currentBillingSource === 'PURCHASE' && normalizedCurrentPlan !== 'FREE';
  const currentPlanPriority = getPlanPriority(normalizedCurrentPlan);
  const currentPlanLabel = getPlanCatalogItem(normalizedCurrentPlan).label;
  const currentPlanEndsAtLabel = useMemo(() => {
    if (!currentPlanExpiresAt) return null;
    const parsed = new Date(currentPlanExpiresAt);
    if (Number.isNaN(parsed.getTime())) return null;
    return formatDateMoscow(parsed, { day: 'numeric', month: 'long', year: 'numeric' });
  }, [currentPlanExpiresAt]);
  const availablePaymentMethods = useMemo(() => {
    if (!paymentMethodAvailability) return [];
    return PAYMENT_METHODS.filter((method) => paymentMethodAvailability[method.id] === true);
  }, [paymentMethodAvailability]);
  const selectedPaymentMethod = useMemo(
    () => availablePaymentMethods.find((method) => method.id === selectedPaymentMethodId) ?? null,
    [availablePaymentMethods, selectedPaymentMethodId]
  );

  useEffect(() => {
    if (availablePaymentMethods.length === 0) {
      setSelectedPaymentMethodId(null);
      return;
    }

    setSelectedPaymentMethodId((current) => (
      current && availablePaymentMethods.some((method) => method.id === current)
        ? current
        : availablePaymentMethods[0]!.id
    ));
  }, [availablePaymentMethods]);

  useEffect(() => {
    let isCancelled = false;
    const cachedCatalog = planCatalogCache;

    const loadPlanCatalog = async () => {
      if (cachedCatalog?.plans?.length) {
        setPlans(cachedCatalog.plans);
        setIsCatalogLoading(false);

        if (isFreshPlanCatalogCache(cachedCatalog.updatedAt)) {
          return;
        }
      } else {
        setIsCatalogLoading(true);
      }

      try {
        const loadedPlans = await requestPlanCatalog();
        if (isCancelled) return;
        setPlans(loadedPlans);
        setIsCatalogLoading(false);
      } catch {
        if (isCancelled) return;
        if (cachedCatalog?.plans?.length) {
          setPlans(cachedCatalog.plans);
          setIsCatalogLoading(false);
          return;
        }
        setPlans(getFallbackPlans());
        setIsCatalogLoading(false);
      }
    };

    void loadPlanCatalog();
    return () => {
      isCancelled = true;
    };
  }, []);

  const orderedPlans = useMemo(() => (plans.length > 0 ? orderPlans(plans) : []), [plans]);
  const yearlyDiscountBadgeText = useMemo(() => {
    if (orderedPlans.length === 0) return null;

    const discounts = orderedPlans
      .filter((plan) => plan.id !== 'FREE')
      .map((plan) => plan.price.yearlyDiscountPercent)
      .filter((value) => value > 0);

    if (discounts.length === 0) return null;

    const minDiscount = Math.min(...discounts);
    const maxDiscount = Math.max(...discounts);
    return minDiscount === maxDiscount ? `-${maxDiscount}%` : `до -${maxDiscount}%`;
  }, [orderedPlans]);

  useEffect(() => {
    if (!showInvoiceModal) return;
    const previousOverflow = document.body.style.overflow;
    document.body.style.overflow = 'hidden';
    return () => {
      document.body.style.overflow = previousOverflow;
    };
  }, [showInvoiceModal]);

  useEffect(() => {
    if (!showInvoiceModal || isCreatingInvoice || isCancellingInvoice) return;

    const handleEscape = (event: KeyboardEvent) => {
      if (event.key === 'Escape') {
        setShowInvoiceModal(false);
        setBillingStep('checkout');
      }
    };

    window.addEventListener('keydown', handleEscape);
    return () => window.removeEventListener('keydown', handleEscape);
  }, [showInvoiceModal, isCreatingInvoice, isCancellingInvoice]);

  const openInvoiceModal = useCallback((plan: PlanCatalogItem, isUpgrade: boolean, isDowngrade: boolean) => {
    setInvoiceModal({
      planId: plan.id,
      planLabel: plan.label,
      billingCycle,
      priceUsdCents: getDisplayPrice(plan, billingCycle),
      isUpgrade,
      isDowngrade,
    });
    setInvoice(null);
    setCheckoutQuote(null);
    setIsQuoteLoading(false);
    setIsCancellingInvoice(false);
    setPaymentMethodAvailability(null);
    setIsPaymentMethodsLoading(false);
    setSelectedPaymentMethodId(null);
    setPaymentMethodsError('');
    setQuoteError('');
    setInvoiceError('');
    setBillingStep('checkout');
    setShowInvoiceModal(true);
  }, [billingCycle]);

  const closeInvoiceModal = useCallback(() => {
    if (isCreatingInvoice || isCancellingInvoice) return;
    setShowInvoiceModal(false);
    setBillingStep('checkout');
  }, [isCreatingInvoice, isCancellingInvoice]);

  const createInvoice = useCallback(async () => {
    if (!invoiceModal) return;
    if (!selectedPaymentMethod) {
      setInvoiceError(NO_AVAILABLE_PAYMENT_METHODS_MESSAGE);
      return;
    }

    const provider = PAYMENT_METHOD_TO_PROVIDER[selectedPaymentMethod.id];
    if (!provider) {
      setInvoiceError('Выбранный способ оплаты сейчас недоступен');
      return;
    }

    setIsCreatingInvoice(true);
    setInvoiceError('');

    try {
      const interval = toBillingInterval(invoiceModal.billingCycle);
      const response = await fetch('/api/billing/checkout', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ plan: invoiceModal.planId, interval, provider }),
      });

      if (!response.ok) {
        throw new Error(await getResponseErrorTextWithRequestId(response, 'Не удалось создать счёт на оплату'));
      }

      const data = await response.json() as CheckoutCreateResponse;
      if (data.quote) {
        setCheckoutQuote(data.quote);
      }
      setInvoice(data.invoice);
      if (data.invoice.status === 'PAID') {
        router.replace('/profile?billing=success', { scroll: false });
      }
    } catch (error) {
      setInvoiceError(error instanceof Error ? error.message : 'Не удалось создать счёт на оплату');
    } finally {
      setIsCreatingInvoice(false);
    }
  }, [invoiceModal, router, selectedPaymentMethod]);

  useEffect(() => {
    if (!showInvoiceModal || !invoiceModal || billingStep !== 'checkout') {
      return;
    }

    const controller = new AbortController();
    let isActive = true;

    const loadCheckoutPreview = async () => {
      setIsQuoteLoading(true);
      setQuoteError('');

      try {
        const response = await fetch('/api/billing/checkout', {
          method: 'POST',
          headers: { 'Content-Type': 'application/json' },
          body: JSON.stringify({
            plan: invoiceModal.planId,
            interval: toBillingInterval(invoiceModal.billingCycle),
            preview: true,
          }),
          signal: controller.signal,
        });

        if (!response.ok) {
          throw new Error(await getResponseErrorTextWithRequestId(response, 'Не удалось рассчитать сумму оплаты'));
        }

        const data = await response.json() as CheckoutPreviewResponse;
        if (!isActive) return;
        setCheckoutQuote(data.preview);
      } catch (error) {
        if (!isActive || controller.signal.aborted) return;
        setCheckoutQuote(null);
        setQuoteError(error instanceof Error ? error.message : 'Не удалось рассчитать сумму оплаты');
      } finally {
        if (isActive) {
          setIsQuoteLoading(false);
        }
      }
    };

    void loadCheckoutPreview();

    return () => {
      isActive = false;
      controller.abort();
    };
  }, [billingStep, invoiceModal, showInvoiceModal]);

  useEffect(() => {
    if (!showInvoiceModal || billingStep !== 'checkout') {
      return;
    }

    const controller = new AbortController();
    let isActive = true;

    const loadPaymentMethods = async () => {
      setIsPaymentMethodsLoading(true);
      setPaymentMethodsError('');

      try {
        const response = await fetch('/api/billing/payment-methods', {
          cache: 'no-store',
          signal: controller.signal,
        });

        if (!response.ok) {
          throw new Error(await getResponseErrorTextWithRequestId(response, 'Не удалось загрузить способы оплаты'));
        }

        const data = await response.json() as PaymentMethodsResponse;
        if (!isActive) return;

        const availability: Partial<Record<PaymentMethodId, boolean>> = {};
        if (Array.isArray(data.methods)) {
          for (const method of data.methods) {
            const id = typeof method?.id === 'string' ? method.id.trim().toLowerCase() : '';
            if (!isPaymentMethodId(id)) continue;
            availability[id] = method.enabled === true;
          }
        }

        setPaymentMethodAvailability(availability);
      } catch (error) {
        if (!isActive || controller.signal.aborted) return;
        setPaymentMethodAvailability({});
        setPaymentMethodsError(error instanceof Error ? error.message : 'Не удалось загрузить способы оплаты');
      } finally {
        if (isActive) {
          setIsPaymentMethodsLoading(false);
        }
      }
    };

    void loadPaymentMethods();

    return () => {
      isActive = false;
      controller.abort();
    };
  }, [billingStep, showInvoiceModal]);

  const refreshInvoiceStatus = useCallback(async (invoiceId: string) => {
    try {
      const response = await fetch(`/api/billing/invoices/${invoiceId}`, {
        cache: 'no-store',
      });

      if (!response.ok) {
        throw new Error(await getResponseErrorTextWithRequestId(response, 'Не удалось получить статус счёта'));
      }

      const data = await response.json() as InvoiceStatusResponse;
      setInvoice((current) => {
        if (!current || current.id !== invoiceId) {
          return current;
        }

        return {
          ...current,
          status: data.invoice.status,
          expiresAt: data.invoice.expiresAt,
          paidAt: data.invoice.paidAt,
        };
      });

      if (data.invoice.status === 'PAID') {
        router.replace('/profile?billing=success', { scroll: false });
      }
    } catch (error) {
      setInvoiceError(error instanceof Error ? error.message : 'Не удалось обновить статус оплаты');
    }
  }, [router]);

  const cancelInvoice = useCallback(async () => {
    if (!invoice?.id) return;

    setIsCancellingInvoice(true);
    setInvoiceError('');

    try {
      const response = await fetch(`/api/billing/invoices/${invoice.id}`, {
        method: 'PATCH',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ action: 'cancel' }),
      });

      if (!response.ok) {
        throw new Error(await getResponseErrorTextWithRequestId(response, 'Не удалось отменить оплату'));
      }

      const data = await response.json() as InvoiceStatusResponse;
      setInvoice((current) => {
        if (!current) return current;
        return {
          ...current,
          status: data.invoice.status,
          expiresAt: data.invoice.expiresAt,
          paidAt: data.invoice.paidAt,
        };
      });
    } catch (error) {
      setInvoiceError(error instanceof Error ? error.message : 'Не удалось отменить оплату');
    } finally {
      setIsCancellingInvoice(false);
    }
  }, [invoice?.id]);

  const proceedToInvoice = useCallback(() => {
    if (!invoiceModal) return;
    if (!selectedPaymentMethod) {
      setInvoiceError(NO_AVAILABLE_PAYMENT_METHODS_MESSAGE);
      return;
    }

    trackEvent('pricing_select', {
      plan: invoiceModal.planId,
      interval: toBillingInterval(invoiceModal.billingCycle),
      paymentMethod: selectedPaymentMethod.id,
    });

    setBillingStep('invoice');
    if (!invoice || invoice.status !== 'PENDING') {
      void createInvoice();
    }
  }, [createInvoice, invoice, invoiceModal, selectedPaymentMethod]);

  useEffect(() => {
    if (!showInvoiceModal || billingStep !== 'invoice' || !invoice?.id || invoice.status !== 'PENDING') {
      return;
    }

    void refreshInvoiceStatus(invoice.id);
    const timer = window.setInterval(() => {
      void refreshInvoiceStatus(invoice.id);
    }, POLL_INTERVAL_MS);

    return () => window.clearInterval(timer);
  }, [billingStep, invoice?.id, invoice?.status, refreshInvoiceStatus, showInvoiceModal]);

  const openInvoiceUrl = invoice?.invoiceUrl ?? null;
  const checkoutAmountUsdCents = checkoutQuote?.amountUsdCents ?? invoiceModal?.priceUsdCents ?? 0;
  const checkoutProration = checkoutQuote?.proration;
  const hasAvailablePaymentMethods = availablePaymentMethods.length > 0;

  return (
    <section id="pricing">
      <div className="flex flex-col md:flex-row items-center justify-between gap-6 mb-8">
        <div>
          <h3 className="text-xl font-bold text-white mb-2">Переключиться на другой тариф</h3>
          <p className="text-sm text-gray-400">Выберите подходящий план для ваших потребностей.</p>
        </div>

        <div className="flex flex-col items-end gap-3 shrink-0">
          <div className="inline-flex bg-black/40 border border-white/10 rounded-full p-1">
            <button
              type="button"
              onClick={() => setBillingCycle('monthly')}
              className={cn(
                'px-6 py-2 rounded-full text-sm font-medium transition-all',
                billingCycle === 'monthly' ? 'bg-white/10 text-white' : 'text-gray-400 hover:text-white',
              )}
            >
              Месяц
            </button>
            <button
              type="button"
              onClick={() => setBillingCycle('yearly')}
              className={cn(
                'px-6 py-2 rounded-full text-sm font-medium transition-all flex items-center gap-2',
                billingCycle === 'yearly' ? 'bg-white/10 text-white' : 'text-gray-400 hover:text-white',
              )}
            >
              Год
              {yearlyDiscountBadgeText ? (
                <span className="bg-green-500/20 text-green-400 px-2 py-0.5 rounded-full text-[10px]">
                  {yearlyDiscountBadgeText}
                </span>
              ) : null}
            </button>
          </div>

        </div>
      </div>

      <div className="grid grid-cols-1 md:grid-cols-2 xl:grid-cols-4 gap-6">
        {isCatalogLoading && orderedPlans.length === 0 ? (
          PLAN_ORDER.map((planId) => (
            <div
              key={`pricing-skeleton-${planId}`}
              className="glass-panel rounded-3xl border border-white/10 bg-white/[0.03] p-8 backdrop-blur-xl"
            >
              <div className="h-4 w-20 rounded bg-white/10 animate-pulse mb-4" />
              <div className="h-7 w-32 rounded bg-white/10 animate-pulse mb-2" />
              <div className="h-4 w-full rounded bg-white/5 animate-pulse mb-1.5" />
              <div className="h-4 w-3/4 rounded bg-white/5 animate-pulse mb-6" />
              <div className="h-11 w-40 rounded bg-white/10 animate-pulse mb-6" />
              <div className="space-y-3 mb-6">
                <div className="h-4 w-full rounded bg-white/5 animate-pulse" />
                <div className="h-4 w-full rounded bg-white/5 animate-pulse" />
                <div className="h-4 w-full rounded bg-white/5 animate-pulse" />
                <div className="h-4 w-full rounded bg-white/5 animate-pulse" />
              </div>
              <div className="space-y-2.5 mb-8">
                <div className="h-4 w-1/2 rounded bg-white/5 animate-pulse" />
                <div className="h-4 w-4/5 rounded bg-white/5 animate-pulse" />
                <div className="h-4 w-4/5 rounded bg-white/5 animate-pulse" />
                <div className="h-4 w-3/5 rounded bg-white/5 animate-pulse" />
              </div>
              <div className="h-10 w-full rounded-xl bg-white/10 animate-pulse" />
            </div>
          ))
        ) : (
          orderedPlans.map((plan) => {
            const styles = PLAN_STYLES[plan.id];
            const isCurrent = normalizedCurrentPlan === plan.id;
            const planPriority = getPlanPriority(plan.id);
            const displayPrice = getDisplayPrice(plan, billingCycle);
            const priceHint = getPriceHint(plan, billingCycle);
            const includedPrimaryFeatures = PRIMARY_FEATURE_KEYS.filter((featureKey) => plan.features[featureKey]);
            const extraFeatureKeys = EXTRA_FEATURE_KEYS.filter((featureKey) => plan.features[featureKey]);
            const extraFeatureCount = extraFeatureKeys.length;
            const extrasExpanded = expandedFeaturePlanIds.includes(plan.id);
            const isUpgrade = hasPaidCurrentPlan && plan.id !== 'FREE' && planPriority > currentPlanPriority;
            const isDowngrade = hasPaidCurrentPlan && plan.id !== 'FREE' && planPriority < currentPlanPriority;

            return (
              <div key={plan.id} className={styles.card}>
                {isCurrent ? (
                  <div className="absolute -top-3.5 left-0 right-0 mx-auto w-max bg-gradient-to-r from-violet-500 to-fuchsia-500 font-bold text-[10px] uppercase tracking-wider px-3 py-1 rounded-full text-white shadow-lg shadow-violet-500/30 z-20 flex items-center gap-1">
                    <Zap className="w-3 h-3" /> Текущий
                  </div>
                ) : null}

                <h3 className="text-xl font-bold text-white mb-2">{plan.label}</h3>
                <p className="text-xs text-gray-400 mb-6 min-h-[32px]">{plan.audience}</p>

                <div className="flex flex-col mb-6 border-b border-white/5 pb-6">
                  <div className="flex items-end gap-1">
                    <span className="text-4xl font-bold font-mono tracking-tighter text-white">{formatUsdCents(displayPrice)}</span>
                    <span className="text-gray-500 mb-1">{getPriceSuffix(billingCycle)}</span>
                  </div>
                  <span className={cn('text-[10px] mt-1', plan.id === 'FREE' ? 'text-gray-500' : 'text-green-400')}>{priceHint}</span>
                </div>

                <div className="space-y-3 mb-6 text-sm">
                  <div className="flex justify-between items-center">
                    <span className="text-gray-400">Активные ссылки</span>
                    <span className="font-bold text-white">{formatNumber(plan.limits.maxActiveLinks)}</span>
                  </div>
                  <div className="flex justify-between items-center">
                    <span className="text-gray-400">Новых в месяц</span>
                    <span className="font-bold text-white">{formatNumber(plan.limits.maxMonthlyNewLinks)}</span>
                  </div>
                  <div className="flex justify-between items-center">
                    <span className="text-gray-400">Папки</span>
                    <span className="font-bold text-white">{formatNumber(plan.limits.maxFolders)}</span>
                  </div>
                  <div className="flex justify-between items-center">
                    <span className="text-gray-400">Аналитика</span>
                    <span className="font-bold text-white whitespace-nowrap text-[13px] sm:text-sm">{formatPeriods(plan.analyticsPeriods)}</span>
                  </div>
                </div>

                <div className="space-y-2.5 text-xs text-gray-300 mb-8 flex-1">
                  <div className="font-semibold text-white/50 mt-6 mb-3 border-b border-white/5 pb-2 uppercase tracking-wide text-[10px]">
                    Что включено
                  </div>
                  <li className="flex items-start gap-2">
                    <CheckCircle2 className={cn('w-4 h-4 shrink-0', styles.check)} />
                    <span className="pt-0.5">Теги до {formatNumber(plan.limits.maxTags)}</span>
                  </li>
                  <li className="flex items-start gap-2">
                    <CheckCircle2 className={cn('w-4 h-4 shrink-0', styles.check)} />
                    <span className="pt-0.5">UTM до {formatNumber(plan.limits.maxUtmTemplates)}</span>
                  </li>

                  {includedPrimaryFeatures.length > 0 ? (
                    includedPrimaryFeatures.map((featureKey) => (
                      <li key={`${plan.id}-${featureKey}`} className="flex items-start gap-2">
                        <CheckCircle2 className={cn('w-4 h-4 shrink-0', styles.check)} />
                        <span className="pt-0.5">{FEATURE_LABELS[featureKey]}</span>
                      </li>
                    ))
                  ) : (
                    <li className="flex items-start gap-2 text-gray-500">
                      <CheckCircle2 className={cn('w-4 h-4 shrink-0', styles.check)} />
                      <span className="pt-0.5">Базовые функции без PRO-опций</span>
                    </li>
                  )}

                  {extraFeatureCount > 0 ? (
                    <>
                      <div>
                        <button
                          type="button"
                          aria-expanded={extrasExpanded}
                          onClick={() => {
                            setExpandedFeaturePlanIds((current) =>
                              current.includes(plan.id)
                                ? current.filter((planId) => planId !== plan.id)
                                : [...current, plan.id]
                            );
                          }}
                          className={cn(
                            'flex w-full items-start justify-between gap-2 rounded-xl border border-white/5 bg-white/[0.03] px-3 py-2 text-left font-medium transition-all duration-300 hover:border-white/15 hover:bg-white/[0.06]',
                            styles.extra,
                          )}
                        >
                          <span className="flex items-start gap-2">
                            <Plus className="w-4 h-4 shrink-0" />
                            <span className="pt-0.5">{extrasExpanded ? 'Скрыть возможности' : `+${extraFeatureCount} возможностей`}</span>
                          </span>
                          <ChevronDown className={cn('mt-0.5 h-4 w-4 shrink-0 transition-transform duration-300', extrasExpanded && 'rotate-180')} />
                        </button>
                      </div>
                      {extrasExpanded ? (
                        <div className="space-y-2 rounded-2xl border border-white/5 bg-black/20 p-3">
                          {extraFeatureKeys.map((featureKey) => (
                            <div key={`${plan.id}-extra-${featureKey}`} className="flex items-start gap-2">
                              <CheckCircle2 className={cn('w-4 h-4 shrink-0', styles.check)} />
                              <span className="pt-0.5">{FEATURE_LABELS[featureKey]}</span>
                            </div>
                          ))}
                        </div>
                      ) : null}
                    </>
                  ) : null}
                </div>

                {plan.id === 'FREE' ? null : isCurrent ? (
                  <button
                    type="button"
                    className="w-full py-2.5 text-sm rounded-xl bg-white/5 text-gray-400 font-medium border border-white/10 cursor-default mt-auto"
                  >
                    Текущий активный план
                  </button>
                ) : (
                  <button
                    type="button"
                    onClick={() => {
                      openInvoiceModal(plan, isUpgrade, isDowngrade);
                    }}
                    className={cn('w-full py-2.5 text-sm rounded-xl text-center mt-auto inline-flex items-center justify-center', styles.cta)}
                  >
                    Выбрать тариф
                  </button>
                )}
              </div>
            );
          })
        )}
      </div>

      {showInvoiceModal && invoiceModal ? (
        <div className="fixed inset-0 z-[120] flex items-center justify-center p-4">
          <button
            type="button"
            aria-label="Закрыть модальное окно"
            className="absolute inset-0 bg-black/65 backdrop-blur-sm"
            onClick={closeInvoiceModal}
          />

          <div
            className={cn(
              'relative z-10 overflow-hidden rounded-[1.75rem] border border-white/10 bg-[#09090B]/95 shadow-[0_24px_90px_rgba(0,0,0,0.65)]',
              billingStep === 'checkout' ? 'w-full max-w-[760px]' : 'w-full max-w-[380px]',
            )}
          >
            {billingStep === 'checkout' ? (
              <div className="flex flex-col md:flex-row">
                <div className="relative w-full border-b border-white/10 bg-white/[0.02] p-6 md:w-5/12 md:border-b-0 md:border-r">
                  <div className="pointer-events-none absolute inset-0 bg-gradient-to-br from-violet-500/10 via-transparent to-transparent" />
                  <div className="relative z-10">
                    <h2 className="mb-6 text-3xl font-bold tracking-tight text-white">Оформление</h2>

                    <div className="mb-6 rounded-2xl border border-white/10 bg-black/45 p-4">
                      <div className="flex items-center gap-3">
                        <div className="flex h-10 w-10 items-center justify-center rounded-lg bg-violet-500/20 text-violet-300">
                          <Crown className="h-5 w-5" />
                        </div>
                        <div>
                          <div className="text-sm text-gray-400">Тариф</div>
                          <div className="text-xl font-semibold uppercase tracking-wide text-white">{invoiceModal.planLabel}</div>
                        </div>
                      </div>
                    </div>

                    <div className="space-y-3 mb-6">
                      <div className="flex items-center justify-between">
                        <span className="text-lg text-gray-400">Период</span>
                        <span className="text-lg font-semibold text-white">
                          {invoiceModal.billingCycle === 'monthly' ? '1 месяц' : '1 год'}
                        </span>
                      </div>
                      <div className="h-px w-full bg-white/10" />
                      <div className="flex items-center justify-between">
                        <span className="text-lg text-gray-400">К оплате</span>
                        <div className="text-right">
                          <span className="text-2xl font-bold text-white">{formatUsdCents(checkoutAmountUsdCents)}</span>
                          <div className="mt-0.5 text-[11px] text-gray-500">
                            {isQuoteLoading ? 'Пересчитываем сумму…' : checkoutQuote?.isUpgradeProration ? 'Доплата по остатку периода' : 'Итоговая стоимость периода'}
                          </div>
                        </div>
                      </div>
                    </div>

                    <div className="rounded-xl border border-white/10 bg-white/[0.04] p-4 text-sm text-gray-400">
                      <div className="inline-flex items-start gap-2">
                        <ShieldAlert className="h-4 w-4 mt-0.5 text-violet-300" />
                        <span>Безопасная оплата. SSL-шифрование передаваемых данных.</span>
                      </div>
                    </div>
                  </div>
                </div>

                <div className="relative w-full p-6 md:w-7/12">
                  <button
                    type="button"
                    onClick={closeInvoiceModal}
                    className="absolute right-6 top-6 text-gray-400 transition-colors hover:text-white"
                    aria-label="Закрыть"
                  >
                    <X className="h-5 w-5" />
                  </button>

                  <h3 className="mb-6 text-sm font-bold uppercase tracking-wider text-gray-500">СПОСОБ ОПЛАТЫ</h3>

                  <div className="mb-6">
                    {isPaymentMethodsLoading ? (
                      <div className="flex items-center gap-2 rounded-2xl border border-white/10 bg-black/35 px-4 py-3 text-sm text-gray-400">
                        <Loader2 className="h-4 w-4 animate-spin text-violet-300" />
                        Загружаем способы оплаты...
                      </div>
                    ) : hasAvailablePaymentMethods ? (
                      <div role="radiogroup" aria-label="Способы оплаты" className="space-y-3">
                        {availablePaymentMethods.map((method) => {
                          const Icon = method.icon;
                          const selected = method.id === selectedPaymentMethodId;
                          return (
                            <button
                              key={method.id}
                              type="button"
                              role="radio"
                              aria-checked={selected}
                              onClick={() => setSelectedPaymentMethodId(method.id)}
                              className={cn(
                                'flex w-full items-center gap-4 rounded-2xl border p-4 text-left transition-all',
                                selected
                                  ? 'border-violet-500/60 bg-violet-500/10 shadow-[0_0_24px_rgba(139,92,246,0.18)]'
                                  : 'border-white/10 bg-black/35 hover:border-violet-500/30',
                              )}
                            >
                              <div className={cn(
                                'flex h-10 w-10 shrink-0 items-center justify-center rounded-full',
                                selected ? 'bg-violet-500/15 text-violet-300' : 'bg-white/5 text-gray-400',
                              )}
                              >
                                <Icon className="h-4 w-4" />
                              </div>
                              <div className="flex-1 min-w-0">
                                <div className="text-base font-semibold text-white">{method.label}</div>
                                <div className="text-xs text-gray-400">{method.description}</div>
                              </div>
                              <div className={cn(
                                'flex h-5 w-5 shrink-0 items-center justify-center rounded-full border-2 transition-colors',
                                selected ? 'border-violet-500' : 'border-white/30',
                              )}
                              >
                                {selected ? <div className="h-2 w-2 rounded-full bg-violet-500" /> : null}
                              </div>
                            </button>
                          );
                        })}
                      </div>
                    ) : (
                      <div className="rounded-2xl border border-amber-500/25 bg-amber-500/10 p-4 text-sm text-amber-100">
                        {NO_AVAILABLE_PAYMENT_METHODS_MESSAGE}
                      </div>
                    )}
                  </div>

                  {invoiceModal.isUpgrade ? (
                    <div className="mb-4 rounded-xl border border-emerald-500/25 bg-emerald-500/10 p-3 text-xs text-emerald-100">
                      <p className="font-semibold text-emerald-50">Апгрейд с зачётом остатка текущего тарифа</p>
                      {checkoutProration ? (
                        <>
                          <p className="mt-1.5">
                            Засчитаем {checkoutProration.remainingPercent}% от активного {getIntervalLabel(checkoutProration.activeInterval)} тарифа: {formatUsdCents(checkoutProration.unusedCreditUsdCents)} в счёт нового периода.
                          </p>
                          <p className="mt-1.5">
                            Доплата = {formatUsdCents(checkoutProration.requestedPeriodPriceUsdCents)} - {formatUsdCents(checkoutProration.unusedCreditUsdCents)} = {formatUsdCents(checkoutAmountUsdCents)}.
                          </p>
                        </>
                      ) : (
                        <p className="mt-1.5">После оплаты новый тариф активируется сразу.</p>
                      )}
                    </div>
                  ) : null}

                  {invoiceModal.isDowngrade ? (
                    <div className="mb-4 rounded-xl border border-amber-500/25 bg-amber-500/10 p-3 text-xs text-amber-100">
                      <div className="mb-1 inline-flex items-center gap-1.5">
                        <TriangleAlert className="h-3.5 w-3.5" />
                        Даунгрейд подписки
                      </div>
                      <p>
                        Тариф {invoiceModal.planLabel} активируется после завершения текущего тарифа {currentPlanLabel}
                        {currentPlanEndsAtLabel ? ` (до ${currentPlanEndsAtLabel})` : ''}.
                      </p>
                    </div>
                  ) : null}

                  <ApiErrorAlert message={paymentMethodsError} className="mb-4" />
                  <ApiErrorAlert message={quoteError} className="mb-4" />
                  <ApiErrorAlert message={invoiceError} className="mb-4" />

                  <button
                    type="button"
                    onClick={proceedToInvoice}
                    disabled={isQuoteLoading || isPaymentMethodsLoading || !selectedPaymentMethod}
                    className="inline-flex w-full items-center justify-center gap-2 rounded-2xl bg-gradient-to-r from-fuchsia-500 to-violet-600 px-6 py-3 text-lg font-semibold text-white transition-all hover:brightness-110 disabled:cursor-not-allowed disabled:opacity-70"
                  >
                    {isQuoteLoading
                      ? 'Считаем сумму...'
                      : isPaymentMethodsLoading
                        ? 'Загружаем способы оплаты...'
                        : selectedPaymentMethod
                          ? 'Перейти к оплате'
                          : NO_AVAILABLE_PAYMENT_METHODS_MESSAGE}
                    <ArrowRight className="h-5 w-5" />
                  </button>
                </div>
              </div>
            ) : (
              <div className="relative p-5">
                <div className="mb-4 flex items-center justify-between">
                  <button
                    type="button"
                    onClick={() => setBillingStep('checkout')}
                    className="inline-flex items-center gap-1.5 text-sm text-gray-300 transition-colors hover:text-white"
                  >
                    <ArrowLeft className="h-4 w-4" /> Назад
                  </button>
                  <button
                    type="button"
                    onClick={closeInvoiceModal}
                    className="text-gray-400 transition-colors hover:text-white"
                    aria-label="Закрыть"
                  >
                    <X className="h-4 w-4" />
                  </button>
                </div>

                <ApiErrorAlert message={invoiceError} className="mb-4" />

                {isCreatingInvoice ? (
                  <div className="flex flex-col items-center justify-center gap-3 py-8">
                    <Loader2 className="h-7 w-7 animate-spin text-violet-400" />
                    <p className="text-sm text-gray-300">
                      {selectedPaymentMethod
                        ? `Создаём счёт в ${selectedPaymentMethod.label}...`
                        : 'Создаём счёт на оплату...'}
                    </p>
                  </div>
                ) : invoice ? (
                  <>
                    <div className="mb-4 flex flex-col items-center text-center">
                      <div className="mb-2.5 flex h-14 w-14 items-center justify-center rounded-full bg-violet-500/15 text-violet-300">
                        {(() => {
                          const InvoiceIcon = selectedPaymentMethod?.icon ?? Bitcoin;
                          return <InvoiceIcon className="h-6 w-6" />;
                        })()}
                      </div>
                      <h3 className="text-2xl font-bold tracking-tight text-white">
                        {selectedPaymentMethod?.label ?? 'Оплата'}
                      </h3>
                      <p className="mt-1 text-sm text-gray-400">
                        {selectedPaymentMethod?.description ?? 'Перейдите по ссылке, чтобы завершить оплату'}
                      </p>
                    </div>

                    <div className="mb-5 space-y-2.5 text-xs">
                      <div className="flex items-center justify-between border-b border-white/10 pb-2.5">
                        <span className="text-sm text-gray-400">Сумма</span>
                        <span className="text-xl font-semibold text-white">{formatUsdCents(invoice.amountUsdCents)}</span>
                      </div>
                      <div className="flex items-center justify-between border-b border-white/10 pb-2.5">
                        <span className="text-sm text-gray-400">Статус</span>
                        <span className={cn(
                          'inline-flex items-center gap-2 text-sm font-medium',
                          invoice.status === 'PAID'
                            ? 'text-emerald-400'
                            : invoice.status === 'PENDING'
                              ? 'text-yellow-400'
                              : 'text-gray-300',
                        )}
                        >
                          {invoice.status === 'PENDING' ? (
                            <span className="h-2 w-2 rounded-full bg-yellow-400" />
                          ) : null}
                          {getInvoiceStatusLabel(invoice.status)}
                        </span>
                      </div>
                      <div className="border-b border-white/10 pb-2.5">
                        <div className="mb-1 text-xs uppercase tracking-wide text-gray-500">ID счёта</div>
                        <div className="break-all text-right font-mono text-[11px] text-gray-200">{invoice.id}</div>
                      </div>
                      <div className="border-b border-white/10 pb-2.5">
                        <div className="flex items-start justify-between gap-3">
                          <div className="text-xs uppercase tracking-wide text-gray-500">Действует до</div>
                          <div className="text-right">
                            <div className="text-sm leading-tight text-gray-200">{formatDateTime(invoice.expiresAt, runtimeTimeZone)}</div>
                            <div className="mt-0.5 text-[11px] text-gray-500">{runtimeTimeZone}</div>
                          </div>
                        </div>
                      </div>
                    </div>

                    <div className="space-y-3">
                      {invoice.status === 'PENDING' && openInvoiceUrl ? (
                        <a
                          href={openInvoiceUrl}
                          target="_blank"
                          rel="noopener noreferrer"
                          className="inline-flex w-full items-center justify-center rounded-2xl bg-gradient-to-r from-fuchsia-500 to-violet-600 px-5 py-2.5 text-sm font-semibold text-white shadow-[0_0_20px_rgba(139,92,246,0.25)] transition-all hover:brightness-110 hover:shadow-[0_0_25px_rgba(139,92,246,0.45)]"
                        >
                          Открыть счёт
                        </a>
                      ) : null}
                    </div>

                    {invoice.status === 'PENDING' ? (
                      <button
                        type="button"
                        onClick={() => void cancelInvoice()}
                        disabled={isCancellingInvoice}
                        className="mt-4 w-full text-center text-sm text-gray-400 transition-colors hover:text-red-300 disabled:cursor-not-allowed disabled:opacity-60"
                      >
                        {isCancellingInvoice ? 'Отменяем оплату...' : 'Отменить оплату'}
                      </button>
                    ) : null}

                  </>
                ) : (
                  <div className="py-10 text-center">
                    <p className="mb-4 text-sm text-gray-400">Счёт пока не создан.</p>
                    <button
                      type="button"
                      onClick={() => void createInvoice()}
                      disabled={!selectedPaymentMethod}
                      className="inline-flex items-center justify-center rounded-xl bg-violet-600 px-4 py-2.5 text-sm font-medium text-white transition-colors hover:bg-violet-500 disabled:cursor-not-allowed disabled:opacity-60"
                    >
                      {selectedPaymentMethod ? 'Создать счёт' : NO_AVAILABLE_PAYMENT_METHODS_MESSAGE}
                    </button>
                  </div>
                )}
              </div>
            )}
          </div>
        </div>
      ) : null}
    </section>
  );
}
