/* PANEL SAAS · Orgullo Millonario — React + Tailwind · Liquid Glass
   Conectado a OM-DB: lo que se edita aquí se refleja EN VIVO en la página principal (site.html). */
const {useState,useEffect,useRef,useMemo,useSyncExternalStore,createContext,useContext}=React;
const useDB=()=>useSyncExternalStore(OMDB.subscribe,OMDB.get);

/* ============ ICONS ============ */
const I={
  dash:<path d="M3 3h7v9H3zM14 3h7v5h-7zM14 12h7v9h-7zM3 16h7v5H3z"/>,
  card:<><rect x="4" y="3" width="12" height="16" rx="2"/><path d="M8 21h12V8"/></>,
  squad:<><circle cx="9" cy="8" r="3"/><circle cx="17" cy="10" r="2.5"/><path d="M3 20a6 6 0 0 1 12 0M13 20a5 5 0 0 1 8-4"/></>,
  spark:<path d="m13 2-8 12h6l-2 8 8-12h-6l2-8Z"/>,
  gift:<><path d="M4 9h16v10H4z"/><path d="M4 9l2-5 6 3 6-3 2 5M12 9v10"/></>,
  heart:<path d="M12 21C7 17 3 13.5 3 9.5A4.5 4.5 0 0 1 12 7a4.5 4.5 0 0 1 9 2.5c0 4-4 7.5-9 11.5Z"/>,
  play:<><rect x="2" y="4" width="20" height="16" rx="3"/><path d="m10 8 6 4-6 4V8Z"/></>,
  chat:<path d="M21 12a8 8 0 0 1-8 8H4l2-3a8 8 0 1 1 15-5Z"/>,
  grid:<><rect x="3" y="3" width="8" height="8" rx="2"/><rect x="13" y="3" width="8" height="8" rx="2"/><rect x="3" y="13" width="8" height="8" rx="2"/><rect x="13" y="13" width="8" height="8" rx="2"/></>,
  bell:<path d="M6 9a6 6 0 1 1 12 0c0 5 2 6 2 6H4s2-1 2-6M10 19a2 2 0 0 0 4 0"/>,
  search:<><circle cx="11" cy="11" r="7"/><path d="m21 21-4-4"/></>,
  x:<path d="M6 6l12 12M18 6 6 18"/>,
  down:<path d="M4 4v12h12M8 10l4 4 6-8"/>,
  eye:<><path d="M2 12s3.5-6 10-6 10 6 10 6-3.5 6-10 6-10-6-10-6Z"/><circle cx="12" cy="12" r="2.5"/></>,
};
const Ic=({n,s=18,c=""})=><svg viewBox="0 0 24 24" width={s} height={s} className={c} fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round">{I[n]}</svg>;

/* ============ TOAST ============ */
const ToastCtx=createContext(()=>{});
function ToastHost({children}){
  const [msg,setMsg]=useState(null);const t=useRef();
  const toast=m=>{setMsg(m);clearTimeout(t.current);t.current=setTimeout(()=>setMsg(null),2400);};
  return <ToastCtx.Provider value={toast}>{children}
    <div className={`fixed left-1/2 -translate-x-1/2 bottom-24 md:bottom-8 z-[90] transition-all duration-300 ${msg?'opacity-100 translate-y-0':'opacity-0 translate-y-4 pointer-events-none'}`}>
      <div className="glass rounded-2xl px-5 py-3 text-[13px] font-semibold border-river/40" style={{borderColor:'rgba(224,30,47,.45)'}}>{msg}</div>
    </div>
  </ToastCtx.Provider>;
}

/* ============ SHARED ============ */
const Sec=({label,children,right})=>(
  <div className="flex items-center justify-between mb-3">
    <span className="font-mono text-[9px] tracking-[2px] text-mut">{label}</span>{right}
  </div>
);
const Bar=({pct,cls})=>(
  <div className="h-[7px] rounded-full bg-white/10 overflow-hidden">
    <i className={`block h-full rounded-full ${cls}`} style={{width:pct+'%',background:cls?undefined:'linear-gradient(90deg,#8d0917,#ff2e3e)'}}/>
  </div>
);

/* ============ MODULES ============ */
function KpiModule(){
  const db=useDB();const k=db.kpis;
  const kpis=[[k.viajes,"VIAJES PUBLICADOS","#2f7df6","🚌"],[k.reservas,"RESERVAS","#22c55e","📅"],[k.socios,"SOCIOS","#ffcf3e","👤"],[k.visitas,"VISITAS TOTALES","#ff2e3e","👁"]];
  return <div className="grid grid-cols-2 lg:grid-cols-4 gap-3">
    {kpis.map(([n,l,c,e],i)=>(
      <div key={i} className="glass rounded-3xl p-4 press cursor-default overflow-hidden">
        <div className="flex items-start justify-between"><b className="font-disp text-[30px] leading-none pr-6" style={{color:c}}>{n}</b><span className="text-[15px] opacity-90">{e}</span></div>
        <small className="font-mono text-[8px] tracking-[1.5px] text-mut block mt-2 leading-relaxed">{l}</small>
        <div className="absolute inset-x-0 bottom-0 h-[3px]" style={{background:`linear-gradient(90deg,${c},transparent)`}}/>
      </div>))}
  </div>;
}

/* ============ SITIO & HERO — controla la página principal EN VIVO ============ */
function SiteModule(){
  const db=useDB();const toast=useContext(ToastCtx);const c=db.config;
  const F=({label,val,onChange,mono})=>(
    <label className="block"><span className="font-mono text-[8px] tracking-[1.5px] text-mut block mb-1.5">{label}</span>
      <input value={val} onChange={e=>onChange(e.target.value)} className={`w-full bg-white/[.06] border border-white/10 rounded-xl px-3.5 py-2.5 text-[12px] outline-none focus:border-river/60 transition-colors ${mono?'font-mono':''}`}/></label>);
  return <>
    <Sec label="TODO ESTO SE REFLEJA EN VIVO EN LA PÁGINA" right={<a href="site.html" target="_blank" className="press font-mono text-[8.5px] tracking-[1px] text-cyanx border border-cyanx/40 rounded-lg px-3 py-1.5 hover:bg-cyanx/10">ABRIR SITIO ↗</a>}/>
    <div className="flex flex-col gap-3">
      <F label="TÍTULO DEL HERO" val={c.hero_titulo} onChange={v=>OMDB.set('config.hero_titulo',v)}/>
      <F label="SUBTÍTULO" val={c.hero_subtitulo} onChange={v=>OMDB.set('config.hero_subtitulo',v)}/>
      <div className="grid grid-cols-2 gap-3">
        <F label="WHATSAPP" val={c.whatsapp} onChange={v=>OMDB.set('config.whatsapp',v)} mono/>
        <F label="LINK MERCADO PAGO" val={c.mp_link} onChange={v=>OMDB.set('config.mp_link',v)} mono/>
      </div>
      <div>
        <span className="font-mono text-[8px] tracking-[1.5px] text-mut block mb-1.5">TEMA DEL SITIO</span>
        <div className="grid grid-cols-2 gap-2">
          {[['dark','Oscuro'],['light','Claro']].map(([t,l])=>(
            <button key={t} onClick={()=>{OMDB.set('config.tema',t);toast('Tema: '+l);}} className={`press rounded-xl py-2.5 text-[12px] font-bold border transition-all ${c.tema===t?'text-white border-river':'text-mut border-white/10'}`} style={c.tema===t?{background:'linear-gradient(160deg,#ff2e3e,#8d0917)'}:{}}>{l}</button>))}
        </div>
      </div>
      <button onClick={()=>{OMDB.reset();toast('Datos restablecidos a los valores de fábrica');}} className="press glass rounded-xl py-2.5 text-[11px] font-bold text-mut hover:text-ink mt-1">↺ Restablecer datos del sitio</button>
    </div>
  </>;
}

function RevenueModule(){
  return <>
    <Sec label="FACTURACIÓN" right={<b className="font-disp text-gold2 text-[16px]">$24.900/mes</b>}/>
    <svg viewBox="0 0 260 90" className="w-full">
      <defs><linearGradient id="fg" x1="0" y1="0" x2="0" y2="1"><stop offset="0" stopColor="#ff2e3e" stopOpacity=".4"/><stop offset="1" stopColor="#ff2e3e" stopOpacity="0"/></linearGradient></defs>
      <line x1="0" y1="28" x2="260" y2="24" stroke="#22c55e" strokeWidth="1.5" strokeDasharray="4 4" opacity=".8"/>
      <path d="M0 78 40 72 80 60 120 66 160 45 200 52 240 30 260 24 260 90 0 90Z" fill="url(#fg)"/>
      <polyline points="0,78 40,72 80,60 120,66 160,45 200,52 240,30 260,24" fill="none" stroke="#ff2e3e" strokeWidth="2.5" strokeLinecap="round"/>
      <circle cx="240" cy="30" r="4" fill="#ff2e3e"/><circle cx="240" cy="30" r="8" fill="none" stroke="#ff2e3e" opacity=".4"/>
    </svg>
    <div className="grid grid-cols-4 gap-2 mt-3 text-center">
      {[["$24.900","MES ACTUAL","text-gold2"],["$1.22M","META ANUAL","text-ink"],["20,41%","PROGRESO","text-green-400"],["21","OPERACIONES","text-ink"]].map(([b,s,c],i)=>(
        <div key={i}><b className={`font-mono text-[11px] block ${c}`}>{b}</b><small className="font-mono text-[6.5px] text-dim tracking-wide">{s}</small></div>))}
    </div>
    <div className="mt-4"><Bar pct={20.41}/><div className="flex justify-between font-mono text-[8.5px] text-mut mt-2"><span>OBJETIVO ANUAL</span><span className="text-green-400">20,41%</span></div></div>
  </>;
}

function WorldModule(){
  const dots=useMemo(()=>{
    let seed=77;const rnd=()=>((seed=(seed*1103515245+12345)&0x7fffffff)/0x7fffffff);
    const zones=[[18,18,55,32,.5],[55,52,28,48,.6],[112,12,40,26,.5],[118,40,32,38,.55],[150,14,60,40,.5],[196,60,26,20,.45]];
    const a=[];zones.forEach(z=>{for(let i=0;i<z[2]/4;i++)for(let j=0;j<z[3]/4;j++)if(rnd()<z[4])a.push([z[0]+i*4+rnd()*2,z[1]+j*4+rnd()*2]);});return a;
  },[]);
  const hot=[[72,92,4],[70,86,2.5],[40,40,2.5],[135,32,2],[126,58,2],[170,30,2],[205,68,2]];
  return <>
    <Sec label="VISITAS EN EL MUNDO" right={<span className="flex items-center gap-2 font-mono text-[8.5px] text-green-400"><i className="w-[6px] h-[6px] rounded-full bg-green-400" style={{animation:'pulseDot 1.4s infinite'}}/>EN VIVO</span>}/>
    <svg viewBox="0 0 260 120" className="w-full">
      {dots.map((d,i)=><circle key={i} cx={d[0]} cy={d[1]} r="1" fill="rgba(255,255,255,.16)"/>)}
      {hot.map((p,i)=><g key={i}><circle cx={p[0]} cy={p[1]} r={p[2]} fill="#ff2e3e" style={{animation:'pulseDot 2s infinite'}}/><circle cx={p[0]} cy={p[1]} r={p[2]*2.2} fill="none" stroke="#ff2e3e" strokeWidth=".6" opacity=".4"/></g>)}
    </svg>
    <div className="flex justify-between items-end -mt-3">
      <div><b className="font-disp text-[26px] text-river2 leading-none">882</b><small className="font-mono text-[7px] tracking-[1px] text-mut block">VISITAS</small></div>
      <div className="text-right"><b className="font-disp text-[18px] text-cyanx leading-none">138</b><small className="font-mono text-[7px] text-mut block">HOY</small></div>
    </div>
  </>;
}

function FiguritasModule(){
  const toast=useContext(ToastCtx);
  const RZ=[["COMÚN","#9a9aa6"],["PLATA","#c0c0cb"],["ORO","#ffcf3e"],["LEYENDA","#ff2e3e"],["HOLOGRÁFICA","#8b5cf6"],["ULTRA PREMIUM","#22d3ee"]];
  const CLUBS=[["River","assets/river.png"],["Boca","assets/boca.png"],["Barracas","assets/barracas.png"],["Racing","assets/racing.png"],["Talleres","assets/talleres.png"],["Argentinos","assets/argentinos.png"]];
  const FLAGS=["🇦🇷","🇧🇷","🇺🇾","🇨🇴","🇨🇱","🇵🇾","🇻🇪"];
  const [rz,setRz]=useState(4);
  const [name,setName]=useState("Franco Armani");
  const [num,setNum]=useState("23");
  const [pos,setPos]=useState("ARQ");
  const [club,setClub]=useState(0);
  const [flag,setFlag]=useState(0);
  const [photo,setPhoto]=useState("assets/armani.png");
  const [imgH,setImgH]=useState(108);
  const [imgY,setImgY]=useState(0);
  const fileRef=useRef();
  const c=RZ[rz][1];
  const onFile=e=>{const f=e.target.files&&e.target.files[0];if(!f)return;if(f.size>4.5e6){toast('Imagen muy grande (máx 4.5MB)');return;}const r=new FileReader();r.onload=()=>{setPhoto(r.result);toast('Imagen del jugador cargada');};r.readAsDataURL(f);};
  const crear=()=>{
    if(!name.trim()){toast('Poné un nombre');return;}
    OMDB.update(s=>{s.figuritas=[{clave:'c'+Date.now(),nombre:name.trim(),tier:RZ[rz][0],img:photo,tenida:true,cant:1,num,pos,flag:FLAGS[flag],club:CLUBS[club][1]},...s.figuritas].slice(0,20);});
    toast(`✔ ${name} (${RZ[rz][0]}) publicada en el álbum del sitio`);
  };
  const exportPNG=async()=>{
    const W=520,H=728,cv=document.createElement('canvas');cv.width=W;cv.height=H;const x=cv.getContext('2d');
    const rr=(a,b,w,h,r)=>{x.beginPath();x.moveTo(a+r,b);x.arcTo(a+w,b,a+w,b+h,r);x.arcTo(a+w,b+h,a,b+h,r);x.arcTo(a,b+h,a,b,r);x.arcTo(a,b,a+w,b,r);x.closePath();};
    rr(0,0,W,H,40);x.clip();
    const g=x.createLinearGradient(0,0,W,H);g.addColorStop(0,c+'55');g.addColorStop(.5,'#1a1226');g.addColorStop(1,'#0b0714');x.fillStyle=g;x.fillRect(0,0,W,H);
    const load=src=>new Promise(res=>{const im=new Image();im.crossOrigin='anonymous';im.onload=()=>res(im);im.onerror=()=>res(null);im.src=src;});
    const pl=await load(photo);
    if(pl){const ph=H*(imgH/100),pw=ph*(pl.width/pl.height);x.drawImage(pl,(W-pw)/2,H-ph+imgY*3,pw,ph);}
    const ov=x.createLinearGradient(0,H*0.45,0,H);ov.addColorStop(0,'rgba(0,0,0,0)');ov.addColorStop(1,'rgba(0,0,0,.95)');x.fillStyle=ov;x.fillRect(0,H*0.45,W,H*0.55);
    // holo streak
    const hs=x.createLinearGradient(0,0,W,H);hs.addColorStop(.3,'rgba(255,255,255,0)');hs.addColorStop(.47,'rgba(255,255,255,.28)');hs.addColorStop(.52,c+'88');hs.addColorStop(.68,'rgba(255,255,255,0)');x.fillStyle=hs;x.fillRect(0,0,W,H);
    // flag + number
    x.font='40px serif';x.fillText(FLAGS[flag],24,58);
    x.fillStyle='rgba(255,255,255,.14)';x.font='900 120px Oswald, sans-serif';x.textAlign='right';x.fillText(num,W-28,150);
    // name + tier
    x.textAlign='center';x.fillStyle='#fff';x.font='700 46px Oswald, sans-serif';x.fillText(name.toUpperCase().slice(0,16),W/2,H-92);
    x.fillStyle=c;x.font='700 22px "JetBrains Mono", monospace';x.fillText(RZ[rz][0]+' · #'+num,W/2,H-54);
    // border
    x.strokeStyle=c;x.lineWidth=8;rr(4,4,W-8,H-8,36);x.stroke();
    const club_im=await load(CLUBS[club][1]);if(club_im){x.drawImage(club_im,W-84,24,56,56);}
    const a=document.createElement('a');a.download=`figurita-${name.toLowerCase().replace(/\s+/g,'-')||'cromo'}.png`;a.href=cv.toDataURL('image/png');a.click();
    toast('PNG descargado ✔');
  };
  return <>
    <div className="grid grid-cols-1 sm:grid-cols-[1fr_auto] gap-5">
      <div className="flex flex-col gap-4 min-w-0">
        <div>
          <Sec label="DATOS DEL JUGADOR"/>
          <input value={name} onChange={e=>setName(e.target.value)} className="w-full bg-white/[.06] border border-white/10 rounded-2xl px-4 py-3 text-[13px] font-semibold outline-none focus:border-river/60 transition-colors" placeholder="Nombre del jugador"/>
          <div className="grid grid-cols-[1fr_1fr] gap-2 mt-2">
            <input value={num} onChange={e=>setNum(e.target.value.slice(0,3))} className="bg-white/[.06] border border-white/10 rounded-xl px-3 py-2 text-[11px] font-mono text-center outline-none focus:border-river/60 min-w-0" placeholder="N°"/>
            <select value={pos} onChange={e=>setPos(e.target.value)} className="bg-white/[.06] border border-white/10 rounded-xl px-3 py-2 text-[11px] font-mono text-center outline-none focus:border-river/60 min-w-0">{["ARQ","DEF","MED","DEL","DT"].map(p=><option key={p} className="bg-[#15151a]">{p}</option>)}</select>
          </div>
        </div>
        <div>
          <Sec label="FOTO DEL JUGADOR"/>
          <input ref={fileRef} type="file" accept="image/*" onChange={onFile} className="hidden"/>
          <div className="grid grid-cols-2 gap-2">
            <button onClick={()=>fileRef.current.click()} className="press rounded-xl py-2.5 text-[11px] font-bold text-white flex items-center justify-center gap-2" style={{background:'linear-gradient(160deg,#2f7df6,#1b4fb0)',boxShadow:'0 8px 22px -8px rgba(47,125,246,.6)'}}>⬆ Subir imagen</button>
            <button onClick={()=>{setPhoto('assets/armani.png');toast('Foto de ejemplo');}} className="press glass rounded-xl py-2.5 text-[11px] font-bold text-mut hover:text-ink">Ejemplo</button>
          </div>
          <p className="font-mono text-[7.5px] text-dim tracking-[.5px] mt-1.5">PNG recortado del jugador · fondo transparente ideal · máx 4.5MB</p>
        </div>
        <div>
          <Sec label="RAREZA / EDICIÓN"/>
          <div className="flex flex-wrap gap-2">
            {RZ.map(([r,cc],i)=>(
              <button key={r} onClick={()=>{setRz(i);}}
                className={`press rounded-full px-4 py-2 text-[10px] font-mono tracking-[1px] border transition-all ${i===rz?'text-white':'text-mut border-white/10 hover:text-ink'}`}
                style={i===rz?{borderColor:cc,background:`color-mix(in srgb, ${cc} 22%, transparent)`,boxShadow:`0 0 20px ${cc}44`}:{}}>{r}</button>))}
          </div>
        </div>
        <div className="grid grid-cols-2 gap-3">
          <div><Sec label="ESCUDO"/><div className="flex flex-wrap gap-1.5">{CLUBS.map(([n,src],i)=><button key={n} onClick={()=>setClub(i)} className={`press w-9 h-9 rounded-lg grid place-items-center bg-white/[.05] border ${i===club?'border-river':'border-white/10'}`}><img src={src} alt={n} className="w-6 h-6 object-contain"/></button>)}</div></div>
          <div><Sec label="BANDERA"/><div className="flex flex-wrap gap-1.5">{FLAGS.map((f,i)=><button key={i} onClick={()=>setFlag(i)} className={`press w-9 h-9 rounded-lg grid place-items-center text-[16px] bg-white/[.05] border ${i===flag?'border-river':'border-white/10'}`}>{f}</button>)}</div></div>
        </div>
        <div>
          <Sec label="DIMENSIONES DE LA FOTO"/>
          <div className="flex items-center gap-3"><span className="font-mono text-[8px] text-mut w-14">ZOOM</span><input type="range" min="70" max="150" value={imgH} onChange={e=>setImgH(+e.target.value)} className="flex-1"/><output className="font-mono text-[10px] text-gold2 w-10 text-right">{imgH}%</output></div>
          <div className="flex items-center gap-3 mt-2"><span className="font-mono text-[8px] text-mut w-14">ALTURA</span><input type="range" min="-20" max="20" value={imgY} onChange={e=>setImgY(+e.target.value)} className="flex-1"/><output className="font-mono text-[10px] text-gold2 w-10 text-right">{imgY}</output></div>
        </div>
        <div className="grid grid-cols-2 gap-2 mt-auto">
          <button onClick={crear} className="press rounded-2xl py-3 text-[12px] font-bold text-white" style={{background:'linear-gradient(160deg,#ff2e3e,#8d0917)',boxShadow:'0 10px 30px -8px rgba(224,30,47,.6)'}}>＋ Crear y publicar</button>
          <button onClick={exportPNG} className="press glass rounded-2xl py-3 text-[12px] font-bold text-mut hover:text-ink">⬇ Descargar PNG</button>
        </div>
      </div>
      <div className="flex flex-col items-center gap-3 mx-auto">
        <span className="font-mono text-[8px] tracking-[2px] text-mut">VISTA PREVIA EN VIVO</span>
        <div className="relative w-[186px] aspect-[3/4.3] rounded-[22px] overflow-hidden press cursor-pointer" style={{border:`2px solid ${c}`,boxShadow:`0 20px 50px -12px ${c}66, inset 0 1px 0 rgba(255,255,255,.2)`,background:`linear-gradient(165deg,${c}44,#1a1226 55%,#0b0714)`}}>
          <img src={photo} alt={name} className="absolute inset-x-0 w-full object-contain object-bottom" style={{height:imgH+'%',bottom:imgY+'%',left:'50%',transform:'translateX(-50%)'}}/>
          <span className="absolute top-2.5 left-2.5 text-[16px]">{FLAGS[flag]}</span>
          <span className="absolute top-1.5 right-2.5 font-disp text-[30px] font-bold text-white/15">{num}</span>
          <img src={CLUBS[club][1]} alt="" className="absolute top-2.5 right-2.5 w-6 h-6 object-contain drop-shadow" style={{display:'none'}}/>
          <span className="absolute inset-0 pointer-events-none" style={{background:`linear-gradient(115deg,transparent 30%,rgba(255,255,255,.3) 45%,${c}77 52%,transparent 68%)`,animation:'holoShine 2.6s linear infinite'}}/>
          {(rz===4||rz===5)&&<span className="absolute inset-0 pointer-events-none mix-blend-overlay" style={{background:`repeating-linear-gradient(60deg,${c}22 0 6px,transparent 6px 12px)`,animation:'holoShine 4s linear infinite reverse'}}/>}
          <div className="absolute inset-x-0 bottom-0 pt-10 pb-3 px-2 text-center" style={{background:'linear-gradient(transparent,rgba(0,0,0,.94) 42%)'}}>
            <b className="font-disp text-[15px] tracking-[1px] block leading-tight">{name.toUpperCase()||'—'}</b>
            <small className="font-mono text-[7.5px] tracking-[2.5px]" style={{color:c}}>{RZ[rz][0]} · #{num}</small>
          </div>
        </div>
        <img src={CLUBS[club][1]} alt="" className="w-0 h-0"/>
      </div>
    </div>
  </>;
}

function PlantillaModule(){
  const toast=useContext(ToastCtx);
  const G=[["① ARQUEROS",[["armani","Armani","#1"]]],
    ["② DEFENSORES",[["montiel","Montiel","#4"],["pezzella","Pezzella","#6"],["diaz","Paulo Díaz","#17"]]],
    ["③ MEDIOCAMPISTAS",[["perez","E. Pérez","#24"],["castano","Castaño","#20"],["quintero","Quintero","#10"]]],
    ["④ FORWARDS",[["borja","Borja","#9"],["colidio","Colidio","#11"],["salas","M. Salas","#7"]]]];
  return <>
    <Sec label="(4-3-3) · DT E. GALLARDO" right={<b className="font-disp text-[20px] text-gold2">40 <span className="font-mono text-[7px] text-mut tracking-[1px]">EN PLANTEL</span></b>}/>
    <div className="flex flex-col gap-1.5 flex-1">
      {G.map(([lbl,ps])=><React.Fragment key={lbl}>
        <div className="font-mono text-[7.5px] tracking-[1.5px] text-river2 mt-1">{lbl}</div>
        {ps.map(([img,n,num])=>(
          <div key={n} className="press flex items-center gap-3 bg-white/[.05] border border-white/[.07] rounded-2xl px-3 py-2 cursor-pointer hover:bg-white/[.09] transition-colors">
            <img src={`assets/plantel/${img}.png`} alt="" className="w-7 h-7 rounded-full object-cover object-top bg-white/10"/>
            <b className="text-[12px] flex-1">{n}</b><small className="font-mono text-[9px] text-dim">{num}</small>
          </div>))}
      </React.Fragment>)}
    </div>
    <button onClick={()=>toast('Abriendo gestión de plantilla…')} className="press glass rounded-2xl py-2.5 mt-3 text-[11px] font-bold text-mut hover:text-ink w-full">Ver plantilla completa</button>
  </>;
}

function SponsorsModule(){
  const toast=useContext(ToastCtx);
  const tiers=[["ORO","text-gold2","rgba(212,164,55,.35)",[<img key="b" src="assets/betano.png" alt="Betano" className="h-6 object-contain"/>,"CODERE","GATORADE"]],
    ["PLATA","text-[#c0c0cb]","rgba(192,192,203,.25)",["STANLEY","KONAMI","MOSTAZA"]],
    ["BRONCE","text-[#b0763a]","rgba(176,118,58,.3)",["TIENDA RIVER","QUILMES","ASSIST CARD"]]];
  return <>
    <Sec label="MULTI-TIER"/>
    <div className="flex flex-col gap-3 flex-1">
      {tiers.map(([t,tc,bc,logos])=>(
        <div key={t}>
          <small className={`font-mono text-[8px] tracking-[2px] block mb-1.5 ${tc}`}>{t}</small>
          <div className="grid grid-cols-3 gap-2">
            {logos.map((l,i)=>(
              <span key={i} className="press h-11 rounded-2xl grid place-items-center font-disp text-[10.5px] tracking-[1px] text-mut bg-white/[.05] cursor-pointer hover:bg-white/[.09] transition-colors px-2 text-center" style={{border:`1px solid ${bc}`}}>{l}</span>))}
          </div>
        </div>))}
    </div>
    <button onClick={()=>toast('Abriendo gestor de sponsors…')} className="press glass rounded-2xl py-2.5 mt-3 text-[11px] font-bold text-mut hover:text-ink w-full">Gestionar sponsors</button>
  </>;
}

function HistoriasModule(){
  const toast=useContext(ToastCtx);
  const viajes=[["Boca Juniors vs River Plate","La Bombonera · 25/05",["BUS","ENTRADA"]],["River Plate vs Talleres","Más Monumental · 01/06",["BUS","COMIDA"]],["River Plate vs Independiente","Más Monumental · 08/06",["BUS"]]];
  return <>
    <Sec label="AI TELEGRAM PARSER" right={<span className="font-mono text-[8px] text-cyanx tracking-[1px]">⚡ IA</span>}/>
    <div className="flex flex-col gap-2">
      {viajes.map(([t,s,tags])=>(
        <div key={t} className="press bg-white/[.05] border border-white/[.07] rounded-2xl px-3.5 py-2.5 cursor-pointer hover:bg-white/[.09] transition-colors">
          <b className="text-[12px] block">{t}</b><small className="font-mono text-[8px] text-dim">{s}</small>
          <div className="flex gap-1.5 mt-1.5">{tags.map(g=><span key={g} className="font-mono text-[7px] tracking-[.5px] px-2 py-[3px] rounded-md bg-cyanx/10 text-cyanx">{g}</span>)}</div>
        </div>))}
    </div>
    <div className="font-mono text-[8.5px] leading-[1.8] text-mut bg-black/40 border border-white/[.07] rounded-2xl p-3.5 mt-3 whitespace-pre-line max-h-32 overflow-y-auto">{`VAMOS A LA BOMBONERA\nBOCA JRS VS RIVER PLATE\nVIERNES 25/05 · BUS 10:00 HS + ENTRADA\nDESDE EL OBELISCO · RESERVA AL 11 2234-5678\n¡CUPOS LIMITADOS!`}</div>
    <button onClick={()=>toast('🤖 Mensaje analizado: viaje detectado y publicado')} className="press rounded-2xl py-3 mt-3 text-[12px] font-bold text-white w-full" style={{background:'linear-gradient(160deg,#ff2e3e,#8d0917)',boxShadow:'0 10px 30px -8px rgba(224,30,47,.6)'}}>Analizar mensaje</button>
  </>;
}

function SorteosModule(){
  const toast=useContext(ToastCtx);
  const db=useDB();const s=db.sorteo;const sold=useMemo(()=>new Set(s.sold),[s.sold]);
  const toggle=n=>OMDB.update(st=>{const set=new Set(st.sorteo.sold);set.has(n)?set.delete(n):set.add(n);st.sorteo.sold=[...set].sort((a,b)=>a-b);});
  return <>
    <Sec label="CLIC PARA MARCAR VENDIDO · SE ACTUALIZA EN EL SITIO" right={<span className="font-mono text-[8px] text-gold2 tracking-[1px]">${s.precio} C/U</span>}/>
    <div className="grid grid-cols-[auto_1fr] gap-4 items-center">
      <img src={s.img} alt="Premio" className="w-24 object-contain drop-shadow-[0_10px_20px_rgba(0,0,0,.6)]"/>
      <div className="grid grid-cols-10 gap-[3px]">
        {Array.from({length:s.total},(_,n)=>(
          <button key={n} onClick={()=>toggle(n)} className={`press aspect-square rounded-[4px] grid place-items-center font-mono text-[6px] ${sold.has(n)?'bg-crimson text-white':'bg-white/[.06] text-dim border border-white/[.06]'}`}>{String(n).padStart(2,'0')}</button>))}
      </div>
    </div>
    <div className="flex justify-between font-mono text-[8px] text-mut mt-3"><span>■ VENDIDOS <b className="text-gold2">{sold.size}</b></span><span>□ DISPONIBLES <b className="text-gold2">{s.total-sold.size}</b></span></div>
  </>;
}

function ReelsModule(){
  const db=useDB();const toast=useContext(ToastCtx);const [txt,setTxt]=useState('');
  const add=()=>{if(!txt.trim())return;OMDB.update(s=>{s.reels=[{titulo:txt.trim(),vistas:'0',plataforma:'TIKTOK'},...s.reels];});setTxt('');toast('Reel publicado en el sitio');};
  const del=i=>OMDB.update(s=>{s.reels.splice(i,1);});
  return <>
    <Sec label="REELS / TIKTOK CMS"/>
    <div className="flex gap-2 mb-3">
      <input value={txt} onChange={e=>setTxt(e.target.value)} onKeyDown={e=>e.key==='Enter'&&add()} placeholder="Título del reel…" className="flex-1 bg-white/[.06] border border-white/10 rounded-xl px-3 py-2 text-[11px] outline-none focus:border-river/60 min-w-0"/>
      <button onClick={add} className="press rounded-xl px-4 text-[16px] font-bold text-white" style={{background:'linear-gradient(160deg,#ff2e3e,#8d0917)'}}>＋</button>
    </div>
    <div className="flex flex-col gap-2 flex-1">
      {db.reels.map((r,i)=>(
        <div key={i} className="flex items-center gap-3 bg-white/[.05] border border-white/[.07] rounded-2xl px-3 py-2.5">
          <span className="w-9 h-11 rounded-xl grid place-items-center text-[12px] flex-none" style={{background:'linear-gradient(160deg,#2a2a33,#101014)'}}>▶</span>
          <div className="min-w-0 flex-1"><b className="text-[11.5px] block leading-tight truncate">{r.titulo}</b><small className="font-mono text-[7px] text-dim">{r.vistas} VISTAS · {r.plataforma}</small></div>
          <button onClick={()=>del(i)} className="press w-7 h-7 rounded-lg grid place-items-center text-dim hover:text-river2"><Ic n="x" s={13}/></button>
        </div>))}
    </div>
  </>;
}

/* ============ MODULE REGISTRY (hiper modular) ============ */
const MODULES=[
  {id:'kpi',   title:'Dashboard & Métricas', icon:'dash',  span:'lg:col-span-6', bare:true, C:KpiModule},
  {id:'site',  title:'Sitio & Hero',         icon:'eye',   span:'lg:col-span-3', C:SiteModule},
  {id:'rev',   title:'Facturación',          icon:'down',  span:'lg:col-span-3', C:RevenueModule},
  {id:'world', title:'Visitas',              icon:'eye',   span:'lg:col-span-3', C:WorldModule},
  {id:'figus', title:'Figuritas Builder',    icon:'card',  span:'lg:col-span-4', C:FiguritasModule},
  {id:'squad', title:'Plantilla',            icon:'squad', span:'lg:col-span-2 lg:row-span-2', C:PlantillaModule},
  {id:'hist',  title:'Historias · Telegram', icon:'chat',  span:'lg:col-span-2', C:HistoriasModule},
  {id:'sorteo',title:'Sorteos',              icon:'gift',  span:'lg:col-span-2', C:SorteosModule},
  {id:'spons', title:'Sponsors',             icon:'heart', span:'lg:col-span-2', C:SponsorsModule},
  {id:'reels', title:'Reels TikTok',         icon:'play',  span:'lg:col-span-2', C:ReelsModule},
];
const LS_KEY='om-panel-modules-v1';

/* ============ MODULE MANAGER SHEET ============ */
function ModuleSheet({open,onClose,enabled,setEnabled}){
  if(!open)return null;
  return <div className="fixed inset-0 z-[80] flex items-end md:items-center justify-center" onClick={onClose}>
    <div className="absolute inset-0 bg-black/60 backdrop-blur-sm"/>
    <div onClick={e=>e.stopPropagation()} className="glass-deep relative rounded-t-glass md:rounded-glass w-full md:w-[420px] p-6 safe-b" style={{animation:'sheetUp .35s cubic-bezier(.22,1,.36,1) both'}}>
      <div className="w-10 h-1 rounded-full bg-white/20 mx-auto mb-4 md:hidden"/>
      <div className="flex items-center justify-between mb-4">
        <b className="font-disp text-[16px] tracking-[1px]">MÓDULOS DEL PANEL</b>
        <button onClick={onClose} className="press w-8 h-8 rounded-full glass grid place-items-center text-mut hover:text-ink"><Ic n="x" s={14}/></button>
      </div>
      <div className="flex flex-col gap-2 max-h-[55vh] overflow-y-auto">
        {MODULES.map(m=>{
          const on=enabled.includes(m.id);
          return <button key={m.id} onClick={()=>setEnabled(on?enabled.filter(x=>x!==m.id):[...enabled,m.id])}
            className="press flex items-center gap-3 bg-white/[.05] border border-white/[.08] rounded-2xl px-4 py-3 text-left">
            <span className={on?'text-river2':'text-dim'}><Ic n={m.icon} s={16}/></span>
            <b className={`text-[12.5px] flex-1 ${on?'':'text-dim'}`}>{m.title}</b>
            <span className={`w-11 h-6 rounded-full p-[3px] transition-colors ${on?'bg-river':'bg-white/15'}`}>
              <i className={`block w-[18px] h-[18px] rounded-full bg-white shadow transition-transform ${on?'translate-x-5':''}`}/>
            </span>
          </button>;})}
      </div>
      <p className="font-mono text-[8px] text-dim tracking-[1px] mt-4 text-center">TU CONFIGURACIÓN SE GUARDA AUTOMÁTICAMENTE</p>
    </div>
  </div>;
}

/* ============ APP ============ */
function App(){
  const toast=useContext(ToastCtx);
  const [enabled,setEnabledRaw]=useState(()=>{const all=MODULES.map(m=>m.id);try{const v=JSON.parse(localStorage.getItem(LS_KEY));if(!Array.isArray(v))return all;return[...v.filter(id=>all.includes(id)),...all.filter(id=>!v.includes(id))];}catch(e){return all;}});
  const setEnabled=v=>{setEnabledRaw(v);try{localStorage.setItem(LS_KEY,JSON.stringify(v));}catch(e){}};
  const [sheet,setSheet]=useState(false);
  const [clock,setClock]=useState('');
  useEffect(()=>{const f=()=>{const d=new Date(),p=n=>String(n).padStart(2,'0');setClock(`${p(d.getDate())}/${p(d.getMonth()+1)}/${d.getFullYear()} · ${p(d.getHours())}:${p(d.getMinutes())} HS`);};f();const t=setInterval(f,30000);return()=>clearInterval(t);},[]);
  const mods=MODULES.filter(m=>enabled.includes(m.id));
  const navGo=id=>{const el=document.getElementById('mod-'+id);if(el){const y=el.getBoundingClientRect().top+window.scrollY-84;window.scrollTo({top:y,behavior:'smooth'});}else toast('Activá ese módulo desde “Módulos”');};
  return <>
    {/* fondo liquid */}
    <div className="blob w-[520px] h-[520px] -top-40 -left-32" style={{background:'radial-gradient(circle,#8d0917 0%,transparent 70%)',opacity:.55,animation:'drift1 18s ease-in-out infinite'}}/>
    <div className="blob w-[420px] h-[420px] top-1/3 -right-32" style={{background:'radial-gradient(circle,#3b1d6e 0%,transparent 70%)',opacity:.5,animation:'drift2 22s ease-in-out infinite'}}/>
    <div className="blob w-[380px] h-[380px] bottom-0 left-1/3" style={{background:'radial-gradient(circle,#5a4008 0%,transparent 70%)',opacity:.4,animation:'drift1 26s ease-in-out infinite'}}/>

    {/* topbar glass */}
    <header className="sticky top-0 z-[60] px-3 md:px-6 pt-3">
      <div className="glass-deep rounded-glass flex items-center gap-3 px-4 md:px-5 py-2.5 max-w-[1440px] mx-auto">
        <img src="assets/logo-om.png" alt="OM" className="w-8 h-9 object-contain"/>
        <div className="leading-tight mr-2">
          <b className="font-disp text-[13px] tracking-[1px] block">PANEL SAAS</b>
          <small className="font-mono text-[7px] tracking-[2px] text-river2">ORGULLO MILLONARIO</small>
        </div>
        <nav className="hidden lg:flex items-center gap-1 flex-1 justify-center">
          {MODULES.slice(0,7).map(m=>(
            <button key={m.id} onClick={()=>navGo(m.id)} className="press flex items-center gap-2 px-3.5 py-2 rounded-full text-[11px] font-semibold text-mut hover:text-ink hover:bg-white/[.07] transition-colors">
              <Ic n={m.icon} s={13}/>{m.title.split(' ')[0]}
            </button>))}
        </nav>
        <div className="flex items-center gap-2 ml-auto">
          <button onClick={()=>toast('Buscar…')} className="press w-9 h-9 rounded-full glass grid place-items-center text-mut hover:text-ink"><Ic n="search" s={15}/></button>
          <button onClick={()=>toast('Sin notificaciones nuevas')} className="press w-9 h-9 rounded-full glass grid place-items-center text-mut hover:text-ink relative"><Ic n="bell" s={15}/><i className="absolute top-1.5 right-2 w-[6px] h-[6px] rounded-full bg-river2"/></button>
          <button onClick={()=>setSheet(true)} className="press hidden md:flex items-center gap-2 px-4 py-2 rounded-full text-[11px] font-bold text-white" style={{background:'linear-gradient(160deg,#ff2e3e,#8d0917)',boxShadow:'0 8px 24px -6px rgba(224,30,47,.6)'}}><Ic n="grid" s={13}/>Módulos</button>
          <div className="w-9 h-9 rounded-full grid place-items-center font-disp font-bold text-[14px] text-gold2 border-2 border-river" style={{background:'radial-gradient(circle at 35% 30%,#3a3a44,#17171c)'}}>A</div>
        </div>
      </div>
    </header>

    {/* grid de módulos */}
    <main className="relative z-10 px-3 md:px-6 py-4 pb-28 md:pb-10 max-w-[1440px] mx-auto grid grid-cols-1 md:grid-cols-2 lg:grid-cols-6 gap-3 md:gap-4 items-start">
      {mods.map((m,i)=>m.bare
        ?<div key={m.id} id={'mod-'+m.id} className={`${m.span} md:col-span-2 rise`} style={{animationDelay:i*60+'ms'}}><m.C/></div>
        :<section key={m.id} id={'mod-'+m.id} className={`glass rounded-glass p-5 flex flex-col ${m.span} rise`} style={{animationDelay:i*60+'ms'}}>
          <div className="flex items-center gap-2.5 mb-4">
            <span className="w-8 h-8 rounded-xl grid place-items-center text-river2" style={{background:'rgba(224,30,47,.12)',border:'1px solid rgba(224,30,47,.3)'}}><Ic n={m.icon} s={15}/></span>
            <b className="font-disp text-[14px] tracking-[1.5px]">{m.title.toUpperCase()}</b>
          </div>
          <m.C/>
        </section>)}
      {mods.length===0&&<div className="col-span-full glass rounded-glass p-10 text-center text-mut text-[13px]">No hay módulos activos. Tocá <b className="text-ink">Módulos</b> para activarlos.</div>}
    </main>

    {/* footer */}
    <footer className="relative z-10 hidden md:flex items-center gap-5 px-6 pb-4 max-w-[1440px] mx-auto font-mono text-[8px] tracking-[1px] text-dim">
      <span>ORGULLO MILLONARIO ® 2026</span><span>PANEL SAAS v3.0 · LIQUID</span>
      <span className="text-green-400">SERVIDORES: ONLINE ●</span><span className="ml-auto">ACTUALIZADO: {clock}</span>
    </footer>

    {/* tab bar móvil */}
    <nav className="lg:hidden fixed bottom-3 inset-x-3 z-[70] safe-b">
      <div className="glass-deep rounded-glass flex items-center justify-around px-2 py-2">
        {[['kpi','dash','Inicio'],['figus','card','Figus'],['squad','squad','Plantel'],['sorteo','gift','Sorteos']].map(([id,ic,l])=>(
          <button key={id} onClick={()=>navGo(id)} className="press flex flex-col items-center gap-1 px-4 py-1.5 rounded-2xl text-mut hover:text-ink">
            <Ic n={ic} s={19}/><small className="font-mono text-[7px] tracking-[1px]">{l}</small>
          </button>))}
        <button onClick={()=>setSheet(true)} className="press flex flex-col items-center gap-1 px-4 py-1.5 rounded-2xl text-white">
          <span className="w-[26px] h-[26px] -my-[3px] rounded-full grid place-items-center" style={{background:'linear-gradient(160deg,#ff2e3e,#8d0917)',boxShadow:'0 6px 18px -4px rgba(224,30,47,.7)'}}><Ic n="grid" s={13}/></span>
          <small className="font-mono text-[7px] tracking-[1px]">Módulos</small>
        </button>
      </div>
    </nav>

    <ModuleSheet open={sheet} onClose={()=>setSheet(false)} enabled={enabled} setEnabled={setEnabled}/>
  </>;
}

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