// Shared shop state — cart + view + filters + lang. Each variation calls
// useShop() to get the same hook shape but renders its own visuals.

(function () {
  const { useState, useEffect, useMemo, useCallback } = React;

  // Force re-render when language flips (Tweaks panel posts an event), or
  // when fury-api.js swaps PROFILE / SERVERS / PRODUCTS with live backend data.
  function useLang() {
    const [, force] = useState(0);
    useEffect(() => {
      const onChange = () => force((x) => x + 1);
      window.addEventListener('fury:lang', onChange);
      window.addEventListener('fury:data', onChange);
      return () => {
        window.removeEventListener('fury:lang', onChange);
        window.removeEventListener('fury:data', onChange);
      };
    }, []);
    return window.FURY_lang();
  }

  function useShop(initialView) {
    const lang = useLang();
    // Bumped from useLang on every fury:data event. Used as a useMemo dep so
    // memoised lookups against window.FURY_PRODUCTS recompute after fury-api
    // swaps the array.
    const dataVer = window.__furyDataVersion || 0;
    const t = window.FURY_I18N[lang];
    const [view, setView] = useState(initialView || 'shop');
    const [cat, setCat] = useState('all');
    const [search, setSearch] = useState('');
    const [sort, setSort] = useState('popular');
    const [cart, setCart] = useState({}); // {id: qty}
    const [cartOpen, setCartOpen] = useState(false);
    const [serverId, setServerId] = useState('fury-1');
    const [selectedId, setSelectedId] = useState(null);
    const [buyQty, setBuyQty] = useState(1);
    const selected = selectedId ? window.FURY_PRODUCTS.find((p) => p.id === selectedId) : null;
    const select = useCallback((id) => { setSelectedId(id); setBuyQty(1); }, []);
    const closeSelected = useCallback(() => setSelectedId(null), []);

    const products = useMemo(() => {
      let list = window.FURY_PRODUCTS.slice();
      if (cat !== 'all') list = list.filter((p) => p.cat === cat);
      const q = search.trim().toLowerCase();
      if (q) {
        list = list.filter((p) =>
          window.FURY_pname(p).toLowerCase().includes(q) || p.id.includes(q)
        );
      }
      if (sort === 'price_asc') list.sort((a, b) => a.price - b.price);
      else if (sort === 'price_desc') list.sort((a, b) => b.price - a.price);
      else if (sort === 'new') list.sort((a, b) => (b.badge === 'new' ? 1 : 0) - (a.badge === 'new' ? 1 : 0));
      return list;
    }, [cat, search, sort, lang, dataVer]);

    const add = useCallback((id) => {
      // Корзина работает только для авторизованных. Гость, нажав «купить»,
      // отправляется на Steam OpenID — после возврата он залогинен и может
      // добавлять снова. Покупка в БД на сервере и так гейтится requireAuth,
      // но логичнее не давать копить нелегитимную корзину в гостевой сессии.
      const loggedIn = window.FURY_PROFILE && window.FURY_PROFILE.loggedIn !== false;
      if (!loggedIn) {
        if (window.FURY_API && window.FURY_API.login) window.FURY_API.login();
        return;
      }
      setCart((c) => ({ ...c, [id]: (c[id] || 0) + 1 }));
    }, []);
    const remove = useCallback((id) => {
      setCart((c) => { const n = { ...c }; delete n[id]; return n; });
    }, []);
    const setQty = useCallback((id, q) => {
      setCart((c) => {
        const n = { ...c };
        if (q <= 0) delete n[id]; else n[id] = q;
        return n;
      });
    }, []);

    const cartItems = useMemo(() =>
      Object.entries(cart)
        .map(([id, qty]) => ({ p: window.FURY_PRODUCTS.find((x) => x.id === id), qty }))
        .filter((x) => x.p),
      [cart, dataVer]
    );
    const subtotal = cartItems.reduce((s, x) => s + x.p.price * x.qty, 0);
    const cartCount = cartItems.reduce((s, x) => s + x.qty, 0);
    const discount = Math.min(window.FURY_PROFILE.bonus, Math.floor(subtotal * 0.1));
    const total = Math.max(0, subtotal - discount);

    return {
      lang, t,
      view, setView,
      cat, setCat,
      search, setSearch,
      sort, setSort,
      cart, cartItems, cartCount, subtotal, discount, total,
      cartOpen, setCartOpen,
      add, remove, setQty,
      serverId, setServerId,
      products,
      profile: window.FURY_PROFILE,
      servers: window.FURY_SERVERS,
      selected, select, closeSelected, buyQty, setBuyQty,
    };
  }

  // Format integer with thin spaces as group separator.
  function fmt(n) {
    return String(n).replace(/\B(?=(\d{3})+(?!\d))/g, '\u202F');
  }

  // Tone → tonal palette used for image placeholders so each card has a
  // distinct silhouette without external assets. Variations reuse these
  // freely or override with their own gradient.
  const TONES = {
    olive:   ['#4a5238', '#2a2e1f', '#8a9472'],
    crimson: ['#5a1818', '#1f0a0a', '#a83232'],
    rust:    ['#6b3a1c', '#2a1408', '#b06038'],
    bone:    ['#7a7466', '#3a3528', '#bdb6a0'],
    frost:   ['#3a4a5a', '#16202b', '#8aa0b8'],
    iron:    ['#3a3d40', '#16181a', '#7c8086'],
    wood:    ['#5a3a1c', '#2a1a08', '#a8743a'],
    gold:    ['#7a5a18', '#2e220a', '#d4a83a'],
  };

  function toneGrad(tone) {
    const [mid, dark, light] = TONES[tone] || TONES.iron;
    return `radial-gradient(120% 90% at 30% 30%, ${light} 0%, ${mid} 35%, ${dark} 100%)`;
  }

  // Tiny SVG glyph per category — silhouette-style, monochrome.
  function CategoryGlyph({ cat, size = 60, color = 'currentColor', opacity = 0.85 }) {
    const s = { width: size, height: size, color, opacity, display: 'block' };
    const stroke = { fill: 'none', stroke: 'currentColor', strokeWidth: 1.5, strokeLinecap: 'round', strokeLinejoin: 'round' };
    const fill = { fill: 'currentColor' };
    const paths = {
      kits: <g {...stroke}>
        <path d="M20 18 L32 12 L44 18 L44 36 L32 44 L20 36 Z" />
        <path d="M20 18 L32 24 L44 18" /><path d="M32 24 L32 44" />
        <circle cx="32" cy="32" r="3" {...fill} />
      </g>,
      build: <g {...stroke}>
        <path d="M14 46 L14 26 L32 14 L50 26 L50 46 Z" />
        <path d="M26 46 L26 34 L38 34 L38 46" />
        <path d="M14 26 L50 26" />
      </g>,
      vehicles: <g {...stroke}>
        <path d="M12 36 L12 28 L22 22 L40 22 L48 28 L52 28 L52 38 L48 38" />
        <path d="M12 38 L20 38" /><path d="M30 38 L40 38" />
        <circle cx="24" cy="40" r="4" /><circle cx="44" cy="40" r="4" />
      </g>,
      vip: <g {...stroke}>
        <path d="M14 22 L22 36 L32 18 L42 36 L50 22 L46 46 L18 46 Z" />
        <circle cx="32" cy="14" r="2" {...fill} />
      </g>,
      cosmetics: <g {...stroke}>
        <circle cx="32" cy="32" r="14" />
        <path d="M32 18 L32 46 M18 32 L46 32 M22 22 L42 42 M42 22 L22 42" />
      </g>,
      currency: <g {...stroke}>
        <circle cx="24" cy="28" r="10" />
        <circle cx="38" cy="36" r="10" />
        <path d="M22 25 L26 25 M22 28 L26 28 M22 31 L26 31" strokeWidth="1.2" />
      </g>,
      slots: <g {...stroke}>
        <rect x="16" y="16" width="32" height="32" rx="2" />
        <path d="M22 26 L42 26 M22 32 L42 32 M22 38 L34 38" />
      </g>,
    };
    return (
      <svg viewBox="0 0 64 64" style={s} aria-hidden="true">
        {paths[cat] || paths.kits}
      </svg>
    );
  }

  Object.assign(window, { useShop, useLang, furyFmt: fmt, furyTone: toneGrad, FuryGlyph: CategoryGlyph });
})();
