const { useEffect, useMemo, useRef, useState } = React;

const API_BASE =
  window.__SHOP_API_BASE__ ||
  localStorage.getItem("shop-api-base") ||
  (window.location.protocol === "file:" ? "http://127.0.0.1:8000/api" : "/api");

const SESSION_TOKEN_KEY = "shop-session-token";

const navItems = [
  { id: "home", label: "Главная", icon: "icon-home-fill" },
  { id: "favorites", label: "Избранное", icon: "icon-heart-fill" },
  { id: "cart", label: "Корзина", icon: "icon-bag-fill" },
  { id: "profile", label: "Профиль", icon: "icon-user-fill" },
];

const sortModes = [
  { id: "featured", label: "По популярности" },
  { id: "priceAsc", label: "Цена: ниже" },
  { id: "priceDesc", label: "Цена: выше" },
];

const emptyPromoForm = {
  code: "",
  discount_type: "percent",
  amount: "10",
  description: "",
  usage_limit: "",
  is_active: true,
};

const emptyProductForm = {
  title: "",
  price: "2990",
  category: "ФУТБОЛКИ",
  sort_order: "0",
  is_active: true,
  imagesText: "",
  sizesText: "S\nM\nL\nXL",
  descriptionText: "",
};

let cdekWidgetScriptPromise = null;

function ensureCdekWidgetScript() {
  if (window.CDEKWidget) {
    return Promise.resolve(window.CDEKWidget);
  }

  if (cdekWidgetScriptPromise) {
    return cdekWidgetScriptPromise;
  }

  cdekWidgetScriptPromise = new Promise((resolve, reject) => {
    const existing = document.querySelector('script[data-cdek-widget="1"]');
    if (existing) {
      existing.addEventListener("load", () => resolve(window.CDEKWidget));
      existing.addEventListener("error", () => reject(new Error("Не удалось загрузить виджет СДЭК")));
      return;
    }

    const script = document.createElement("script");
    script.src = "https://cdn.jsdelivr.net/npm/@cdek-it/widget@3";
    script.async = true;
    script.dataset.cdekWidget = "1";
    script.onload = () => {
      if (window.CDEKWidget) {
        resolve(window.CDEKWidget);
      } else {
        reject(new Error("Виджет СДЭК загрузился некорректно"));
      }
    };
    script.onerror = () => reject(new Error("Не удалось загрузить виджет СДЭК"));
    document.head.appendChild(script);
  });

  return cdekWidgetScriptPromise;
}


function rub(value) {
  return `${new Intl.NumberFormat("ru-RU").format(value)} \u20bd`;
}

function getStoredToken() {
  return localStorage.getItem(SESSION_TOKEN_KEY) || "";
}

function setStoredToken(token) {
  localStorage.setItem(SESSION_TOKEN_KEY, token);
}

function clearStoredToken() {
  localStorage.removeItem(SESSION_TOKEN_KEY);
}

function getTelegramInitData() {
  return window.Telegram?.WebApp?.initData || "";
}

function isLocalPreview() {
  return (
    window.location.protocol === "file:" ||
    window.location.hostname === "127.0.0.1" ||
    window.location.hostname === "localhost"
  );
}

function parseTimestamp(value) {
  if (!value) {
    return null;
  }

  if (typeof value === "number") {
    return new Date(value * 1000);
  }

  return new Date(`${value.replace(" ", "T")}Z`);
}

function formatOrderDate(value) {
  const date = parseTimestamp(value);
  if (!date || Number.isNaN(date.getTime())) {
    return "\u2014";
  }
  return new Intl.DateTimeFormat("ru-RU", {
    day: "2-digit",
    month: "short",
    hour: "2-digit",
    minute: "2-digit",
  }).format(date);
}

function getDisplayName(user) {
  if (!user) {
    return "Покупатель";
  }
  return (
    user.display_name ||
    [user.first_name, user.last_name].filter(Boolean).join(" ").trim() ||
    (user.username ? `@${user.username}` : "Покупатель")
  );
}

function getInitials(user) {
  const name = getDisplayName(user).replace("@", "").trim();
  const parts = name.split(/\s+/).filter(Boolean);
  const letters = parts.slice(0, 2).map((part) => part[0]?.toUpperCase() || "");
  return letters.join("") || "TG";
}

async function copyText(text) {
  if (navigator.clipboard?.writeText) {
    await navigator.clipboard.writeText(text);
    return;
  }

  const input = document.createElement("textarea");
  input.value = text;
  input.setAttribute("readonly", "");
  input.style.position = "absolute";
  input.style.left = "-9999px";
  document.body.appendChild(input);
  input.select();
  document.execCommand("copy");
  document.body.removeChild(input);
}

async function apiRequest(path, options = {}) {
  const headers = {
    "Content-Type": "application/json",
    ...(options.headers || {}),
  };

  if (!options.skipAuth) {
    const token = getStoredToken();
    if (token) {
      headers.Authorization = `Bearer ${token}`;
    }
  }

  const response = await fetch(`${API_BASE}${path}`, {
    ...options,
    headers,
  });

  if (!response.ok) {
    const payload = await response.json().catch(() => ({}));
    if (response.status === 401 && !options.skipAuth) {
      clearStoredToken();
    }
    const detail = payload.detail;
    const error = new Error(
      typeof detail === "string" ? detail : payload.message || `Ошибка API (${response.status})`
    );
    error.status = response.status;
    error.payload = payload;
    error.path = path;
    throw error;
  }

  return response.json();
}

function makeCartKey(productId, size = "") {
  return `${productId}::${size || ""}`;
}

function buildCartIndex(items) {
  return Object.fromEntries(items.map((item) => [item.key, item]));
}

function normalizeState(payload) {
  const favorites = payload.favorites || [];
  const cartItems = (payload.cart || []).map((item) => ({
    ...item,
    size: item.size || "",
    key: item.key || makeCartKey(item.product_id, item.size || ""),
  }));

  return {
    user: payload.user || null,
    favorites,
    cartItems,
    cartIndex: buildCartIndex(cartItems),
    orders: payload.orders || [],
    supportUrl: payload.support_url || null,
    supportUsername: payload.support_username || null,
  };
}

function Icon({ id }) {
  return (
    <svg aria-hidden="true">
      <use href={`#${id}`}></use>
    </svg>
  );
}

function CatalogHeader({
  activeCategory,
  searchOpen,
  searchQuery,
  onSearchToggle,
  onSearchChange,
  onOpenCategories,
  onCycleSort,
  onOpenProfile,
  categoryButtons,
}) {
  return (
    <>
      <header className="catalog-top">
        <button className="icon-button accent" onClick={onOpenProfile} aria-label="Профиль">
          <Icon id="icon-menu" />
        </button>
        <h1>TEST</h1>
        <button className="icon-button accent" onClick={onSearchToggle} aria-label="Поиск">
          <Icon id="icon-search" />
        </button>
      </header>

      <section className="toolbar">
        <div className="chips-row">
          <button className="chip chip-round" onClick={onCycleSort} aria-label="Сортировка">
            <Icon id="icon-sort" />
          </button>

          <button className="chip chip-wide" onClick={onOpenCategories}>
            <span>{activeCategory === "ALL" ? "Категории" : activeCategory}</span>
            <svg className="chevron" aria-hidden="true">
              <use href="#icon-chevron"></use>
            </svg>
          </button>

          <div className="chip-strip">{categoryButtons}</div>
        </div>

        {searchOpen ? (
          <div className="search-panel">
            <label className="search-field">
              <Icon id="icon-search" />
              <input
                type="search"
                placeholder="Поиск товаров"
                autoComplete="off"
                value={searchQuery}
                onChange={(event) => onSearchChange(event.target.value)}
              />
            </label>
          </div>
        ) : null}
      </section>
    </>
  );
}

function ProductCard({ product, isFavorite, onToggleFavorite, onOpen }) {
  return (
    <article className="product-card">
      <div className="product-image">
        <button
          className={`product-heart ${isFavorite ? "active" : ""}`}
          onClick={() => onToggleFavorite(product.id)}
          aria-label="Добавить в избранное"
        >
          <Icon id={isFavorite ? "icon-heart-fill" : "icon-heart-outline"} />
        </button>

        <button className="product-media-button" onClick={() => onOpen(product.id)} aria-label={product.title}>
          <div className="product-photo-frame">
            <img className="product-photo" src={product.images[0]} alt={product.title} loading="lazy" />
          </div>
        </button>

        <div className="product-dots">
          {product.images.map((_, index) => (
            <span key={index} className={index === 0 ? "active" : ""}></span>
          ))}
        </div>
      </div>

      <button className="product-copy-button" onClick={() => onOpen(product.id)}>
        <div className="product-price">{rub(product.price)}</div>
        <h2 className="product-title">{product.title}</h2>
        <div className="product-meta">{product.category}</div>
      </button>
    </article>
  );
}

function FavoritesEmpty({ onBackToShop }) {
  return (
    <div className="empty-state favorite-empty tab-screen">
      <div className="favorite-empty-art" aria-hidden="true">
        <svg viewBox="0 0 140 140">
          <path className="duck-body" d="M71 21c17 0 31 13 31 31 0 9-4 17-10 23 10 5 18 14 22 25 2 6-2 12-9 12H42c-7 0-11-6-9-12 4-11 12-20 22-25-6-6-10-14-10-23 0-18 14-31 31-31Z" />
          <path className="duck-shade" d="M71 21c17 0 31 13 31 31 0 9-4 17-10 23 5 2 9 5 13 9-8 4-18 6-29 6-26 0-47-13-47-29 0-7 4-14 11-19a31 31 0 0 1 31-21Z" />
          <ellipse className="duck-eye" cx="56" cy="59" rx="4.8" ry="6.2" />
          <ellipse className="duck-eye" cx="84" cy="59" rx="4.8" ry="6.2" />
          <path className="duck-beak" d="M52 74c0-6 8-10 18-10s18 4 18 10c0 7-8 13-18 13s-18-6-18-13Z" />
          <path d="M56 74c5 3 10 4 14 4s9-1 14-4" fill="none" stroke="#b54c18" strokeWidth="3" strokeLinecap="round" />
          <path className="duck-heart" d="M26 96c-1.7 0-3-.5-4.1-1.4-4.2-3.1-11.4-9-12.2-14.4-.6-3.7 1.8-7.1 5.6-7.6 2.3-.3 4.5.6 5.9 2.3 1.5-1.7 3.6-2.6 5.9-2.3 3.7.5 6.2 3.9 5.6 7.6-.8 5.4-8 11.3-12.2 14.4-1.1.9-2.5 1.4-4.1 1.4Z" />
          <path className="duck-heart" d="M106 35c-1.5 0-2.8-.5-3.8-1.3-3.8-2.8-10.2-8-10.9-12.8-.5-3.4 1.6-6.4 4.9-6.9 2.1-.3 4 .5 5.3 2.1 1.3-1.6 3.3-2.4 5.4-2.1 3.3.5 5.4 3.5 4.9 6.9-.8 4.8-7.2 10-10.9 12.8-1 .8-2.3 1.3-3.9 1.3Z" />
          <path className="duck-heart" d="M113 72c-1.4 0-2.5-.4-3.5-1.2-3.3-2.5-8.9-7-9.5-11.1-.4-3 1.4-5.6 4.3-6.1 1.8-.3 3.6.5 4.7 1.9 1.1-1.4 2.9-2.2 4.7-1.9 2.9.5 4.8 3.1 4.3 6.1-.6 4.1-6.2 8.6-9.5 11.1-.9.8-2.1 1.2-3.5 1.2Z" />
          <circle className="duck-heart-shine" cx="104" cy="18" r="2" />
          <circle className="duck-heart-shine" cx="111" cy="55" r="1.8" />
          <path d="M67 40c-9 0-17 4-22 10" fill="none" stroke="#fff8d8" strokeWidth="4" strokeLinecap="round" />
        </svg>
      </div>
      <h2>В избранном пока пусто</h2>
      <p>Сохраняйте понравившиеся вещи, чтобы быстро вернуться к ним позже.</p>
      <button className="primary-action" onClick={onBackToShop}>
        Вернуться в каталог
      </button>
    </div>
  );
}

const checkoutSteps = [
  { id: "contact", label: "Контакты" },
  { id: "delivery", label: "Доставка" },
  { id: "shipping", label: "Способ доставки" },
  { id: "payment", label: "Оплата" },
  { id: "review", label: "Подтверждение" },
];

function formatCdekEta(tariff) {
  if (!tariff) {
    return "";
  }
  if (tariff.period_min && tariff.period_max) {
    if (tariff.period_min === tariff.period_max) {
      return `${tariff.period_max} дн.`;
    }
    return `${tariff.period_min}-${tariff.period_max} дн.`;
  }
  if (tariff.period_max) {
    return `${tariff.period_max} дн.`;
  }
  return "";
}

function getOrderStatusLabel(status, paymentProvider) {
  const normalized = (status || "").toLowerCase();
  if (normalized === "paid") {
    return "Оплачен";
  }
  if (normalized === "pending_payment") {
    return "Ожидает оплаты";
  }
  if (normalized === "new" || normalized === "manual_review") {
    return paymentProvider === "manual" ? "Нужно подтвердить" : "Новый заказ";
  }
  if (normalized === "processing") {
    return "В обработке";
  }
  if (normalized === "completed") {
    return "Завершен";
  }
  return "Заказ создан";
}

function CheckoutFlow({
  open,
  step,
  draft,
  options,
  cartItems,
  productMap,
  couponCode,
  promoPreview,
  applyingPromo,
  submitting,
  onClose,
  onBack,
  onAdvance,
  onSubmit,
  onChange,
  onDeliveryPicked,
  onCouponChange,
  onApplyPromo,
}) {
  const widgetRef = useRef(null);
  const deliveryPickedRef = useRef(onDeliveryPicked);
  const [widgetLoading, setWidgetLoading] = useState(false);
  const [widgetError, setWidgetError] = useState("");

  const widgetConfig = options?.cdek_widget || {};
  const deliveryChosen = Boolean(draft.delivery_code && draft.delivery_method_id && draft.delivery_address);

  const totalItems = cartItems.reduce((sum, item) => sum + item.quantity, 0);
  const itemsAmount = cartItems.reduce((sum, item) => {
    const product = productMap[item.product_id];
    return sum + (product ? product.price * item.quantity : 0);
  }, 0);
  const discountAmount = promoPreview?.coupon_applied ? promoPreview.discount_amount || 0 : 0;
  const deliveryAmount = draft.delivery_amount || 0;
  const finalTotal =
    (promoPreview?.coupon_applied ? promoPreview.total_amount || Math.max(0, itemsAmount - discountAmount) : itemsAmount) +
    deliveryAmount;

  const activeStepIndex = checkoutSteps.findIndex((item) => item.id === step);
  const reviewDeliveryAddress = draft.delivery_address || "";

  useEffect(() => {
    deliveryPickedRef.current = onDeliveryPicked;
  }, [onDeliveryPicked]);

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

    async function initWidget() {
      if (!open || !widgetConfig.configured) {
        return;
      }

      setWidgetLoading(true);
      setWidgetError("");

      try {
        const CDEKWidget = await ensureCdekWidgetScript();
        if (cancelled) {
          return;
        }

        if (widgetRef.current?.destroy) {
          widgetRef.current.destroy();
        }

        widgetRef.current = new CDEKWidget({
          apiKey: widgetConfig.api_key,
          servicePath: widgetConfig.service_path,
          popup: true,
          canChoose: true,
          defaultLocation: draft.contact_city || widgetConfig.default_location || "Чебоксары",
          from: widgetConfig.from,
          goods: widgetConfig.goods || [],
          lang: "rus",
          currency: "RUB",
          hideDeliveryOptions:
            draft.delivery_mode === "pickup" ? { door: true } : { office: true },
          onChoose(type, tariff, address) {
            const mode = type === "door" ? "courier" : "pickup";
            const pointLabel =
              address?.name ||
              address?.office_name ||
              (mode === "courier" ? "Адрес доставки" : "Пункт выдачи СДЭК");
            const label =
              tariff?.tariff_name ||
              tariff?.name ||
              (mode === "courier" ? "Курьерская доставка" : "Посылка склад-склад");
            const normalizedAddress =
              mode === "courier"
                ? address?.formatted || address?.address || draft.delivery_address || ""
                : address?.address || address?.formatted || "";
            const normalizedCode =
              address?.code ||
              address?.office_code ||
              address?.city_code ||
              normalizedAddress ||
              `${mode}-${Date.now()}`;
            const cityCode =
              address?.city_code ||
              address?.location?.city_code ||
              address?.city?.code ||
              "";
            const officeCode = address?.code || address?.office_code || "";

            deliveryPickedRef.current?.({
              delivery_mode: mode,
              delivery_code: String(normalizedCode),
              delivery_point_label: pointLabel,
              delivery_address: normalizedAddress,
              delivery_city_code: cityCode ? String(cityCode) : "",
              delivery_office_code: officeCode ? String(officeCode) : "",
              delivery_method_id: String(tariff?.tariff_code || tariff?.id || mode),
              delivery_label: label,
              delivery_eta: formatCdekEta(tariff),
              delivery_amount: Number(tariff?.delivery_sum || 0),
            });

            try {
              this.close();
            } catch (err) {
              console.warn("Не удалось закрыть виджет СДЭК автоматически.", err);
            }
          },
        });
      } catch (err) {
        if (!cancelled) {
          setWidgetError(err.message || "Не удалось инициализировать виджет СДЭК");
        }
      } finally {
        if (!cancelled) {
          setWidgetLoading(false);
        }
      }
    }

    initWidget();

    return () => {
      cancelled = true;
      if (widgetRef.current?.destroy) {
        widgetRef.current.destroy();
      }
      widgetRef.current = null;
    };
  }, [
    open,
    widgetConfig.configured,
    widgetConfig.api_key,
    widgetConfig.service_path,
    widgetConfig.from,
    widgetConfig.goods,
    widgetConfig.default_location,
    draft.contact_city,
    draft.delivery_mode,
  ]);

  if (!open || !options) {
    return null;
  }

  function openDeliveryWidget() {
    if (!widgetConfig.configured) {
      setWidgetError(
        "Добавьте на сервере YANDEX_MAPS_API_KEY, CDEK_INTEGRATION_ACCOUNT и CDEK_INTEGRATION_PASSWORD, чтобы включить выбор доставки."
      );
      return;
    }

    if (!widgetRef.current?.open) {
      setWidgetError("Виджет СДЭК еще не успел загрузиться. Попробуйте еще раз через секунду.");
      return;
    }

    setWidgetError("");
    widgetRef.current.open();
  }

  return (
    <div className="checkout-shell">
      <div className="checkout-backdrop" onClick={onClose}></div>
      <section className="checkout-layer">
        <header className="checkout-topbar">
          <button className="checkout-back-btn" onClick={onBack}>
            <span aria-hidden="true">←</span>
            <span>Назад</span>
          </button>
          <div className="checkout-brand">TEST</div>
          <button className="checkout-close-btn" onClick={onClose}>×</button>
        </header>

        <div className="checkout-progress">
          {checkoutSteps.map((item, index) => (
            <span
              key={item.id}
              className={`checkout-progress-bar ${index <= activeStepIndex ? "active" : ""}`}
            ></span>
          ))}
        </div>

        <div className="checkout-stage">
          {step === "contact" ? (
            <div className="checkout-step">
              <h2 className="checkout-title">Контактные данные</h2>
              <div className="checkout-card">
                <div className="checkout-section-link">Ваши данные</div>
                <label className="checkout-field">
                  <input
                    value={draft.contact_first_name}
                    onChange={(event) => onChange("contact_first_name", event.target.value)}
                    placeholder="Имя"
                  />
                </label>
                <label className="checkout-field">
                  <input
                    value={draft.contact_last_name}
                    onChange={(event) => onChange("contact_last_name", event.target.value)}
                    placeholder="Фамилия"
                  />
                </label>
                <label className="checkout-field">
                  <input
                    value={draft.contact_city}
                    onChange={(event) => onChange("contact_city", event.target.value)}
                    placeholder="Город"
                  />
                </label>
                <div className="checkout-phone-row">
                  <span className="checkout-country-pill">🇷🇺</span>
                  <label className="checkout-phone-code">
                    <input
                      value={draft.contact_phone}
                      onChange={(event) => onChange("contact_phone", event.target.value)}
                      placeholder="+7 999 123 45 67"
                    />
                  </label>
                </div>
                <label className="checkout-field">
                  <input
                    value={draft.contact_email}
                    onChange={(event) => onChange("contact_email", event.target.value)}
                    placeholder="Эл. почта"
                  />
                </label>
              </div>

              <div className="checkout-card">
                <div className="checkout-section-link">Комментарий к заказу</div>
                <label className="checkout-field large">
                  <textarea
                    value={draft.order_note}
                    onChange={(event) => onChange("order_note", event.target.value)}
                    placeholder="Комментарий"
                  ></textarea>
                </label>
              </div>

              <p className="checkout-muted">
                Эти данные нужны, чтобы мы могли оформить и доставить ваш заказ.
              </p>
            </div>
          ) : null}

          {step === "delivery" ? (
            <div className="checkout-step checkout-step-map">
              <div className="checkout-mode-switch">
                <button
                  className={`checkout-mode-tab ${draft.delivery_mode === "pickup" ? "active" : ""}`}
                  onClick={() => onChange("delivery_mode", "pickup")}
                >
                  Самовывоз
                </button>
                <button
                  className={`checkout-mode-tab ${draft.delivery_mode === "courier" ? "active" : ""}`}
                  onClick={() => onChange("delivery_mode", "courier")}
                >
                  Курьер
                </button>
              </div>

              <div className="checkout-widget-inline checkout-widget-picker">
                <div className="checkout-widget-hero">
                  <span className="checkout-widget-badge">
                    {draft.delivery_mode === "pickup" ? "СДЭК • ПВЗ" : "СДЭК • КУРЬЕР"}
                  </span>
                  <h3>
                    {draft.delivery_mode === "pickup"
                      ? "Выберите удобный пункт выдачи"
                      : "Выберите адрес и способ доставки"}
                  </h3>
                  <p>
                    Официальный виджет СДЭК откроется поверх экрана и вернет готовый вариант доставки в оформление.
                  </p>
                </div>

                <button
                  className="checkout-widget-launch"
                  onClick={openDeliveryWidget}
                  disabled={widgetLoading || !widgetConfig.configured}
                >
                  {widgetLoading
                    ? "Загружаем виджет..."
                    : draft.delivery_mode === "pickup"
                      ? "Выбрать пункт выдачи СДЭК"
                      : "Выбрать адрес доставки"}
                </button>

                {!deliveryChosen && !widgetError ? (
                  <div className="checkout-widget-hint">
                    После выбора мы автоматически подставим адрес, срок и стоимость на следующий шаг.
                  </div>
                ) : null}

                {widgetError ? <div className="checkout-widget-error">{widgetError}</div> : null}
                {deliveryChosen ? (
                  <div className="checkout-widget-selected">
                    <div className="checkout-widget-selected-top">
                      <strong>{draft.delivery_label}</strong>
                      <span className="checkout-widget-selected-price">{rub(deliveryAmount)}</span>
                    </div>
                    <span>{reviewDeliveryAddress}</span>
                    <div className="checkout-widget-selected-meta">
                      <span className="checkout-widget-selected-pill">
                        {draft.delivery_mode === "pickup" ? "Пункт выдачи" : "Курьер"}
                      </span>
                      {draft.delivery_eta ? (
                        <span className="checkout-widget-selected-pill">{draft.delivery_eta}</span>
                      ) : null}
                    </div>
                  </div>
                ) : null}
              </div>
            </div>
          ) : null}

          {step === "shipping" ? (
            <div className="checkout-step">
              <h2 className="checkout-title">Способ доставки</h2>
              <div className="checkout-card">
                <div className="checkout-section-link">Выбранная доставка</div>
                <div className="checkout-method-row selected static">
                  <span className="checkout-method-radio"></span>
                  <span className="checkout-method-copy">
                    <strong>{draft.delivery_label || "Способ доставки не выбран"}</strong>
                    <small>{draft.delivery_eta || "Срок появится после выбора в виджете"}</small>
                  </span>
                  <span className="checkout-method-price">{rub(deliveryAmount)}</span>
                </div>
                <div className="checkout-shipping-address">
                  {reviewDeliveryAddress || "Откройте предыдущий шаг и выберите ПВЗ или адрес"}
                </div>
                <button className="checkout-secondary-btn" onClick={openDeliveryWidget}>
                  Изменить доставку
                </button>
              </div>
            </div>
          ) : null}

          {step === "payment" ? (
            <div className="checkout-step">
              <h2 className="checkout-title">Оплата</h2>
              <div className="checkout-card">
                <div className="checkout-section-link">Способ оплаты</div>
                <button className="checkout-method-row selected" onClick={() => onChange("payment_method", "manual")}>
                  <span className="checkout-method-radio"></span>
                  <span className="checkout-method-copy">
                    <strong>Подтверждение через менеджера</strong>
                    <small>После оформления мы свяжемся с вами в Telegram и подскажем, как завершить заказ.</small>
                  </span>
                </button>
              </div>
            </div>
          ) : null}

          {step === "review" ? (
            <div className="checkout-step">
              <h2 className="checkout-title">Подтверждение заказа</h2>

              <div className="checkout-card">
                <div className="checkout-section-link">Контактные данные</div>
                <div className="checkout-summary-block">
                  <strong>
                    {draft.contact_first_name} {draft.contact_last_name}
                  </strong>
                  <span>{draft.contact_phone}</span>
                  <span>{draft.contact_email}</span>
                </div>
                <div className="checkout-summary-block top-gap">
                  <strong>Доставка</strong>
                  <span>
                    {draft.delivery_label || (draft.delivery_mode === "pickup" ? "СДЭК" : "Курьер")}: {reviewDeliveryAddress}
                  </span>
                </div>
              </div>

              <div className="checkout-card">
                <div className="checkout-section-link">{draft.delivery_eta || "Доставка"}</div>
                <div className="checkout-review-products">
                  {cartItems.map((item) => {
                    const product = productMap[item.product_id];
                    if (!product) {
                      return null;
                    }
                    return (
                      <div key={item.key} className="checkout-review-thumb">
                        <img src={product.images[0]} alt={product.title} />
                      </div>
                    );
                  })}
                </div>
                <div className="checkout-summary-line">
                  <span>{draft.delivery_label || "Доставка"}</span>
                  <strong>{rub(deliveryAmount)}</strong>
                </div>
              </div>

              <div className="checkout-card">
                <div className="checkout-section-link">Способ оплаты</div>
                <div className="checkout-summary-line plain">
                  <span>Подтверждение через менеджера</span>
                </div>
              </div>

              <div className="checkout-card">
                <div className="checkout-section-link">Комментарий к заказу</div>
                <div className="checkout-note-copy">{draft.order_note || "Без комментария"}</div>
              </div>

              <div className="checkout-card">
                <div className="discount-row dark">
                  <input
                    className="discount-input dark"
                    type="text"
                    placeholder="Промокод"
                    value={couponCode}
                    onChange={(event) => onCouponChange(event.target.value.toUpperCase())}
                  />
                  <button className="discount-apply-btn" onClick={onApplyPromo} disabled={applyingPromo}>
                    {applyingPromo ? "..." : "Применить"}
                  </button>
                </div>
                {promoPreview?.promo_error ? (
                  <div className="discount-note error">{promoPreview.promo_error}</div>
                ) : null}
                {promoPreview?.coupon_applied ? (
                  <div className="discount-note success">
                    Промокод {promoPreview.coupon_code} применен, скидка {rub(discountAmount)}
                  </div>
                ) : null}
                <div className="checkout-summary-line">
                  <span>Товары ({totalItems})</span>
                  <strong>{rub(itemsAmount)}</strong>
                </div>
                <div className="checkout-summary-line">
                  <span>Доставка</span>
                  <strong>{rub(deliveryAmount)}</strong>
                </div>
                {discountAmount > 0 ? (
                  <div className="checkout-summary-line discount">
                    <span>Скидка</span>
                    <strong>-{rub(discountAmount)}</strong>
                  </div>
                ) : null}
                <div className="checkout-summary-line total">
                  <span>Итого</span>
                  <strong>{rub(finalTotal)}</strong>
                </div>
              </div>

              <p className="checkout-legal">
                Нажимая кнопку, вы соглашаетесь на обработку персональных данных
              </p>
            </div>
          ) : null}
        </div>

        <div className="checkout-bottombar">
          {step === "contact" ? (
            <button className="primary-action checkout-flow-btn" onClick={onAdvance}>
              Выбрать способ доставки
            </button>
          ) : null}
          {step === "delivery" ? (
            <button className="primary-action checkout-flow-btn" onClick={onAdvance} disabled={!deliveryChosen}>
              {draft.delivery_mode === "pickup" ? "Выбрать пункт выдачи" : "Продолжить"}
            </button>
          ) : null}
          {step === "shipping" ? (
            <button className="primary-action checkout-flow-btn" onClick={onAdvance}>
              Далее
            </button>
          ) : null}
          {step === "payment" ? (
            <button className="primary-action checkout-flow-btn" onClick={onAdvance}>
              Далее
            </button>
          ) : null}
          {step === "review" ? (
            <button className="primary-action checkout-flow-btn" onClick={onSubmit} disabled={submitting}>
              {submitting ? "Оформляем..." : `Оформить заказ • ${rub(finalTotal)}`}
            </button>
          ) : null}
        </div>
      </section>
    </div>
  );
}

function CartScreen({
  cartItems,
  productMap,
  couponCode,
  promoPreview,
  applyingPromo,
  onCouponChange,
  onApplyPromo,
  onClearCart,
  onIncrement,
  onDecrement,
  onCheckout,
}) {
  if (!cartItems.length) {
    return (
      <div className="empty-state tab-screen">
        <h2>Корзина пока пустая</h2>
        <p>Добавьте товары в корзину, чтобы оформить заказ.</p>
      </div>
    );
  }

  const totalItems = cartItems.reduce((sum, item) => sum + item.quantity, 0);
  const subtotalAmount = cartItems.reduce((sum, item) => {
    const product = productMap[item.product_id];
    return sum + (product ? product.price * item.quantity : 0);
  }, 0);
  const discountAmount = promoPreview?.coupon_applied ? promoPreview.discount_amount || 0 : 0;
  const totalAmount = promoPreview?.coupon_applied
    ? promoPreview.total_amount || Math.max(0, subtotalAmount - discountAmount)
    : subtotalAmount;
  const appliedCouponCode = promoPreview?.coupon_applied ? promoPreview.coupon_code : "";

  return (
    <div className="tab-screen cart-screen">
      <div className="cart-header">
        <h2>Корзина</h2>
        <button className="cart-clear" onClick={onClearCart}>
          Очистить
        </button>
      </div>

      <div className="cart-body">
        <div className="cart-items-stack">
          {cartItems.map((item) => {
            const product = productMap[item.product_id];
            if (!product) {
              return null;
            }
            return (
              <div className="cart-item-card" key={item.key}>
                <div className="cart-line">
                  <div className="cart-thumb">
                    <img className="cart-thumb-image" src={product.images[0]} alt={product.title} />
                  </div>

                  <div>
                    <h3 className="cart-item-title">{product.title}</h3>
                    <div className="cart-size">Размер одежды {item.size || "Единый"}</div>

                    <div className="cart-controls-row">
                      <div className="qty-control">
                        <button className="qty-btn" onClick={() => onDecrement(item)} aria-label="Уменьшить">
                          <Icon id="icon-minus" />
                        </button>
                        <span className="qty-value">{item.quantity}</span>
                        <button className="qty-btn" onClick={() => onIncrement(item)} aria-label="Увеличить">
                          <Icon id="icon-plus" />
                        </button>
                      </div>
                      <div className="cart-item-price">{rub(product.price * item.quantity)}</div>
                    </div>
                  </div>
                </div>
              </div>
            );
          })}
        </div>

        <div className="cart-totals">
          <div className="discount-row">
            <input
              className="discount-input"
              type="text"
              placeholder="Промокод"
              value={couponCode}
              onChange={(event) => onCouponChange(event.target.value.toUpperCase())}
            />
            <button className="discount-apply-btn" onClick={onApplyPromo} disabled={applyingPromo}>
              {applyingPromo ? "..." : "Применить"}
            </button>
          </div>
          {promoPreview?.promo_error ? (
            <div className="discount-note error">{promoPreview.promo_error}</div>
          ) : null}
          {promoPreview?.coupon_applied ? (
            <div className="discount-note success">
              Промокод {appliedCouponCode} применен, скидка {rub(discountAmount)}
            </div>
          ) : null}
          <div className="summary-row">
            <span>Товары ({totalItems})</span>
            <span>{rub(subtotalAmount)}</span>
          </div>
          {discountAmount > 0 ? (
            <div className="summary-row discount">
              <span>Скидка</span>
              <span>-{rub(discountAmount)}</span>
            </div>
          ) : null}
          <div className="summary-row total">
            <span>Итого</span>
            <strong>{rub(totalAmount)}</strong>
          </div>
        </div>
      </div>

      <div className="cart-footer">
        <button className="primary-action checkout-btn" onClick={onCheckout}>
          Перейти к оформлению • {rub(totalAmount)}
        </button>
      </div>
    </div>
  );
}

function ProfileScreen({
  user,
  orders,
  favoritesCount,
  cartCount,
  productMap,
  supportUrl,
  supportUsername,
  onOpenAdmin,
  onResumeOrderPayment,
}) {
  const displayName = getDisplayName(user);
  const username = user?.username ? `@${user.username}` : "не указан";
  const authDate = user?.last_auth_date ? formatOrderDate(user.last_auth_date) : "\u2014";

  return (
    <div className="tab-screen profile-screen">
      <div className="profile-hero">
        <div className="profile-avatar">
          {user?.photo_url ? (
            <img src={user.photo_url} alt={displayName} />
          ) : (
            <div className="profile-avatar-fallback">{getInitials(user)}</div>
          )}
        </div>
        <h2 className="profile-name">{displayName}</h2>
        <div className="profile-history-note">{username}</div>
      </div>

      <section className="profile-card profile-stats-grid">
        <div className="profile-stat">
          <span>Заказы</span>
          <strong>{orders.length}</strong>
        </div>
        <div className="profile-stat">
          <span>Избранное</span>
          <strong>{favoritesCount}</strong>
        </div>
        <div className="profile-stat">
          <span>Товары в корзине</span>
          <strong>{cartCount}</strong>
        </div>
      </section>

      <section className="profile-card">
        <div className="profile-section-title">Профиль</div>
        <div className="profile-detail-row">
          <span>Имя пользователя</span>
          <strong>{username}</strong>
        </div>
        <div className="profile-detail-row">
          <span>Язык</span>
          <strong>{user?.language_code || "ru"}</strong>
        </div>
        <div className="profile-detail-row">
          <span>Последний вход</span>
          <strong>{authDate}</strong>
        </div>
        {supportUsername ? (
          <div className="profile-detail-row">
            <span>Поддержка</span>
            <a className="profile-link" href={supportUrl} target="_blank" rel="noreferrer">
              @{supportUsername}
            </a>
          </div>
        ) : null}
        {user?.is_admin ? (
          <button className="admin-entry-btn" onClick={onOpenAdmin}>
            Открыть админку
          </button>
        ) : null}
      </section>

      <section className="profile-card">
        <div className="profile-section-title">История заказов</div>
        {orders.length ? (
          <div className="profile-orders">
            {orders.map((order) => (
              <article className="order-card" key={order.id}>
                <div className="order-card-top">
                  <div>
                    <div className="order-card-title">Заказ #{order.id}</div>
                    <div className="order-card-meta">{formatOrderDate(order.created_at)}</div>
                  </div>
                  <div className="order-card-total">{rub(order.total_amount)}</div>
                </div>
                <div className="order-card-meta">{getOrderStatusLabel(order.status, order.payment_provider)}</div>
                <div className="order-card-items">
                  {order.items.map((item, index) => {
                    const product = productMap[item.product_id];
                    return (
                      <div className="order-card-line" key={`${order.id}-${item.product_id}-${index}`}>
                        <span>{product?.title || `Товар #${item.product_id}`}</span>
                        <strong>
                          {item.quantity} × {rub(item.unit_price)}
                        </strong>
                      </div>
                    );
                  })}
                </div>
                {order.coupon_code ? <div className="order-card-note">Промокод: {order.coupon_code}</div> : null}
                {order.status !== "paid" && order.payment_provider === "robokassa" ? (
                  <button className="admin-entry-btn" onClick={() => onResumeOrderPayment(order.id)}>
                    Оплатить заказ
                  </button>
                ) : null}
              </article>
            ))}
          </div>
        ) : (
          <div className="profile-empty-note">У вас пока нет заказов. Когда оформите первую покупку, она появится здесь.</div>
        )}
      </section>
    </div>
  );
}

function AdminScreen({
  dashboard,
  loading,
  promoForm,
  productForm,
  editingPromoId,
  editingProductId,
  onPromoFormChange,
  onProductFormChange,
  onSavePromo,
  onEditPromo,
  onResetPromo,
  onSaveProduct,
  onEditProduct,
  onToggleProduct,
  onResetProduct,
  onRefresh,
}) {
  if (loading) {
    return (
      <div className="tab-screen admin-screen">
        <div className="empty-state app-loading">
          <h2>Загружаем данные</h2>
          <p>Еще немного, и все будет готово.</p>
        </div>
      </div>
    );
  }

  return (
    <div className="tab-screen admin-screen">
      <section className="admin-card">
        <div className="admin-header-row">
          <div>
            <h2>Админка</h2>
            <p>Заказы, промокоды и управление товарами</p>
          </div>
          <button className="admin-refresh-btn" onClick={onRefresh}>Обновить</button>
        </div>
      </section>

      <section className="admin-card">
        <div className="admin-section-title">Все заказы</div>
        <div className="admin-orders">
          {dashboard.orders.length ? (
            dashboard.orders.map((order) => (
              <article className="admin-order-card" key={order.id}>
                <div className="admin-order-top">
                  <div>
                    <strong>Заказ #{order.id}</strong>
                    <div className="admin-order-meta">
                      {order.customer.display_name}
                      {order.customer.username ? ` • @${order.customer.username}` : ""}
                    </div>
                  </div>
                  <div className="admin-order-total">{rub(order.total_amount)}</div>
                </div>
                <div className="admin-order-meta">{formatOrderDate(order.created_at)}</div>
                {order.coupon_code ? (
                  <div className="admin-order-meta">
                    Промокод: {order.coupon_code} • скидка {rub(order.discount_amount || 0)}
                  </div>
                ) : null}
                <div className="admin-order-lines">
                  {order.items.map((item, index) => (
                    <div className="admin-order-line" key={`${order.id}-${index}`}>
                      <span>{item.product_title || `Товар #${item.product_id}`}</span>
                      <strong>
                        {item.quantity} × {rub(item.unit_price)} {item.size ? `• ${item.size}` : ""}
                      </strong>
                    </div>
                  ))}
                </div>
              </article>
            ))
          ) : (
            <div className="profile-empty-note">Заказов пока нет.</div>
          )}
        </div>
      </section>

      <section className="admin-card">
        <div className="admin-section-title">Промокоды</div>
        <div className="admin-form-grid">
          <label>
            <span>Код</span>
            <input value={promoForm.code} onChange={(e) => onPromoFormChange("code", e.target.value.toUpperCase())} />
          </label>
          <label>
            <span>Тип</span>
            <select value={promoForm.discount_type} onChange={(e) => onPromoFormChange("discount_type", e.target.value)}>
              <option value="percent">процент</option>
              <option value="fixed">фиксированная</option>
            </select>
          </label>
          <label>
            <span>Значение</span>
            <input type="number" min="1" value={promoForm.amount} onChange={(e) => onPromoFormChange("amount", e.target.value)} />
          </label>
          <label>
            <span>Лимит использований</span>
            <input type="number" min="1" value={promoForm.usage_limit} onChange={(e) => onPromoFormChange("usage_limit", e.target.value)} />
          </label>
          <label className="admin-form-full">
            <span>Описание</span>
            <input value={promoForm.description} onChange={(e) => onPromoFormChange("description", e.target.value)} />
          </label>
          <label className="admin-checkbox">
            <input type="checkbox" checked={promoForm.is_active} onChange={(e) => onPromoFormChange("is_active", e.target.checked)} />
            <span>Активен</span>
          </label>
        </div>
        <div className="admin-actions-row">
          <button className="admin-primary-btn" onClick={onSavePromo}>
            {editingPromoId ? "Сохранить промокод" : "Создать промокод"}
          </button>
          {editingPromoId ? (
            <button className="admin-secondary-btn" onClick={onResetPromo}>
              Отмена
            </button>
          ) : null}
        </div>
        <div className="admin-list">
          {dashboard.promoCodes.map((promo) => (
            <div className="admin-list-card" key={promo.id}>
              <div>
                <strong>{promo.code}</strong>
                <div className="admin-order-meta">
                  {promo.discount_type === "percent" ? "процент" : "фикс"} • {promo.amount}
                  {promo.usage_limit ? ` • ${promo.uses_count}/${promo.usage_limit}` : ` • использован ${promo.uses_count} раз`}
                </div>
              </div>
              <div className="admin-inline-actions">
                <span className={`admin-status ${promo.is_active ? "active" : "hidden"}`}>
                  {promo.is_active ? "активен" : "выключен"}
                </span>
                <button className="admin-link-btn" onClick={() => onEditPromo(promo)}>
                  Изменить
                </button>
              </div>
            </div>
          ))}
        </div>
      </section>

      <section className="admin-card">
        <div className="admin-section-title">Товары</div>
        <div className="admin-form-grid">
          <label className="admin-form-full">
            <span>Название</span>
            <input value={productForm.title} onChange={(e) => onProductFormChange("title", e.target.value)} />
          </label>
          <label>
            <span>Цена</span>
            <input type="number" min="1" value={productForm.price} onChange={(e) => onProductFormChange("price", e.target.value)} />
          </label>
          <label>
            <span>Категория</span>
            <input value={productForm.category} onChange={(e) => onProductFormChange("category", e.target.value)} />
          </label>
          <label>
            <span>Порядок сортировки</span>
            <input type="number" value={productForm.sort_order} onChange={(e) => onProductFormChange("sort_order", e.target.value)} />
          </label>
          <label className="admin-checkbox">
            <input type="checkbox" checked={productForm.is_active} onChange={(e) => onProductFormChange("is_active", e.target.checked)} />
            <span>Показывать в каталоге</span>
          </label>
          <label className="admin-form-full">
            <span>Изображения, по одному в строке</span>
            <textarea value={productForm.imagesText} onChange={(e) => onProductFormChange("imagesText", e.target.value)} />
          </label>
          <label className="admin-form-full">
            <span>Размеры, по одному в строке</span>
            <textarea value={productForm.sizesText} onChange={(e) => onProductFormChange("sizesText", e.target.value)} />
          </label>
          <label className="admin-form-full">
            <span>Описание, по одной строке</span>
            <textarea value={productForm.descriptionText} onChange={(e) => onProductFormChange("descriptionText", e.target.value)} />
          </label>
        </div>
        <div className="admin-actions-row">
          <button className="admin-primary-btn" onClick={onSaveProduct}>
            {editingProductId ? "Сохранить товар" : "Создать товар"}
          </button>
          {editingProductId ? (
            <button className="admin-secondary-btn" onClick={onResetProduct}>
              Отмена
            </button>
          ) : null}
        </div>
        <div className="admin-list">
          {dashboard.products.map((product) => (
            <div className="admin-list-card" key={product.id}>
              <div>
                <strong>{product.title}</strong>
                <div className="admin-order-meta">
                  {rub(product.price)} • {product.category} • #{product.sort_order}
                </div>
              </div>
              <div className="admin-inline-actions">
                <span className={`admin-status ${product.is_active ? "active" : "hidden"}`}>
                  {product.is_active ? "виден" : "скрыт"}
                </span>
                <button className="admin-link-btn" onClick={() => onEditProduct(product)}>
                  Изменить
                </button>
                <button className="admin-link-btn" onClick={() => onToggleProduct(product)}>
                  {product.is_active ? "Скрыть" : "Показать"}
                </button>
              </div>
            </div>
          ))}
        </div>
      </section>
    </div>
  );
}

function CategorySheet({ categories, activeCategory, onSelect, onClose }) {
  return (
    <>
      <div className="sheet-backdrop" onClick={onClose}></div>
      <section className="category-sheet">
        <div className="sheet-handle"></div>
        <div className="sheet-title">Категории</div>
        <div className="category-sheet-grid">
          {categories.map((category) => (
            <button
              key={category}
              className={`category-option ${activeCategory === category ? "active" : ""}`}
              onClick={() => onSelect(category)}
            >
              <span>{category === "ALL" ? "ВСЕ" : category}</span>
              {activeCategory === category ? <span>Выбрано</span> : null}
            </button>
          ))}
        </div>
      </section>
    </>
  );
}

function ProductModal({
  product,
  slideIndex,
  selectedSize,
  isFavorite,
  quantity,
  hasSupport,
  onClose,
  onPrevSlide,
  onNextSlide,
  onToggleFavorite,
  onSelectSize,
  onQtyMinus,
  onQtyPlus,
  onGoToCart,
  onShare,
  onShowSizeChart,
  onContactSeller,
}) {
  if (!product) {
    return null;
  }

  const imageSrc = product.images[slideIndex];
  const imageFitClass = slideIndex === product.images.length - 1 ? "contain" : "";

  return (
    <>
      <div className="sheet-backdrop" onClick={onClose}></div>
      <section className="product-sheet" aria-live="polite">
        <div className="product-view">
          <div className="product-view-topbar">
            <button className="product-close-btn" onClick={onClose} aria-label="Закрыть просмотр">
              <Icon id="icon-close" />
            </button>
          </div>

          <section className="product-view-media">
            <div className="product-view-progress">
              {product.images.map((_, index) => (
                <span key={index} className={`product-view-progress-bar ${index === slideIndex ? "active" : ""}`}></span>
              ))}
            </div>

            <div className="product-view-fabs">
              <button
                className={`product-view-fab ${isFavorite ? "active" : ""}`}
                onClick={() => onToggleFavorite(product.id)}
                aria-label="В избранное"
              >
                <Icon id={isFavorite ? "icon-heart-fill" : "icon-heart-outline"} />
              </button>
              <button className="product-view-fab" onClick={onShare} aria-label="Поделиться">
                <Icon id="icon-share" />
              </button>
            </div>

            <div className="product-view-image-shell">
              <button className="product-view-hotspot prev" onClick={onPrevSlide} aria-label="Предыдущее фото"></button>
              <img className={`sheet-product-image ${imageFitClass}`} src={imageSrc} alt={product.title} />
              <button className="product-view-hotspot next" onClick={onNextSlide} aria-label="Следующее фото"></button>
            </div>
          </section>

          <section className="product-view-section size">
            <div className="product-view-section-label">
              Размер одежды: <strong>{selectedSize}</strong>
            </div>
            <div className="size-row product-view-sizes">
              {product.sizes.map((size) => (
                <button
                  key={size}
                  className={`size-chip ${size === selectedSize ? "active" : ""}`}
                  onClick={() => onSelectSize(size)}
                >
                  {size}
                </button>
              ))}
            </div>
          </section>

          <section className="product-view-section details">
            <h2 className="product-view-title">{product.title}</h2>
            <div className="product-view-price">{rub(product.price)}</div>
            <div className="product-view-subtitle">Описание</div>
            <div className="product-view-copy">
              {product.description.map((line) => (
                <p key={line}>{line}</p>
              ))}
            </div>
            <button className="product-view-readmore" onClick={onShowSizeChart}>
              Размерная сетка
              <Icon id="icon-chevron" />
            </button>
          </section>

          <section className="product-view-section support">
            <div className="product-view-subtitle">Остались вопросы?</div>
            <button
              className="product-view-contact"
              onClick={onContactSeller}
              disabled={!hasSupport}
            >
              Связаться с нами
            </button>
          </section>
        </div>
      </section>

      <div className="product-view-bottom">
        <div className="qty-control product-view-qty">
          <button className="qty-btn" onClick={onQtyMinus} aria-label="Уменьшить">
            <Icon id="icon-minus" />
          </button>
          <span className="qty-value">{quantity}</span>
          <button className="qty-btn" onClick={onQtyPlus} aria-label="Увеличить">
            <Icon id="icon-plus" />
          </button>
        </div>

        <button className="primary-action product-view-cart-btn" onClick={onGoToCart}>
          В корзину
        </button>
      </div>
    </>
  );
}

function Toast({ message }) {
  if (!message) {
    return null;
  }
  return <div className="toast">{message}</div>;
}

function App() {
  const [viewer, setViewer] = useState(null);
  const [products, setProducts] = useState([]);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState("");
  const [activeTab, setActiveTab] = useState("home");
  const [activeCategory, setActiveCategory] = useState("ALL");
  const [favorites, setFavorites] = useState([]);
  const [cartItems, setCartItems] = useState([]);
  const [cartIndex, setCartIndex] = useState({});
  const [orders, setOrders] = useState([]);
  const [searchOpen, setSearchOpen] = useState(false);
  const [searchQuery, setSearchQuery] = useState("");
  const [sortMode, setSortMode] = useState("featured");
  const [activeProductId, setActiveProductId] = useState(null);
  const [selectedSize, setSelectedSize] = useState({});
  const [draftQuantities, setDraftQuantities] = useState({});
  const [couponCode, setCouponCode] = useState("");
  const [promoPreview, setPromoPreview] = useState(null);
  const [applyingPromo, setApplyingPromo] = useState(false);
  const [productSlides, setProductSlides] = useState({});
  const [categorySheetOpen, setCategorySheetOpen] = useState(false);
  const [toast, setToast] = useState("");
  const [supportUrl, setSupportUrl] = useState(null);
  const [supportUsername, setSupportUsername] = useState(null);
  const [checkoutOpen, setCheckoutOpen] = useState(false);
  const [checkoutStep, setCheckoutStep] = useState("contact");
  const [checkoutOptions, setCheckoutOptions] = useState(null);
  const [checkoutLoading, setCheckoutLoading] = useState(false);
  const [checkoutSubmitting, setCheckoutSubmitting] = useState(false);
  const [checkoutDraft, setCheckoutDraft] = useState({
    contact_first_name: "",
    contact_last_name: "",
    contact_phone: "",
    contact_email: "",
    contact_city: "Москва",
    order_note: "",
    delivery_mode: "pickup",
    delivery_code: "",
    delivery_point_label: "",
    delivery_method_id: "",
    delivery_label: "",
    delivery_address: "",
    delivery_city_code: "",
    delivery_office_code: "",
    delivery_eta: "",
    delivery_amount: 0,
    payment_method: "manual",
  });
  const [adminDashboard, setAdminDashboard] = useState({
    orders: [],
    promoCodes: [],
    products: [],
  });
  const [adminLoading, setAdminLoading] = useState(false);
  const [promoForm, setPromoForm] = useState(emptyPromoForm);
  const [productForm, setProductForm] = useState(emptyProductForm);
  const [editingPromoId, setEditingPromoId] = useState(null);
  const [editingProductId, setEditingProductId] = useState(null);

  const favoritesSet = useMemo(() => new Set(favorites), [favorites]);
  const productMap = useMemo(
    () => Object.fromEntries(products.map((product) => [product.id, product])),
    [products]
  );
  const cartCount = useMemo(
    () => cartItems.reduce((sum, entry) => sum + entry.quantity, 0),
    [cartItems]
  );
  const categories = useMemo(
    () => ["ALL", ...new Set(products.map((product) => product.category))],
    [products]
  );
  const activeProduct = useMemo(
    () => products.find((product) => product.id === activeProductId) || null,
    [activeProductId, products]
  );

  function showToast(message) {
    setToast(message);
  }

  function applyState(payload) {
    const next = normalizeState(payload);
    setViewer((prev) => next.user || prev);
    setFavorites(next.favorites);
    setCartItems(next.cartItems);
    setCartIndex(next.cartIndex);
    setOrders(next.orders);
    setSupportUrl(next.supportUrl);
    setSupportUsername(next.supportUsername);
  }

  function resetPromoPreview() {
    setPromoPreview(null);
  }

  function handleCouponChange(value) {
    setCouponCode(value);
    resetPromoPreview();
  }

  function getCartItem(productId, size = "") {
    return cartIndex[makeCartKey(productId, size || "")] || null;
  }

  function getDefaultSize(productId) {
    const product = productMap[productId];
    const existingSize = cartItems.find((item) => item.product_id === productId)?.size;
    return (
      selectedSize[productId] ||
      existingSize ||
      product?.sizes[1] ||
      product?.sizes[0] ||
      "M"
    );
  }

  function getDraftQuantity(productId, size) {
    const key = makeCartKey(productId, size || "");
    return draftQuantities[key] || getCartItem(productId, size)?.quantity || 1;
  }

  function buildCheckoutDraft(payload) {
    const contactDefaults = payload?.contact_defaults || {};
    return {
      contact_first_name: contactDefaults.first_name || viewer?.first_name || "",
      contact_last_name: contactDefaults.last_name || viewer?.last_name || "",
      contact_phone: contactDefaults.phone || "",
      contact_email: contactDefaults.email || "",
      contact_city: contactDefaults.city || "Москва",
      order_note: contactDefaults.note || "",
      delivery_mode: "pickup",
      delivery_code: "",
      delivery_point_label: "",
      delivery_method_id: "",
      delivery_label: "",
      delivery_address: "",
      delivery_city_code: "",
      delivery_office_code: "",
      delivery_eta: "",
      delivery_amount: 0,
      payment_method: "manual",
    };
  }

  async function loadAdminDashboard() {
    setAdminLoading(true);
    try {
      const payload = await apiRequest("/admin/dashboard");
      setAdminDashboard({
        orders: payload.orders || [],
        promoCodes: payload.promo_codes || [],
        products: payload.products || [],
      });
    } catch (err) {
      showToast(err.message || "Не удалось загрузить админку");
    } finally {
      setAdminLoading(false);
    }
  }

  async function authenticate() {
    const existingToken = getStoredToken();

    if (existingToken) {
      try {
        const session = await apiRequest("/me");
        setViewer(session.user || null);
        setSupportUrl(session.support_url || null);
        setSupportUsername(session.support_username || null);
        return;
      } catch (err) {
        clearStoredToken();
      }
    }

    const initData = getTelegramInitData();
    if (initData) {
      try {
        const authPayload = await apiRequest("/auth/telegram", {
          method: "POST",
          body: JSON.stringify({ init_data: initData }),
          skipAuth: true,
        });
        setStoredToken(authPayload.token);
        setViewer(authPayload.user || null);
        setSupportUrl(authPayload.support_url || null);
        setSupportUsername(authPayload.support_username || null);
        return;
      } catch (err) {
        const message = err?.message || "";
        if (!isLocalPreview()) {
          throw err;
        }

        console.warn("Telegram auth failed in local preview, falling back to dev auth.", message);
      }
    }

    if (!isLocalPreview()) {
      throw new Error("Откройте миниапп внутри Telegram, чтобы пройти авторизацию");
    }

    const devPayload = await apiRequest("/auth/dev", {
      method: "POST",
      body: JSON.stringify({ display_name: "Локальный тест" }),
      skipAuth: true,
    });
    setStoredToken(devPayload.token);
    setViewer(devPayload.user || null);
    setSupportUrl(devPayload.support_url || null);
    setSupportUsername(devPayload.support_username || null);
  }

  async function syncState() {
    const payload = await apiRequest("/state");
    applyState(payload);
  }

  async function openCheckoutFlow() {
    try {
      setCheckoutLoading(true);
      const payload = await apiRequest("/checkout/options");
      setCheckoutOptions(payload);
      setCheckoutDraft((prev) => {
        const next = buildCheckoutDraft(payload);
        return prev.contact_first_name ? { ...next, ...prev } : next;
      });
      setCheckoutStep("contact");
      setCheckoutOpen(true);
    } catch (err) {
      showToast(err.message || "Не удалось открыть оформление заказа");
    } finally {
      setCheckoutLoading(false);
    }
  }

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

    async function bootstrap() {
      try {
        setLoading(true);
        await authenticate();
        const [productsPayload, statePayload] = await Promise.all([
          apiRequest("/products"),
          apiRequest("/state"),
        ]);

        if (cancelled) {
          return;
        }

        setProducts(productsPayload.products || []);
        applyState(statePayload);
        setError("");
      } catch (err) {
        if (!cancelled) {
          setError(err.message || "Не удалось загрузить данные");
        }
      } finally {
        if (!cancelled) {
          setLoading(false);
        }
      }
    }

    bootstrap();

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

  useEffect(() => {
    const webApp = window.Telegram?.WebApp;
    if (!webApp) {
      return;
    }

    webApp.ready();
    webApp.expand();

    try {
      webApp.setHeaderColor("#eceef3");
      webApp.setBackgroundColor("#eceef3");
    } catch (err) {
      console.warn("Telegram WebApp styling is not available in this client.", err);
    }
  }, []);

  useEffect(() => {
    if (!toast) {
      return undefined;
    }
    const id = window.setTimeout(() => setToast(""), 1800);
    return () => window.clearTimeout(id);
  }, [toast]);

  useEffect(() => {
    const params = new URLSearchParams(window.location.search);
    const paymentStatus = params.get("payment");
    if (!paymentStatus) {
      return;
    }

    if (paymentStatus === "success") {
      showToast("Оплата прошла успешно");
      setActiveTab("profile");
    } else if (paymentStatus === "failed") {
      showToast("Оплата не была завершена");
      setActiveTab("profile");
    }

    const nextUrl = `${window.location.pathname}${window.location.hash || ""}`;
    window.history.replaceState({}, "", nextUrl);
  }, []);

  useEffect(() => {
    const onKeyDown = (event) => {
      if (event.key === "Escape") {
        setActiveProductId(null);
        setCategorySheetOpen(false);
        setCheckoutOpen(false);
      }
    };
    window.addEventListener("keydown", onKeyDown);
    return () => window.removeEventListener("keydown", onKeyDown);
  }, []);

  const visibleProducts = useMemo(() => {
    let list = [...products];

    if (activeTab === "favorites") {
      list = list.filter((product) => favoritesSet.has(product.id));
    }

    if (activeTab === "home" && activeCategory !== "ALL") {
      list = list.filter((product) => product.category === activeCategory);
    }

    if (searchQuery.trim()) {
      const query = searchQuery.trim().toLowerCase();
      list = list.filter(
        (product) =>
          product.title.toLowerCase().includes(query) ||
          product.category.toLowerCase().includes(query)
      );
    }

    if (sortMode === "priceAsc") {
      list.sort((a, b) => a.price - b.price);
    }

    if (sortMode === "priceDesc") {
      list.sort((a, b) => b.price - a.price);
    }

    return list;
  }, [activeTab, activeCategory, favoritesSet, products, searchQuery, sortMode]);

  function cycleSort() {
    const currentIndex = sortModes.findIndex((mode) => mode.id === sortMode);
    const nextMode = sortModes[(currentIndex + 1) % sortModes.length];
    setSortMode(nextMode.id);
    showToast(nextMode.label);
  }

  async function toggleFavorite(productId) {
    const favorite = !favoritesSet.has(productId);
    try {
      const payload = await apiRequest("/favorites", {
        method: "PUT",
        body: JSON.stringify({ product_id: productId, favorite }),
      });
      applyState(payload);
      showToast(favorite ? "Добавили в избранное" : "Убрали из избранного");
    } catch (err) {
      showToast(err.message || "Не удалось обновить избранное");
    }
  }

  async function saveCartItem(productId, quantity, size) {
    try {
      const payload = await apiRequest("/cart/items", {
        method: "PUT",
        body: JSON.stringify({
          product_id: productId,
          quantity,
          size,
        }),
      });
      applyState(payload);
      resetPromoPreview();
      return true;
    } catch (err) {
      showToast(err.message || "Не удалось обновить корзину");
      return false;
    }
  }

  async function goToCartFromProduct(productId, quantity, size) {
    const updated = await saveCartItem(productId, quantity, size || getDefaultSize(productId));
    if (!updated) {
      return;
    }
    setActiveProductId(null);
    setActiveTab("cart");
  }

  function openProduct(productId) {
    setActiveProductId(productId);
    setCategorySheetOpen(false);
  }

  function closeProduct() {
    setActiveProductId(null);
  }

  function closeCheckout() {
    setCheckoutOpen(false);
    setCheckoutStep("contact");
  }

  function nextSlide(productId, direction) {
    const product = productMap[productId];
    if (!product) {
      return;
    }

    setProductSlides((prev) => ({
      ...prev,
      [productId]: ((prev[productId] || 0) + direction + product.images.length) % product.images.length,
    }));
  }

  function switchTab(tab) {
    setActiveProductId(null);
    setCategorySheetOpen(false);
    setCheckoutOpen(false);
    setActiveTab(tab);
    if (tab !== "home") {
      setActiveCategory("ALL");
      setSearchOpen(false);
    }
    if (tab === "admin" && viewer?.is_admin) {
      loadAdminDashboard();
    }
  }

  async function clearCart() {
    try {
      const payload = await apiRequest("/cart", {
        method: "DELETE",
      });
      applyState(payload);
      setCouponCode("");
      resetPromoPreview();
      showToast("Корзина очищена");
    } catch (err) {
      showToast(err.message || "Не удалось очистить корзину");
    }
  }

  async function applyPromoCode() {
    const normalizedCode = couponCode.trim().toUpperCase();
    setCouponCode(normalizedCode);

    if (!normalizedCode) {
      resetPromoPreview();
      showToast("Введите промокод");
      return;
    }

    try {
      setApplyingPromo(true);
      const payload = await apiRequest("/cart/promo-preview", {
        method: "POST",
        body: JSON.stringify({
          coupon_code: normalizedCode,
        }),
      });
      setPromoPreview(payload);
      if (payload.coupon_applied) {
        showToast("Промокод применен");
      } else if (payload.promo_error) {
        showToast(payload.promo_error);
      }
    } catch (err) {
      setPromoPreview({
        coupon_code: normalizedCode,
        coupon_applied: false,
        promo_error: err.message || "Не удалось проверить промокод",
      });
      showToast(err.message || "Не удалось проверить промокод");
    } finally {
      setApplyingPromo(false);
    }
  }

  async function checkout() {
    await openCheckoutFlow();
  }

  function updateCheckoutDraft(field, value) {
    setCheckoutDraft((prev) => {
      const next = { ...prev, [field]: value };

      if (field === "delivery_mode") {
        next.delivery_code = "";
        next.delivery_point_label = "";
        next.delivery_method_id = "";
        next.delivery_label = "";
        next.delivery_address = "";
        next.delivery_city_code = "";
        next.delivery_office_code = "";
        next.delivery_eta = "";
        next.delivery_amount = 0;
      }

      return next;
    });
  }

  function applyWidgetDeliverySelection(selection) {
    setCheckoutDraft((prev) => ({
      ...prev,
      ...selection,
    }));
  }

  function validateCheckoutStep(stepId) {
    if (stepId === "contact") {
      if (
        !checkoutDraft.contact_first_name.trim() ||
        !checkoutDraft.contact_last_name.trim() ||
        !checkoutDraft.contact_phone.trim() ||
        !checkoutDraft.contact_email.trim() ||
        !checkoutDraft.contact_city.trim()
      ) {
        showToast("Заполните контактные данные");
        return false;
      }
    }

    if (stepId === "delivery") {
      if (!checkoutDraft.delivery_code || !checkoutDraft.delivery_method_id || !checkoutDraft.delivery_address) {
        showToast("Выберите доставку через виджет СДЭК");
        return false;
      }
    }

    return true;
  }

  function advanceCheckoutStep() {
    if (!validateCheckoutStep(checkoutStep)) {
      return;
    }

    const currentIndex = checkoutSteps.findIndex((item) => item.id === checkoutStep);
    const nextStep = checkoutSteps[currentIndex + 1];
    if (nextStep) {
      setCheckoutStep(nextStep.id);
    }
  }

  function backCheckoutStep() {
    if (checkoutStep === "contact") {
      closeCheckout();
      return;
    }
    const currentIndex = checkoutSteps.findIndex((item) => item.id === checkoutStep);
    const prevStep = checkoutSteps[currentIndex - 1];
    if (prevStep) {
      setCheckoutStep(prevStep.id);
    }
  }

  async function submitCheckout() {
    const normalizedCoupon = couponCode.trim().toUpperCase();
    if (normalizedCoupon && !promoPreview?.coupon_applied) {
      showToast("Сначала примените промокод");
      return;
    }

    try {
      setCheckoutSubmitting(true);
      const payload = await apiRequest("/orders/checkout", {
        method: "POST",
        body: JSON.stringify({
          coupon_code: promoPreview?.coupon_applied ? normalizedCoupon : null,
          contact_first_name: checkoutDraft.contact_first_name.trim(),
          contact_last_name: checkoutDraft.contact_last_name.trim(),
          contact_phone: checkoutDraft.contact_phone.trim(),
          contact_email: checkoutDraft.contact_email.trim(),
          contact_city: checkoutDraft.contact_city.trim(),
          order_note: checkoutDraft.order_note.trim(),
          delivery_mode: checkoutDraft.delivery_mode,
          delivery_code: checkoutDraft.delivery_code,
          delivery_method_id: checkoutDraft.delivery_method_id,
          delivery_label: checkoutDraft.delivery_label,
          delivery_address: checkoutDraft.delivery_address,
          delivery_eta: checkoutDraft.delivery_eta || null,
          delivery_amount: checkoutDraft.delivery_amount || 0,
          payment_method: "manual",
        }),
      });
      applyState(payload.state);
      setCouponCode("");
      resetPromoPreview();
      setCheckoutOpen(false);
      setActiveTab("profile");
      if (payload.manual_checkout) {
        showToast("Заказ оформлен. Мы уже получили уведомление и скоро свяжемся с вами.");
        return;
      }
      const redirectUrl = payload.payment?.redirect_url;
      if (!redirectUrl) {
        throw new Error("Не удалось подготовить следующий шаг оформления");
      }
      window.location.href = redirectUrl;
    } catch (err) {
      showToast(err.message || "Не удалось оформить заказ");
    } finally {
      setCheckoutSubmitting(false);
    }
  }

  async function resumeOrderPayment(orderId) {
    try {
      const payload = await apiRequest(`/orders/${orderId}/pay`, {
        method: "POST",
      });
      const redirectUrl = payload.payment?.redirect_url;
      if (!redirectUrl) {
        throw new Error("Не удалось подготовить ссылку на оплату");
      }
      window.location.href = redirectUrl;
    } catch (err) {
      showToast(err.message || "Не удалось открыть оплату");
    }
  }

  async function handleShare() {
    if (!activeProduct) {
      return;
    }

    const shareText = `${activeProduct.title} • ${rub(activeProduct.price)}`;

    try {
      if (navigator.share) {
        await navigator.share({
          title: activeProduct.title,
          text: shareText,
        });
      } else {
        await copyText(shareText);
        showToast("Название товара скопировано");
        return;
      }
    } catch (err) {
      return;
    }

    showToast("Поделились товаром");
  }

  function openSupport() {
    if (!supportUrl) {
      showToast("Добавьте SHOP_SUPPORT_USERNAME на сервере");
      return;
    }

    const webApp = window.Telegram?.WebApp;
    if (webApp?.openTelegramLink) {
      webApp.openTelegramLink(supportUrl);
      return;
    }

    window.open(supportUrl, "_blank", "noopener,noreferrer");
  }

  function updatePromoForm(field, value) {
    setPromoForm((prev) => ({ ...prev, [field]: value }));
  }

  function resetPromoForm() {
    setPromoForm(emptyPromoForm);
    setEditingPromoId(null);
  }

  function editPromo(promo) {
    setEditingPromoId(promo.id);
    setPromoForm({
      code: promo.code,
      discount_type: promo.discount_type,
      amount: String(promo.amount),
      description: promo.description || "",
      usage_limit: promo.usage_limit ? String(promo.usage_limit) : "",
      is_active: promo.is_active,
    });
    setActiveTab("admin");
  }

  async function savePromo() {
    try {
      const payload = {
        code: promoForm.code.trim(),
        discount_type: promoForm.discount_type,
        amount: Number(promoForm.amount),
        description: promoForm.description.trim() || null,
        usage_limit: promoForm.usage_limit ? Number(promoForm.usage_limit) : null,
        is_active: promoForm.is_active,
      };
      if (!payload.code || !payload.amount) {
        showToast("Заполните промокод и размер скидки");
        return;
      }
      const path = editingPromoId ? `/admin/promo-codes/${editingPromoId}` : "/admin/promo-codes";
      const method = editingPromoId ? "PUT" : "POST";
      const response = await apiRequest(path, {
        method,
        body: JSON.stringify(payload),
      });
      setAdminDashboard((prev) => ({ ...prev, promoCodes: response.promo_codes || [] }));
      resetPromoForm();
      showToast(editingPromoId ? "Промокод обновлен" : "Промокод создан");
    } catch (err) {
      showToast(err.message || "Не удалось сохранить промокод");
    }
  }

  function updateProductForm(field, value) {
    setProductForm((prev) => ({ ...prev, [field]: value }));
  }

  function resetProductForm() {
    setProductForm(emptyProductForm);
    setEditingProductId(null);
  }

  function editProduct(product) {
    setEditingProductId(product.id);
    setProductForm({
      title: product.title,
      price: String(product.price),
      category: product.category,
      sort_order: String(product.sort_order || 0),
      is_active: Boolean(product.is_active),
      imagesText: (product.images || []).join("\n"),
      sizesText: (product.sizes || []).join("\n"),
      descriptionText: (product.description || []).join("\n"),
    });
    setActiveTab("admin");
  }

  async function saveProduct() {
    try {
      const payload = {
        title: productForm.title.trim(),
        price: Number(productForm.price),
        category: productForm.category.trim(),
        sort_order: Number(productForm.sort_order || 0),
        is_active: productForm.is_active,
        images: productForm.imagesText.split("\n").map((item) => item.trim()).filter(Boolean),
        sizes: productForm.sizesText.split("\n").map((item) => item.trim()).filter(Boolean),
        description: productForm.descriptionText.split("\n").map((item) => item.trim()).filter(Boolean),
      };
      if (!payload.title || !payload.category || !payload.price) {
        showToast("Заполните title, price и category");
        return;
      }
      const path = editingProductId ? `/admin/products/${editingProductId}` : "/admin/products";
      const method = editingProductId ? "PUT" : "POST";
      const response = await apiRequest(path, {
        method,
        body: JSON.stringify(payload),
      });
      const nextProducts = response.products || [];
      setAdminDashboard((prev) => ({ ...prev, products: nextProducts }));
      setProducts(nextProducts.filter((item) => item.is_active));
      resetProductForm();
      showToast(editingProductId ? "Товар обновлен" : "Товар создан");
    } catch (err) {
      showToast(err.message || "Не удалось сохранить товар");
    }
  }

  async function toggleProduct(product) {
    try {
      const response = await apiRequest(`/admin/products/${product.id}`, {
        method: "PUT",
        body: JSON.stringify({
          title: product.title,
          price: product.price,
          category: product.category,
          sort_order: product.sort_order || 0,
          is_active: !product.is_active,
          images: product.images || [],
          sizes: product.sizes || [],
          description: product.description || [],
        }),
      });
      const nextProducts = response.products || [];
      setAdminDashboard((prev) => ({ ...prev, products: nextProducts }));
      setProducts(nextProducts.filter((item) => item.is_active));
      showToast(product.is_active ? "Товар скрыт" : "Товар снова видим");
    } catch (err) {
      showToast(err.message || "Не удалось изменить видимость товара");
    }
  }

  const categoryButtons = categories
    .filter((category) => category !== "ALL")
    .map((category) => (
      <button
        key={category}
        className={`chip chip-filter ${activeCategory === category ? "active" : ""}`}
        onClick={() => {
          setActiveCategory(category);
          setActiveTab("home");
        }}
      >
        {category}
      </button>
    ));

  const currentProductSize = activeProduct ? getDefaultSize(activeProduct.id) : "";
  const currentProductQty = activeProduct ? Math.max(1, getDraftQuantity(activeProduct.id, currentProductSize)) : 1;

  return (
    <div className="page-shell">
      <div className="device-frame">
        <div className="miniapp">
          {activeTab === "home" ? (
            <CatalogHeader
              activeCategory={activeCategory}
              searchOpen={searchOpen}
              searchQuery={searchQuery}
              onSearchToggle={() => setSearchOpen((prev) => !prev)}
              onSearchChange={setSearchQuery}
              onOpenCategories={() => setCategorySheetOpen(true)}
              onCycleSort={cycleSort}
              onOpenProfile={() => switchTab("profile")}
              categoryButtons={categoryButtons}
            />
          ) : null}

          <main className="content-area">
            <section className="products-grid">
              {loading ? (
                <div className="empty-state tab-screen app-loading">
                  <h2>Открываем магазин</h2>
                  <p>Еще чуть-чуть, загружаем каталог и ваш профиль.</p>
                </div>
              ) : null}

              {!loading && error ? (
                <div className="empty-state tab-screen app-loading">
                  <h2>Не удалось подключиться</h2>
                  <p>{error}</p>
                  <button
                    className="primary-action"
                    onClick={async () => {
                      setError("");
                      setLoading(true);
                      try {
                        await authenticate();
                        const [productsPayload, statePayload] = await Promise.all([
                          apiRequest("/products"),
                          apiRequest("/state"),
                        ]);
                        setProducts(productsPayload.products || []);
                        applyState(statePayload);
                      } catch (err) {
                        setError(err.message || "Не удалось загрузить данные");
                      } finally {
                        setLoading(false);
                      }
                    }}
                  >
                    Попробовать снова
                  </button>
                </div>
              ) : null}

              {!loading && !error && activeTab === "favorites" && !visibleProducts.length ? (
                <FavoritesEmpty onBackToShop={() => switchTab("home")} />
              ) : null}

              {!loading && !error && activeTab === "cart" ? (
                <CartScreen
                  cartItems={cartItems}
                  productMap={productMap}
                  couponCode={couponCode}
                  promoPreview={promoPreview}
                  applyingPromo={applyingPromo}
                  onCouponChange={handleCouponChange}
                  onApplyPromo={applyPromoCode}
                  onClearCart={clearCart}
                  onIncrement={(item) => saveCartItem(item.product_id, item.quantity + 1, item.size)}
                  onDecrement={(item) => saveCartItem(item.product_id, Math.max(0, item.quantity - 1), item.size)}
                  onCheckout={checkout}
                />
              ) : null}

              {!loading && !error && activeTab === "profile" ? (
                <ProfileScreen
                  user={viewer}
                  orders={orders}
                  favoritesCount={favorites.length}
                  cartCount={cartCount}
                  productMap={productMap}
                  supportUrl={supportUrl}
                  supportUsername={supportUsername}
                  onOpenAdmin={() => switchTab("admin")}
                  onResumeOrderPayment={resumeOrderPayment}
                />
              ) : null}

              {!loading && !error && activeTab === "admin" && viewer?.is_admin ? (
                <AdminScreen
                  dashboard={adminDashboard}
                  loading={adminLoading}
                  promoForm={promoForm}
                  productForm={productForm}
                  editingPromoId={editingPromoId}
                  editingProductId={editingProductId}
                  onPromoFormChange={updatePromoForm}
                  onProductFormChange={updateProductForm}
                  onSavePromo={savePromo}
                  onEditPromo={editPromo}
                  onResetPromo={resetPromoForm}
                  onSaveProduct={saveProduct}
                  onEditProduct={editProduct}
                  onToggleProduct={toggleProduct}
                  onResetProduct={resetProductForm}
                  onRefresh={loadAdminDashboard}
                />
              ) : null}

              {!loading &&
              !error &&
              (activeTab === "home" || (activeTab === "favorites" && visibleProducts.length))
                ? visibleProducts.map((product) => (
                    <ProductCard
                      key={product.id}
                      product={product}
                      isFavorite={favoritesSet.has(product.id)}
                      onToggleFavorite={toggleFavorite}
                      onOpen={openProduct}
                    />
                  ))
                : null}
            </section>
          </main>

          <nav className={`bottom-nav ${activeProduct || checkoutOpen ? "hidden" : ""}`}>
            {navItems.map((item) => (
              <button
                key={item.id}
                className={`nav-item ${activeTab === item.id ? "active" : ""}`}
                onClick={() => switchTab(item.id)}
              >
                {item.id === "cart" && cartCount ? <span className="badge">{cartCount}</span> : null}
                <Icon id={item.icon} />
                <span>{item.label}</span>
              </button>
            ))}
          </nav>
        </div>
      </div>

      {categorySheetOpen ? (
        <CategorySheet
          categories={categories}
          activeCategory={activeCategory}
          onClose={() => setCategorySheetOpen(false)}
          onSelect={(category) => {
            setActiveCategory(category);
            setActiveTab("home");
            setCategorySheetOpen(false);
          }}
        />
      ) : null}

      <CheckoutFlow
        open={checkoutOpen}
        step={checkoutStep}
        draft={checkoutDraft}
        options={checkoutOptions}
        cartItems={cartItems}
        productMap={productMap}
        couponCode={couponCode}
        promoPreview={promoPreview}
        applyingPromo={applyingPromo}
        submitting={checkoutSubmitting || checkoutLoading}
        onClose={closeCheckout}
        onBack={backCheckoutStep}
        onAdvance={advanceCheckoutStep}
        onSubmit={submitCheckout}
        onChange={updateCheckoutDraft}
        onDeliveryPicked={applyWidgetDeliverySelection}
        onCouponChange={handleCouponChange}
        onApplyPromo={applyPromoCode}
      />

      <ProductModal
        product={activeProduct}
        slideIndex={activeProduct ? productSlides[activeProduct.id] || 0 : 0}
        selectedSize={currentProductSize || ""}
        isFavorite={activeProduct ? favoritesSet.has(activeProduct.id) : false}
        quantity={currentProductQty}
        hasSupport={Boolean(supportUrl)}
        onClose={closeProduct}
        onPrevSlide={() => activeProduct && nextSlide(activeProduct.id, -1)}
        onNextSlide={() => activeProduct && nextSlide(activeProduct.id, 1)}
        onToggleFavorite={toggleFavorite}
        onSelectSize={(size) => {
          if (!activeProduct) return;
          setSelectedSize((prev) => ({
            ...prev,
            [activeProduct.id]: size,
          }));
        }}
        onQtyMinus={() => {
          if (!activeProduct) return;
          setDraftQuantities((prev) => ({
            ...prev,
            [makeCartKey(activeProduct.id, currentProductSize)]: Math.max(1, currentProductQty - 1),
          }));
        }}
        onQtyPlus={() => {
          if (!activeProduct) return;
          setDraftQuantities((prev) => ({
            ...prev,
            [makeCartKey(activeProduct.id, currentProductSize)]: currentProductQty + 1,
          }));
        }}
        onGoToCart={async () => {
          if (!activeProduct) return;
          await goToCartFromProduct(activeProduct.id, currentProductQty, currentProductSize);
        }}
        onShare={handleShare}
        onShowSizeChart={() => {
          if (!activeProduct) return;
          setProductSlides((prev) => ({
            ...prev,
            [activeProduct.id]: activeProduct.images.length - 1,
          }));
        }}
        onContactSeller={openSupport}
      />

      <Toast message={toast} />
    </div>
  );
}

ReactDOM.createRoot(document.getElementById("root")).render(<App />);
