/* ============================================================
   Төрмен — shared UI primitives
   ============================================================ */
const { useState:useStateU, useEffect:useEffectU, useRef:useRefU } = React;

/* ---------- Lucide icon (renders inline SVG from the UMD data) ---------- */
function pascal(name){ return name.replace(/(^|-)([a-z])/g, (_,a,b)=>b.toUpperCase()); }
function lucideNode(name){
  const L = window.lucide;
  if(!L) return null;
  const src = L.icons || L;
  const d = src[pascal(name)] || src[name];
  return Array.isArray(d) ? d : null;
}
function Icon({ name, size=20, stroke=1.6, className='', style }){
  const data = lucideNode(name);
  return (
    <svg width={size} height={size} viewBox="0 0 24 24" fill="none"
      stroke="currentColor" strokeWidth={stroke} strokeLinecap="round" strokeLinejoin="round"
      className={className} style={style} aria-hidden="true">
      {data
        ? data.map((node,i)=>{ const [tag,attrs]=node; return React.createElement(tag,{key:i,...attrs}); })
        : <circle cx="12" cy="12" r="9" />}
    </svg>
  );
}

/* ---------- placeholder imagery ---------- */
const PH_ICON = { cut:'beef', grill:'flame', kazan:'cooking-pot', broth:'soup', video:'play', farm:'wheat' };
const PH_KW   = { cut:'beef,meat', grill:'barbecue,grill,meat', kazan:'stew,meat', broth:'soup,broth', video:'cooking,food', farm:'farm,cattle,countryside' };
function phHash(s){ s=String(s); let h=0; for(let i=0;i<s.length;i++){ h=(h*31+s.charCodeAt(i))|0; } return Math.abs(h); }
// TEST imagery — themed stock photos. Replace with your own later.
function phImg(type, seed){ const lock = (phHash(seed!=null?seed:type) % 940) + 1; return `https://loremflickr.com/640/480/${PH_KW[type]||'meat'}?lock=${lock}`; }

function Ph({ type='cut', label, className='', children, rounded='var(--radius)', seed, photo=true, imgKey, idx=0, photoSrc, medusaPhoto=false, fit }){
  // medusaPhoto: только загруженное фото, без случайных стоков при ошибке
  // fit: cover — обрезка; contain — целиком в рамке (для загруженных фото по умолчанию)
  const imgFit = fit || (medusaPhoto ? 'contain' : 'cover');
  const sources = [];
  const resolved = photoSrc && window.normalizeMedusaAssetUrl
    ? window.normalizeMedusaAssetUrl(photoSrc) : photoSrc;
  if(resolved) sources.push(resolved);
  if(!medusaPhoto){
    const curated = imgKey && window.imgFor ? window.imgFor(imgKey, idx) : null;
    if(curated) sources.push(curated);
    sources.push(phImg(type, seed!=null?seed:`${imgKey||type}-${idx}`));
  }
  const [stage, setStage] = useStateU(0);
  const src = photo && stage < sources.length ? sources[stage] : null;
  const hasPhoto = !!src && (medusaPhoto || stage === 0 && resolved);
  return (
    <div className={`ph ${imgFit==='contain'?'ph-fit-contain':''} ${hasPhoto?'ph-has-photo':''} ${className}`} style={{ borderRadius:rounded }}>
      {/* fallback layer (shown while loading or if every source fails) */}
      <div className="absolute inset-0 grid place-items-center pointer-events-none">
        <Icon name={PH_ICON[type]||'beef'} size={64} stroke={1} style={{ color:'rgba(255,240,224,0.14)' }} />
      </div>
      {src && (
        <img src={src} alt={label||''}
          onError={()=>setStage(s=>s+1)}
          className={`ph-img absolute inset-0 w-full h-full ${imgFit==='contain'?'object-contain':'object-cover'}`}
          style={{ borderRadius:'inherit' }} />
      )}
      <div className="ph-grain" />
      {label && <>
        <div className="absolute inset-x-0 bottom-0 h-1/2 pointer-events-none" style={{ background:'linear-gradient(to top,rgba(8,5,3,0.66),transparent)', borderRadius:'inherit' }} />
        <span className="ph-label" style={{ color:'rgba(255,250,244,0.92)' }}><Icon name={PH_ICON[type]||'beef'} size={12} stroke={1.8} />{label}</span>
      </>}
      {children}
    </div>
  );
}

/* ---------- scroll reveal ---------- */
function Reveal({ children, delay=0, className='', as:Tag='div' }){
  const ref = useRefU(null);
  useEffectU(()=>{
    const el = ref.current; if(!el) return;
    if(!('IntersectionObserver' in window)){ el.classList.add('in'); return; }
    const io = new IntersectionObserver((es)=>{
      es.forEach(e=>{ if(e.isIntersecting){ el.classList.add('in'); io.unobserve(el); } });
    }, { threshold:0.12, rootMargin:'0px 0px -8% 0px' });
    io.observe(el);
    return ()=>io.disconnect();
  },[]);
  return <Tag ref={ref} className={`reveal ${className}`} style={{ transitionDelay:`${delay}ms` }}>{children}</Tag>;
}

/* ---------- section header ---------- */
function SectionHeader({ eyebrow, title, action }){
  return (
    <div className="flex items-end justify-between gap-4 mb-7 md:mb-9">
      <div>
        <div className="eyebrow mb-3">{eyebrow}</div>
        <h2 className="serif-title text-[26px] md:text-[34px] leading-tight" style={{ color:'var(--ink)' }}>{title}</h2>
      </div>
      {action}
    </div>
  );
}

/* ---------- brand mark (heritage kazan — stroke only, no fill gradients) ---------- */
function BrandEmblem({ px=34, always=false }){
  const ic = Math.round(px * 0.52);
  return (
    <span className={`brand-emblem ${always?'grid':'hidden sm:grid'}`} style={{ width:px, height:px }}>
      <svg width={ic} height={ic} viewBox="0 0 32 32" fill="none" stroke="currentColor"
        strokeWidth="1.55" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true">
        <path d="M16 4 21 9 16 14 11 9Z" />
        <path d="M11 9c-5 0-4 6-7 6M21 9c5 0 4 6 7 6" />
        <path d="M16 14v13M10 27h12" />
      </svg>
    </span>
  );
}

/* ---------- brand logo ---------- */
function Logo({ size=22, onClick, emblem=true, emblemAlways=false, variant='default' }){
  const wordCls = variant==='nav' ? 'brand-wordmark brand-wordmark--nav' : 'brand-wordmark';
  const wordStyle = variant==='nav' ? undefined : { fontSize:size };
  const inner = (
    <>
      {emblem && <BrandEmblem px={Math.round(size * 1.45)} always={emblemAlways} />}
      <span className={wordCls} style={wordStyle}>Төрмен</span>
    </>
  );
  if(onClick){
    return (
      <button type="button" onClick={onClick} className="brand-logo" aria-label="Төрмен — на главную">
        {inner}
      </button>
    );
  }
  return <div className="brand-logo" style={{ cursor:'default' }}>{inner}</div>;
}

/* ---------- star rating (supports fractional averages) ---------- */
function Stars({ value=5, size=13 }){
  return (
    <span className="inline-flex items-center gap-0.5" style={{ color:'var(--gold)' }}>
      {[0,1,2,3,4].map(i=>{
        const fill = Math.max(0, Math.min(1, value - i)); // 0..1 for this star
        return (
          <span key={i} className="relative inline-grid" style={{ width:size, height:size }}>
            <Icon name="star" size={size} stroke={0} className="absolute inset-0" style={{ fill:'var(--ink-4)', color:'transparent' }} />
            <span className="absolute inset-0 overflow-hidden" style={{ width:`${fill*100}%` }}>
              <Icon name="star" size={size} stroke={0} style={{ fill:'var(--gold)', color:'transparent' }} />
            </span>
          </span>
        );
      })}
    </span>
  );
}

Object.assign(window, { Icon, Ph, Reveal, SectionHeader, Logo, Stars });
