// =============================================================================
// CONCESSIONÁRIA — vitrine rotativa de carros DENTRO da Z Shop (4 slots)
// =============================================================================
// Layout master-detail (referência: item shop do Fortnite + lojas AAA):
//   ESQUERDA = lista dos carros da rotação (cards compactos, foto)
//   DIREITA  = palco do carro SELECIONADO: 3D girando devagar (model-viewer,
//              GLB em metadata.model; sem GLB cai na foto), ficha técnica com
//              barras (metadata.stats, mesmos números do ranking KI5), toggle
//              PADRÃO x BLINDADO (price_armored, quando o carro tiver a versão)
//              e o botão de compra.
// Dados: RPC pública genz_car_shop() (rotaciona sozinha no banco quando vence).
// Preview sem banco: /loja com ?carpreview=1 na URL de entrada.
// =============================================================================

// flag de preview: a navegacao SPA reescreve a URL (o ?carpreview=1 some no F5),
// entao ela persiste na sessionStorage — entrou 1x com a flag, vale a aba inteira.
const GZ_CAR_PREVIEW = (function () {
  try {
    if (/[?&]carpreview=1/.test(window.location.search)) {
      sessionStorage.setItem('gz-carpreview', '1');
      return true;
    }
    if (/[?&]carpreview=0/.test(window.location.search)) {
      sessionStorage.removeItem('gz-carpreview');
      return false;
    }
    return sessionStorage.getItem('gz-carpreview') === '1';
  } catch (e) { return false; }
})();

const CAR_RARITY = {
  comum:    { label: 'COMUM',    color: '#B2B2B2' },
  incomum:  { label: 'INCOMUM',  color: '#4CE64C' },
  raro:     { label: 'RARO',     color: '#3075FF' },
  epico:    { label: 'EPICO',    color: '#B34CE6' },
  lendario: { label: 'LENDARIO', color: '#FFA000' },
};
function carRarity(r) { return CAR_RARITY[r] || { label: (r || '').toUpperCase(), color: '#B2B2B2' }; }
function carFmt(n) { return Number(n || 0).toLocaleString('pt-BR'); }

// barras da ficha técnica (chaves de metadata.stats.bars, 0-100 sobre o pool KI5)
const CAR_BARS = [
  { k: 'power',      label: 'POTENCIA' },
  { k: 'speed',      label: 'VELOCIDADE' },
  { k: 'grip',       label: 'DIRIGIBILIDADE' },
  { k: 'offroad',    label: 'OFF-ROAD' },
  { k: 'durability', label: 'DURABILIDADE' },
];

// --- efeitos sonoros da vitrine (E:\GENESIS\SITE\sons site -> sounds/carshop) --
const CAR_SFX = {
  spray: { src: 'sounds/carshop/spray.mp3', vol: 0.6 },        // troca de cor
  armor1: { src: 'sounds/carshop/blindagem.mp3', vol: 0.42 },  // metais encaixando (1)
  armor2: { src: 'sounds/carshop/blindagem2.mp3', vol: 0.42 }, // metais encaixando (2)
};
const gzPreloaded = {};
function gzSfx(name) {
  try {
    const s = CAR_SFX[name];
    const a = new Audio(s.src);
    a.volume = s.vol;
    a.play().catch(function () {});
    return a;
  } catch (e) { return null; }
}
// blindagem = 2 sons em cadeia com timing calibrado:
//   armor1 entra 0.5s depois do clique; armor2 emenda um pouco ANTES do 1 acabar
function gzSfxArmor() {
  setTimeout(function () {
    const a = gzSfx('armor1');
    let fired = false;
    const two = function () { if (!fired) { fired = true; gzSfx('armor2'); } };
    // armor2 entra 0.6s depois do armor1 comecar
    setTimeout(two, 600);
    if (a) a.onended = two; // garantia se o timer falhar
  }, 250);
}

// --- model-viewer sob demanda (só quando a vitrine tem carro 3D) -------------
function ensureModelViewer() {
  if (window.customElements && window.customElements.get('model-viewer')) return;
  if (document.getElementById('gz-mv-loader')) return;
  const s = document.createElement('script');
  s.id = 'gz-mv-loader';
  s.type = 'module';
  s.src = 'https://cdn.jsdelivr.net/npm/@google/model-viewer@3.5.0/dist/model-viewer.min.js';
  document.head.appendChild(s);
}

// --- CSS injetado 1x (keyframes + layout responsivo) --------------------------
function ensureCarShopCss() {
  if (document.getElementById('gz-carshop-css')) return;
  const st = document.createElement('style');
  st.id = 'gz-carshop-css';
  st.textContent = `
    @keyframes gzCarShine {
      0%   { transform: translateX(-130%) skewX(-18deg); }
      100% { transform: translateX(230%)  skewX(-18deg); }
    }
    @keyframes gzCarPulse { 0%,100% { opacity:.55; } 50% { opacity:1; } }
    @keyframes gzCarBarIn { from { width: 0; } }
    @keyframes gzCarFadeIn { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: none; } }

    /* vitrine alinhada com o resto da pagina (o container da Z Shop ja e largo) */
    .gz-cs-breakout { width: 100%; }
    .gz-cs-wrap { display: grid; grid-template-columns: minmax(300px, 480px) minmax(0, 1fr); gap: 18px; align-items: stretch; }
    .gz-cs-list { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; align-content: stretch; }
    .gz-cs-item { cursor: pointer; }
    .gz-cs-item model-viewer { pointer-events: none; }
    .gz-cs-stage-fade { animation: gzCarFadeIn .3s ease; }
    .gz-cs-bar-fill { animation: gzCarBarIn .7s cubic-bezier(.2,.7,.3,1); }
    .gz-car-shine {
      position: absolute; top: 0; bottom: 0; width: 45%;
      background: linear-gradient(90deg, transparent, rgba(255,255,255,.10), transparent);
      animation: gzCarShine 3.4s ease-in-out infinite; pointer-events: none; z-index: 2;
    }
    .gz-car-timer-dot { animation: gzCarPulse 1.6s ease-in-out infinite; }

    @media (max-width: 920px) {
      .gz-cs-wrap { grid-template-columns: 1fr; }
    }
    @media (max-width: 430px) {
      .gz-cs-list { grid-template-columns: 1fr; }
    }
  `;
  document.head.appendChild(st);
}

// --- toca um TRECHO de clipe e PAUSA no fim, sem deixar loopar ----------------
// Vigia frame a frame (requestAnimationFrame): pausa exatamente no ponto final;
// se o clipe der a volta (wrap), congela no fim na hora — sem "pisca".
// fromFrac/toFrac = fracoes 0..1 da duracao. Retorna funcao de cancelamento.
function gzPlayClipSlice(mv, name, fromFrac, toFrac, onDone) {
  let cancelled = false;
  let raf = null;
  let waited = 0;
  function begin() {
    if (cancelled) return;
    let D = 0;
    try { mv.animationName = name; D = mv.duration || 0; } catch (e) { return; }
    // espera 2 frames apos trocar o clipe: duration pode ainda ser a do ANTERIOR
    if (!D || waited < 2) { waited++; raf = requestAnimationFrame(begin); return; }
    try { mv.currentTime = D * fromFrac; mv.play(); } catch (e) { return; }
    let last = D * fromFrac;
    function tick() {
      if (cancelled) return;
      let t = 0, dNow = 0;
      try { t = mv.currentTime; dNow = mv.duration || 0; } catch (e) { return; }
      // relé a duracao TODO frame (se o clipe atualizou, o fim atualiza junto)
      const end = Math.min((dNow || D) * toFrac, (dNow || D)) - 0.001;
      const wrapped = t < last - 0.05;                        // deu a volta
      if (wrapped || t >= end - 0.02) {
        try { mv.pause(); mv.currentTime = end; } catch (e) {}
        onDone && onDone();
        return;
      }
      last = t;
      raf = requestAnimationFrame(tick);
    }
    raf = requestAnimationFrame(tick);
  }
  begin();
  return function cancel() { cancelled = true; if (raf) cancelAnimationFrame(raf); };
}

// --- countdown "NOVOS CARROS EM HH:MM:SS" ------------------------------------
function carCountdown(untilIso, nowMs) {
  if (!untilIso) return null;
  let ms = new Date(untilIso).getTime() - nowMs;
  if (isNaN(ms)) return null;
  if (ms > 365 * 86400 * 1000) return null; // sentinela "tempo indeterminado" (sem rotacao)
  if (ms < 0) ms = 0;
  const s = Math.floor(ms / 1000);
  const d = Math.floor(s / 86400);
  const hh = String(Math.floor((s % 86400) / 3600)).padStart(2, '0');
  const mm = String(Math.floor((s % 3600) / 60)).padStart(2, '0');
  const ss = String(s % 60).padStart(2, '0');
  return (d > 0 ? d + 'd ' : '') + hh + ':' + mm + ':' + ss;
}

// --- mock do preview (?carpreview=1) — stats REAIS do ranking KI5 -------------
function carPreviewData() {
  const in9h = new Date(Date.now() + 9 * 3600 * 1000).toISOString();
  return {
    enabled: true,
    next_rotation_at: in9h,
    slots: [
      { slot: 1, sku: 'car:98stagea260RS', title: "'98 Nissan Stagea 260RS", rarity: 'epico',
        price_credits: 25000, price_armored: 32000, tags: ['esportivo', 'awd'],
        image: 'img/cars/98stagea260RS.png',
        metadata: { model: 'models/cars/98stagea260RS.glb',
          model_armored: 'models/cars/98stagea260RS-blindado.glb',
          skinBase: 'models/cars/skins/98stagea260RS',
          skins: [
            { id: 'black', hex: '#1a1a1c' }, { id: 'blue', hex: '#2757a8' },
            { id: 'green', hex: '#2e7038' }, { id: 'red', hex: '#c0281c' },
            { id: 'white', hex: '#e8e8e4' }, { id: 'yellow', hex: '#e0c341' },
            { id: 'lightBlue', hex: '#7fa8c9' }, { id: 'redBlack', hex: '#7a1420' },
          ],
          stats: {
          bars: { power: 78, speed: 58, grip: 12, offroad: 2, durability: 75 },
          maxSpeed: 130, seats: 4, storage: 21, colors: 24 } } },
      { slot: 2, sku: 'car:90pierceArrow', title: "'90 Pierce Arrow Pumper", rarity: 'epico',
        price_credits: 18000, price_armored: null, tags: ['bombeiro', 'utilitario'],
        image: 'img/cars/90pierceArrow.png',
        metadata: { model: 'models/cars/90pierceArrow.glb',
          skinBase: 'models/cars/skins/90pierceArrow',
          skins: [
            { id: 'RedWhite', hex: '#e8e8e4' }, { id: 'Red', hex: '#c0281c' },
            { id: 'RedBlack', hex: '#1a1a1c' }, { id: 'YellowWhite', hex: '#e0c341' },
          ],
          stats: {
          bars: { power: 59, speed: 15, grip: 8, offroad: 13, durability: 63 },
          maxSpeed: 55, seats: 4, storage: 630, colors: 15 } } },
      { slot: 3, sku: 'car:69chargerDaytona', title: "'69 Dodge Charger Daytona", rarity: 'lendario',
        price_credits: 28000, price_armored: 36000, tags: ['muscle', 'raro de ver'],
        image: 'img/cars/69chargerDaytona.png',
        metadata: { stats: {
          bars: { power: 72, speed: 100, grip: 12, offroad: 2, durability: 53 },
          maxSpeed: 201, seats: 4, storage: 21, colors: 27 } } },
      { slot: 4, sku: 'car:67gt500', title: "'67 Shelby GT500", rarity: 'epico',
        price_credits: 19000, price_armored: null, tags: ['muscle', 'classico'],
        image: 'img/cars/67gt500.png',
        metadata: { stats: {
          bars: { power: 68, speed: 50, grip: 13, offroad: 2, durability: 70 },
          maxSpeed: 115, seats: 4, storage: 174, colors: 54 } } },
    ],
  };
}

// --- card do grid 2x2 (esquerda) — card rico + mini-3D girando + TILT ---------
// Tilt 3D + glare seguindo o mouse (mesmo efeito dos cards da aba Donate),
// na cor da raridade. Sem clipPath aqui: canto cortado achataria o preserve-3d.
function CarGridCard({ car, selected, onSelect }) {
  const r = carRarity(car.rarity);
  const model = car.metadata && car.metadata.model;
  const ref = React.useRef(null);

  const onMove = (e) => {
    const el = ref.current; if (!el) return;
    const b = el.getBoundingClientRect();
    const px = (e.clientX - b.left) / b.width;
    const py = (e.clientY - b.top) / b.height;
    const MAX = 8;
    el.style.transform = `rotateX(${((0.5 - py) * 2 * MAX).toFixed(2)}deg) rotateY(${((px - 0.5) * 2 * MAX).toFixed(2)}deg) scale(1.03)`;
    el.style.setProperty('--gx', (px * 100).toFixed(1) + '%');
    el.style.setProperty('--gy', (py * 100).toFixed(1) + '%');
  };
  const reset = () => { if (ref.current) ref.current.style.transform = 'rotateX(0deg) rotateY(0deg) scale(1)'; };

  return (
    <div className="gz-cs-item" style={{ perspective: 900 }} onClick={() => onSelect(car.sku)}>
      <div ref={ref} onMouseMove={onMove} onMouseLeave={reset} style={{
        position: 'relative', display: 'flex', flexDirection: 'column', height: '100%',
        transformStyle: 'preserve-3d', willChange: 'transform', transition: 'transform .25s ease',
        background: `linear-gradient(165deg, ${r.color}26 0%, #202020 55%, #1a1a1a 100%)`,
        border: selected ? `1px solid ${r.color}` : `1px solid ${r.color}33`,
        borderTop: `3px solid ${r.color}`,
        boxShadow: selected ? `0 12px 36px ${r.color}3d` : '0 8px 24px rgba(0,0,0,.35)',
      }}>
        {/* brilho que segue o mouse (cor da raridade) */}
        <div style={{
          position: 'absolute', inset: 0, pointerEvents: 'none', zIndex: 5,
          background: `radial-gradient(circle at var(--gx,50%) var(--gy,50%), ${r.color}24 0%, transparent 48%)`,
        }} />

        {/* badge raridade (pop pra frente) */}
        <div style={{
          position: 'absolute', top: 10, right: 10, zIndex: 6, transform: 'translateZ(34px)',
          background: r.color + '1c', border: `1px solid ${r.color}55`, color: r.color,
          fontFamily: 'Share Tech Mono', fontSize: 8, padding: '2px 7px', letterSpacing: '0.14em',
        }}>{r.label}</div>

        {/* herói: mini-3D girando (sem controles; o clique seleciona) ou foto — pop máximo.
            flex:1 = toda sobra vertical do card vira área do CARRO (nada de vão vazio) */}
        <div style={{
          position: 'relative', flex: 1, minHeight: 128, transform: 'translateZ(44px)',
          background: `radial-gradient(ellipse at 50% 80%, ${r.color}2e 0%, transparent 66%)`,
        }}>
          {model ? (
            <model-viewer src={model} alt={car.title}
              auto-rotate="" auto-rotate-delay="0" rotation-per-second="20deg"
              interaction-prompt="none" shadow-intensity="0.8" exposure="1.05"
              camera-orbit="223deg 78deg 108%"
              style={{ width: '100%', height: '100%', background: 'transparent' }} />
          ) : (
            <img src={car.image} alt={car.title} style={{
              width: '100%', height: '100%', objectFit: 'contain', padding: '12px 12px 6px',
              filter: `drop-shadow(0 10px 16px ${r.color}44)`,
            }} />
          )}
        </div>

        <div style={{ padding: '8px 12px 12px', display: 'flex', flexDirection: 'column', gap: 5, flexShrink: 0, transform: 'translateZ(18px)' }}>
          <div style={{
            fontFamily: 'Rajdhani', fontWeight: 700, fontSize: 13.5, textTransform: 'uppercase',
            lineHeight: 1.12, color: selected ? '#fff' : 'rgba(255,255,255,.85)',
          }}>{car.title}</div>
          <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between' }}>
            <span style={{ fontFamily: 'Share Tech Mono', fontSize: 13, color: '#a8ff00' }}>
              {carFmt(car.price_credits)} <span style={{ fontSize: 9, color: 'rgba(255,255,255,.45)' }}>ZB</span>
            </span>
            {selected && <span style={{ color: r.color, fontFamily: 'Share Tech Mono', fontSize: 12 }}>▸ NO PALCO</span>}
          </div>
        </div>
      </div>
    </div>
  );
}

function CarShowcase({ session, wallet, busy, onBuy, onNavigate }) {
  const { useState, useEffect } = React;
  const [shop, setShop] = useState(undefined);       // undefined=carregando | null=escondido | obj
  const [selSku, setSelSku] = useState(null);
  const [armored, setArmored] = useState(false);
  const [nowMs, setNowMs] = useState(Date.now());
  const [doorsOpen, setDoorsOpen] = useState(false);
  const [skinId, setSkinId] = useState(null);
  const mvRef = React.useRef(null);
  const doorTimer = React.useRef(null);
  const camRef = React.useRef({ sku: null, orbit: null });   // memoria da rotacao do usuario
  const preview = GZ_CAR_PREVIEW;

  // O clipe "abrir" do GLB é abre -> segura -> fecha. O toggle usa as metades:
  // ABRIR toca 0..50% e pausa (portas abertas); FECHAR toca 50%..fim.
  function stopClip() {
    if (doorTimer.current) { doorTimer.current(); doorTimer.current = null; }
  }
  function toggleDoors() {
    const mv = mvRef.current;
    if (!mv || !mv.availableAnimations || !mv.availableAnimations.length) return;
    const clip = mv.availableAnimations.indexOf('abrir') >= 0 ? 'abrir' : mv.availableAnimations[0];
    stopClip();
    try { mv.timeScale = 1; } catch (e) {}   // portas em velocidade normal
    if (!doorsOpen) {
      doorTimer.current = gzPlayClipSlice(mv, clip, 0, 0.5);
      setDoorsOpen(true);
    } else {
      doorTimer.current = gzPlayClipSlice(mv, clip, 0.5, 1, () => {
        try { mv.currentTime = 0; } catch (e) {}
      });
      setDoorsOpen(false);
    }
  }

  // troca a textura da lataria ("shell") ao vivo
  async function setSkin(s, base) {
    const mv = mvRef.current;
    if (!mv || !mv.model) return;
    try {
      const tex = await mv.createTexture(base + '/' + s.id + '.png');
      // GLB blindado pode dividir a lataria em shell + shell.001 — pinta todas
      mv.model.materials.forEach(m => {
        if (m.name === 'shell' || m.name.startsWith('shell.')) {
          m.pbrMetallicRoughness.baseColorTexture.setTexture(tex);
        }
      });
      setSkinId(s.id);
      gzSfx('spray');
    } catch (e) { console.warn('[GZ] skin swap:', e); }
  }

  useEffect(() => {
    ensureCarShopCss();
    let alive = true;
    function apply(d) {
      if (!alive) return;
      if (!d || !d.enabled || !d.slots || d.slots.length === 0) { setShop(null); return; }
      setShop(d);
      setSelSku(sel => (sel && d.slots.some(s => s.sku === sel)) ? sel : d.slots[0].sku);
    }
    if (preview) { apply(carPreviewData()); return; }
    if (!window.gzCarShop) { setShop(null); return; }
    window.gzCarShop().then(apply);
    return () => { alive = false; };
  }, []);

  // relogio do countdown + recarrega a vitrine quando o prazo vence
  useEffect(() => {
    if (!shop) return;
    const t = setInterval(() => {
      setNowMs(Date.now());
      if (!preview && shop.next_rotation_at && Date.now() > new Date(shop.next_rotation_at).getTime() + 5000) {
        window.gzCarShop && window.gzCarShop().then(d => {
          if (d && d.enabled && d.slots && d.slots.length) {
            setShop(d);
            setSelSku(d.slots[0].sku);
            setArmored(false);
            setDoorsOpen(false); setSkinId(null);
            if (doorTimer.current) { doorTimer.current(); doorTimer.current = null; }
          }
        });
      }
    }, 1000);
    return () => clearInterval(t);
  }, [shop && shop.next_rotation_at]);

  useEffect(() => {
    if (shop && shop.slots && shop.slots.some(s => s.metadata && s.metadata.model)) ensureModelViewer();
    // pre-baixa os GLBs blindados: a troca PADRAO->BLINDADO vem do cache (sem sumico)
    if (shop && shop.slots) shop.slots.forEach(s => {
      const ma = s.metadata && s.metadata.model_armored;
      if (ma && !gzPreloaded[ma]) { gzPreloaded[ma] = 1; fetch(ma).catch(function () {}); }
    });
  }, [shop]);

  // memoria de camera: guarda a rotacao que o usuario deixou e REAPLICA quando
  // o modelo recarrega (troca padrao<->blindado remonta o viewer). Por carro:
  // trocar de carro volta pro angulo padrao, o resto preserva.
  useEffect(() => {
    const mv = mvRef.current;
    if (!mv) return;
    const onCam = () => {
      try { camRef.current = { sku: selSku, orbit: mv.getCameraOrbit().toString() }; } catch (e) {}
    };
    const onLoad = () => {
      const c = camRef.current;
      if (c && c.orbit && c.sku === selSku) {
        try { mv.cameraOrbit = c.orbit; mv.jumpCameraToGoal(); } catch (e) {}
      }
    };
    mv.addEventListener('camera-change', onCam);
    mv.addEventListener('load', onLoad);
    return () => {
      mv.removeEventListener('camera-change', onCam);
      mv.removeEventListener('load', onLoad);
    };
  }, [selSku, armored, shop]);

  // quando o GLB blindado carrega, toca o encaixe das placas 1x
  // (fica ANTES do return condicional: hook depois de return quebra o React)
  useEffect(() => {
    const mv = mvRef.current;
    if (!mv || !shop || !shop.slots || !shop.slots.length) return;
    const s = shop.slots.find(x => x.sku === selSku) || shop.slots[0];
    const ma = s && s.metadata && s.metadata.model_armored;
    const on = armored && s && s.price_armored != null && Number(s.price_armored) > 0;
    if (!on || !ma) return;
    let cancel = null;
    const onLoad = () => {
      if (!mv.availableAnimations || mv.availableAnimations.indexOf('blindar') < 0) return;
      if (cancel) cancel();
      // vigia frame a frame: pausa EXATO no fim (pecas montadas), sem loop nem pisca
      gzSfxArmor();
      try { mv.timeScale = 1; } catch (e) {}   // velocidade original (a que funciona liso)
      cancel = gzPlayClipSlice(mv, 'blindar', 0, 1);
    };
    mv.addEventListener('load', onLoad);
    if (mv.loaded) onLoad();
    return () => {
      if (cancel) cancel();
      mv.removeEventListener('load', onLoad);
    };
  }, [selSku, armored, shop]);

  if (!shop || !shop.slots || shop.slots.length === 0) return null;

  const timer = carCountdown(shop.next_rotation_at, nowMs);
  const sel = shop.slots.find(s => s.sku === selSku) || shop.slots[0];
  const r = carRarity(sel.rarity);
  const model = sel.metadata && sel.metadata.model;
  const modelArmored = sel.metadata && sel.metadata.model_armored;
  const stats = (sel.metadata && sel.metadata.stats) || null;
  const bars = (stats && stats.bars) || null;
  const hasArmored = sel.price_armored != null && Number(sel.price_armored) > 0;
  const useArmored = hasArmored && armored;
  // BLINDADO com GLB proprio: troca o modelo do palco (placas voam e encaixam no load)
  const stageSrc = (useArmored && modelArmored) ? modelArmored : model;
  const price = useArmored ? Number(sel.price_armored) : Number(sel.price_credits);
  const canAfford = session && wallet && (wallet.balance || 0) >= price;
  const isBusy = busy === sel.sku || busy === sel.sku + ':blindado';
  const legendary = sel.rarity === 'lendario';

  function selectCar(sku) {
    setSelSku(sku); setArmored(false);
    setDoorsOpen(false); setSkinId(null);
    stopClip();
  }
  function setArmoredMode(on) {
    setArmored(on);
    setDoorsOpen(false); setSkinId(null);   // GLB remonta: portas fecham, cor volta
    stopClip();
  }
  function handleBuy() {
    if (!session) { onNavigate && onNavigate('auth'); return; }
    if (!onBuy) return;
    // cor escolhida -> skinIndex (idx do skin{} no script). Sem escolha = 0 (a cor
    // que o 3D mostra por padrao). Entrega spawna exatamente essa cor.
    const skins = (sel.metadata && sel.metadata.skins) || [];
    const chosen = skinId ? skins.find(s => s.id === skinId) : null;
    const skinIdx = chosen && chosen.idx != null ? chosen.idx : (skins.length ? 0 : null);
    onBuy({
      sku: useArmored ? sel.sku + ':blindado' : sel.sku,
      title: sel.title + (useArmored ? ' (Blindado)' : ''),
      price_credits: price,
      skin: skinIdx,
    });
  }

  const chip = (label, val) => (
    <div key={label} style={{
      border: '1px solid rgba(255,255,255,.12)', background: 'rgba(255,255,255,.03)',
      padding: '7px 12px', textAlign: 'center', minWidth: 74,
    }}>
      <div style={{ fontFamily: 'Share Tech Mono', fontSize: 15, color: '#fff', lineHeight: 1 }}>{val}</div>
      <div style={{ fontFamily: 'Share Tech Mono', fontSize: 8, color: 'rgba(255,255,255,.42)', letterSpacing: '.12em', marginTop: 4 }}>{label}</div>
    </div>
  );

  return (
    <div className="gz-cs-breakout" style={{ marginBottom: 48 }}>
      {/* header da seção + countdown */}
      <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'flex-end', flexWrap: 'wrap', gap: 12, marginBottom: 16 }}>
        <div>
          <div style={{ display: 'flex', alignItems: 'center', gap: 10, marginBottom: 6 }}>
            <div style={{ width: 24, height: 2, background: '#a8ff00' }} />
            <span style={{ fontFamily: 'Share Tech Mono', fontSize: 11, color: '#a8ff00', letterSpacing: '0.18em' }}>
              CONCESSIONARIA{preview ? ' · PREVIEW' : ''}
            </span>
          </div>
          <div style={{ fontFamily: 'Rajdhani', fontWeight: 700, fontSize: 'clamp(20px,2.6vw,30px)', textTransform: 'uppercase', lineHeight: 1 }}>
            Carros da rotação
          </div>
        </div>
        {timer ? (
          <div style={{
            display: 'flex', alignItems: 'center', gap: 9, padding: '9px 16px',
            border: '1px solid rgba(255,255,255,.14)', background: 'rgba(255,255,255,.04)',
            clipPath: 'polygon(0 0, calc(100% - 8px) 0, 100% 8px, 100% 100%, 8px 100%, 0 calc(100% - 8px))',
          }}>
            <span className="gz-car-timer-dot" style={{ width: 7, height: 7, borderRadius: '50%', background: '#a8ff00', display: 'inline-block' }} />
            <span style={{ fontFamily: 'Share Tech Mono', fontSize: 10, color: 'rgba(255,255,255,.5)', letterSpacing: '.12em' }}>NOVOS CARROS EM</span>
            <span style={{ fontFamily: 'Share Tech Mono', fontSize: 16, color: '#a8ff00' }}>{timer}</span>
          </div>
        ) : (
          <div style={{
            display: 'flex', alignItems: 'center', gap: 9, padding: '9px 16px',
            border: '1px solid rgba(255,255,255,.10)', background: 'rgba(255,255,255,.03)',
            clipPath: 'polygon(0 0, calc(100% - 8px) 0, 100% 8px, 100% 100%, 8px 100%, 0 calc(100% - 8px))',
          }}>
            <span style={{ width: 7, height: 7, borderRadius: '50%', background: 'rgba(255,255,255,.35)', display: 'inline-block' }} />
            <span style={{ fontFamily: 'Share Tech Mono', fontSize: 10, color: 'rgba(255,255,255,.45)', letterSpacing: '.12em' }}>SEM PREVISÃO DE TROCA</span>
          </div>
        )}
      </div>

      <div className="gz-cs-wrap">
        {/* ESQUERDA: grid 2x2 da rotação (cards ricos, mini-3D girando) */}
        <div className="gz-cs-list">
          {shop.slots.map(car => (
            <CarGridCard key={car.sku} car={car} selected={car.sku === sel.sku} onSelect={selectCar} />
          ))}
        </div>

        {/* DIREITA: palco do selecionado */}
        <div key={sel.sku} className="gz-cs-stage-fade" style={{
          position: 'relative', overflow: 'hidden', display: 'flex', flexDirection: 'column',
          background: `linear-gradient(160deg, ${r.color}20 0%, #1e1e1e 45%, #191919 100%)`,
          border: `1px solid ${r.color}45`, borderTop: `3px solid ${r.color}`,
          clipPath: 'polygon(0 0, calc(100% - 16px) 0, 100% 16px, 100% 100%, 16px 100%, 0 calc(100% - 16px))',
        }}>
          {legendary && <div className="gz-car-shine" />}

          {/* badge raridade */}
          <div style={{
            position: 'absolute', top: 14, right: 16, zIndex: 3,
            background: r.color + '1c', border: `1px solid ${r.color}55`, color: r.color,
            fontFamily: 'Share Tech Mono', fontSize: 10, padding: '4px 11px', letterSpacing: '0.14em',
          }}>{r.label}</div>

          {/* palco 3D / foto */}
          <div style={{
            position: 'relative', height: 400,
            background: `radial-gradient(ellipse at 50% 82%, ${r.color}34 0%, transparent 62%)`,
          }}>
            {model ? (
              <model-viewer key={sel.sku} ref={mvRef} src={stageSrc} alt={sel.title}
                auto-rotate="" auto-rotate-delay="0" rotation-per-second="4deg"
                camera-controls="" disable-zoom="" disable-pan="" disable-tap=""
                interaction-prompt="none" shadow-intensity="1" exposure="1.05"
                camera-orbit="225deg 76deg 80%" min-camera-orbit="auto auto 80%"
                style={{ width: '100%', height: '100%', background: 'transparent' }} />
            ) : (
              <img src={sel.image} alt={sel.title} style={{
                width: '100%', height: '100%', objectFit: 'contain', padding: '22px 22px 10px',
                filter: `drop-shadow(0 18px 28px ${r.color}44)`,
              }} />
            )}
            <div style={{
              position: 'absolute', left: 16, bottom: 10, fontFamily: 'Share Tech Mono',
              fontSize: 8, color: 'rgba(255,255,255,.38)', letterSpacing: '.14em', pointerEvents: 'none',
            }}>{model ? '3D · ARRASTE PRA GIRAR' : 'FOTO DO MOD'}</div>
            {model && (
              <button onClick={toggleDoors} style={{
                position: 'absolute', right: 16, bottom: 10, zIndex: 3,
                background: doorsOpen ? r.color + '33' : 'rgba(0,0,0,.45)',
                border: `1px solid ${r.color}66`, color: '#fff',
                fontFamily: 'Share Tech Mono', fontSize: 10, letterSpacing: '.12em',
                padding: '7px 14px', cursor: 'pointer', textTransform: 'uppercase',
                clipPath: 'polygon(0 0, calc(100% - 6px) 0, 100% 6px, 100% 100%, 6px 100%, 0 calc(100% - 6px))',
              }}
                onMouseEnter={e => { e.currentTarget.style.background = r.color + '33'; }}
                onMouseLeave={e => { e.currentTarget.style.background = doorsOpen ? r.color + '33' : 'rgba(0,0,0,.45)'; }}
              >{doorsOpen ? '✕ Fechar portas' : '▶ Abrir portas'}</button>
            )}
            {/* cores do carro: troca a textura da lataria ao vivo */}
            {model && sel.metadata.skinBase && Array.isArray(sel.metadata.skins) && sel.metadata.skins.length > 1 && (
              <div style={{
                position: 'absolute', left: '50%', transform: 'translateX(-50%)', bottom: 8, zIndex: 3,
                display: 'flex', gap: 5, alignItems: 'center', flexWrap: 'wrap', justifyContent: 'center',
                rowGap: 5, maxWidth: 'min(86%, 520px)',
                background: 'rgba(0,0,0,.45)', padding: '6px 10px', borderRadius: 13,
              }}>
                {(() => {
                  const seen = {}; const out = [];
                  sel.metadata.skins.forEach(s => { if (s && s.id && !seen[s.id]) { seen[s.id] = 1; out.push(s); } });
                  return out.map(s => (
                    <button key={s.id} title={s.id} onClick={() => setSkin(s, sel.metadata.skinBase)} style={{
                      width: 13, height: 13, borderRadius: '50%', cursor: 'pointer', padding: 0, flex: '0 0 auto',
                      background: s.hex || '#888',
                      border: skinId === s.id ? '2px solid #fff' : '1px solid rgba(255,255,255,.35)',
                      boxShadow: skinId === s.id ? `0 0 7px ${r.color}` : 'none',
                    }} />
                  ));
                })()}
              </div>
            )}
          </div>

          {/* ficha + compra */}
          <div style={{ padding: '16px 20px 20px', position: 'relative', zIndex: 2, display: 'flex', flexDirection: 'column', gap: 14, flex: 1 }}>
            <div>
              <div style={{ fontFamily: 'Rajdhani', fontWeight: 700, fontSize: 'clamp(20px,2.4vw,27px)', textTransform: 'uppercase', lineHeight: 1.05 }}>
                {sel.title}
              </div>
              {sel.tags && sel.tags.length > 0 && (
                <div style={{ display: 'flex', flexWrap: 'wrap', gap: 6, marginTop: 8 }}>
                  {sel.tags.map(t => (
                    <span key={t} style={{
                      fontFamily: 'Share Tech Mono', fontSize: 9, letterSpacing: '.08em',
                      color: 'rgba(255,255,255,.5)', border: '1px solid rgba(255,255,255,.14)',
                      padding: '2px 8px', textTransform: 'uppercase',
                    }}>{t}</span>
                  ))}
                </div>
              )}
            </div>

            {/* barras + chips lado a lado */}
            {stats && (
              <div style={{ display: 'flex', flexWrap: 'wrap', gap: 18, alignItems: 'flex-start' }}>
                {bars && (
                  <div style={{ flex: '1 1 260px', minWidth: 220, display: 'flex', flexDirection: 'column', gap: 7 }}>
                    {CAR_BARS.map(b => {
                      const v = Math.max(0, Math.min(100, Number(bars[b.k] || 0)));
                      return (
                        <div key={b.k} style={{ display: 'flex', alignItems: 'center', gap: 10 }}>
                          <span style={{ fontFamily: 'Share Tech Mono', fontSize: 8, color: 'rgba(255,255,255,.48)', letterSpacing: '.1em', width: 96, flexShrink: 0 }}>{b.label}</span>
                          <div style={{ flex: 1, height: 7, background: 'rgba(255,255,255,.07)' }}>
                            <div key={sel.sku + b.k} className="gz-cs-bar-fill" style={{
                              width: v + '%', height: '100%',
                              background: `linear-gradient(90deg, ${r.color}88, ${r.color})`,
                            }} />
                          </div>
                          <span style={{ fontFamily: 'Share Tech Mono', fontSize: 10, color: 'rgba(255,255,255,.6)', width: 26, textAlign: 'right', flexShrink: 0 }}>{v}</span>
                        </div>
                      );
                    })}
                    <div style={{ fontFamily: 'Share Tech Mono', fontSize: 7, color: 'rgba(255,255,255,.28)', letterSpacing: '.08em', marginTop: 2 }}>
                      0-100 COMPARADO COM TODOS OS CARROS DO SERVIDOR
                    </div>
                  </div>
                )}
                <div style={{ display: 'flex', flexWrap: 'wrap', gap: 8 }}>
                  {stats.maxSpeed != null && chip('VEL. MAX', stats.maxSpeed)}
                  {stats.seats != null && chip('ASSENTOS', stats.seats)}
                  {stats.storage != null && chip('PORTA-MALAS', stats.storage)}
                  {stats.colors != null && chip('CORES', stats.colors)}
                </div>
              </div>
            )}

            {/* blindagem (só se o carro tiver a versão) */}
            {hasArmored && (
              <div>
                <div style={{ fontFamily: 'Share Tech Mono', fontSize: 9, color: 'rgba(255,255,255,.45)', letterSpacing: '.14em', marginBottom: 7 }}>VERSAO</div>
                <div style={{ display: 'flex', gap: 8, flexWrap: 'wrap' }}>
                  {[{ on: false, label: 'PADRAO', p: Number(sel.price_credits) },
                    { on: true,  label: 'BLINDADO', p: Number(sel.price_armored) }].map(opt => {
                    const active = armored === opt.on;
                    return (
                      <button key={opt.label} onClick={() => setArmoredMode(opt.on)} style={{
                        display: 'flex', alignItems: 'center', gap: 8, padding: '9px 16px',
                        background: active ? r.color + '22' : 'rgba(255,255,255,.03)',
                        border: active ? `1px solid ${r.color}` : '1px solid rgba(255,255,255,.14)',
                        color: active ? '#fff' : 'rgba(255,255,255,.55)',
                        fontFamily: 'Rajdhani', fontWeight: 700, fontSize: 12, letterSpacing: '.08em',
                        cursor: 'pointer', textTransform: 'uppercase',
                        clipPath: 'polygon(0 0, calc(100% - 6px) 0, 100% 6px, 100% 100%, 6px 100%, 0 calc(100% - 6px))',
                      }}>
                        {opt.on && <span style={{ fontSize: 13 }}>🛡</span>}
                        {opt.label}
                        <span style={{ fontFamily: 'Share Tech Mono', fontSize: 11, color: active ? '#a8ff00' : 'rgba(255,255,255,.4)' }}>
                          {carFmt(opt.p)} ZB
                        </span>
                      </button>
                    );
                  })}
                </div>
                {useArmored && (
                  <div style={{ fontFamily: 'Share Tech Mono', fontSize: 9, color: 'rgba(255,255,255,.4)', marginTop: 6, letterSpacing: '.05em' }}>
                    Reforçado: aguenta bem mais dano que a versão padrão.
                  </div>
                )}
              </div>
            )}

            {/* preço + comprar */}
            <div style={{ display: 'flex', alignItems: 'center', gap: 14, marginTop: 'auto', flexWrap: 'wrap' }}>
              <div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>
                {window.ZbIcon ? <window.ZbIcon size={24} /> : null}
                <span style={{ fontFamily: 'Share Tech Mono', fontSize: 28, color: '#a8ff00', lineHeight: 1 }}>{carFmt(price)}</span>
                <span style={{ fontSize: 12, color: 'rgba(255,255,255,.5)' }}>ZB</span>
              </div>
              <button onClick={handleBuy} disabled={isBusy} style={{
                flex: '1 1 180px', maxWidth: 320, padding: '14px 22px',
                background: !session ? 'transparent' : (canAfford ? r.color : 'rgba(255,255,255,.06)'),
                color: !session ? '#a8ff00' : (canAfford ? '#111' : 'rgba(255,255,255,.4)'),
                border: !session ? '1px solid rgba(168,255,0,.4)' : 'none',
                fontFamily: 'Rajdhani', fontWeight: 700, fontSize: 15, letterSpacing: '0.12em',
                cursor: isBusy ? 'wait' : 'pointer', textTransform: 'uppercase', transition: 'all .2s',
                clipPath: 'polygon(0 0, calc(100% - 9px) 0, 100% 9px, 100% 100%, 9px 100%, 0 calc(100% - 9px))',
              }}>
                {!session ? 'Entrar pra comprar' : isBusy ? 'Comprando...' : ('Comprar' + (useArmored ? ' blindado' : ''))}
              </button>
            </div>

            <div style={{ fontFamily: 'Share Tech Mono', fontSize: 9, color: 'rgba(255,255,255,.35)', letterSpacing: '.04em' }}>
              O carro chega perto de você dentro do jogo, já no seu nome e com a chave. Só você pode usar.
            </div>
          </div>
        </div>
      </div>
    </div>
  );
}

Object.assign(window, { CarShowcase });
