/* ARKHAM — shared components: icons, poster, card, hover preview, row */
const { useState, useRef, useEffect, useCallback, useContext, createContext } = React;

const AppCtx = createContext({});

/* ----------------------------- icons ----------------------------- */
const Icon = {
  Play: (p) => (<svg viewBox="0 0 24 24" width={p.s||22} height={p.s||22} fill="currentColor" {...p}><path d="M5 3.5v17a1 1 0 0 0 1.54.84l13.2-8.5a1 1 0 0 0 0-1.68L6.54 2.66A1 1 0 0 0 5 3.5z"/></svg>),
  Pause: (p) => (<svg viewBox="0 0 24 24" width={p.s||22} height={p.s||22} fill="currentColor" {...p}><rect x="5" y="3.5" width="5" height="17" rx="1"/><rect x="14" y="3.5" width="5" height="17" rx="1"/></svg>),
  Info: (p) => (<svg viewBox="0 0 24 24" width={p.s||22} height={p.s||22} fill="none" stroke="currentColor" strokeWidth="1.8" {...p}><circle cx="12" cy="12" r="9.2"/><line x1="12" y1="11" x2="12" y2="16.5"/><circle cx="12" cy="7.6" r="0.4" fill="currentColor" stroke="none"/><circle cx="12" cy="7.7" r="1" fill="currentColor" stroke="none"/></svg>),
  Plus: (p) => (<svg viewBox="0 0 24 24" width={p.s||20} height={p.s||20} fill="none" stroke="currentColor" strokeWidth="2.2" strokeLinecap="round" {...p}><line x1="12" y1="5" x2="12" y2="19"/><line x1="5" y1="12" x2="19" y2="12"/></svg>),
  Check: (p) => (<svg viewBox="0 0 24 24" width={p.s||20} height={p.s||20} fill="none" stroke="currentColor" strokeWidth="2.4" strokeLinecap="round" strokeLinejoin="round" {...p}><polyline points="4 12.5 9.5 18 20 6"/></svg>),
  Like: (p) => (<svg viewBox="0 0 24 24" width={p.s||19} height={p.s||19} fill="none" stroke="currentColor" strokeWidth="1.7" {...p}><path d="M7 10v9H4a1 1 0 0 1-1-1v-7a1 1 0 0 1 1-1h3zm0 0l4.2-6.4a1.6 1.6 0 0 1 2.9 1.1L13.3 9h5.1a1.8 1.8 0 0 1 1.77 2.2l-1.5 6.5A2 2 0 0 1 16.7 19H7"/></svg>),
  VolOn: (p) => (<svg viewBox="0 0 24 24" width={p.s||20} height={p.s||20} fill="none" stroke="currentColor" strokeWidth="1.7" strokeLinejoin="round" {...p}><path d="M4 9v6h3.5L13 19V5L7.5 9H4z" fill="currentColor"/><path d="M16 8.5a4 4 0 0 1 0 7M18.5 6a7.5 7.5 0 0 1 0 12"/></svg>),
  VolOff: (p) => (<svg viewBox="0 0 24 24" width={p.s||20} height={p.s||20} fill="none" stroke="currentColor" strokeWidth="1.7" strokeLinecap="round" strokeLinejoin="round" {...p}><path d="M4 9v6h3.5L13 19V5L7.5 9H4z" fill="currentColor"/><line x1="16.5" y1="9.5" x2="21" y2="14"/><line x1="21" y1="9.5" x2="16.5" y2="14"/></svg>),
  Search: (p) => (<svg viewBox="0 0 24 24" width={p.s||22} height={p.s||22} fill="none" stroke="currentColor" strokeWidth="1.9" strokeLinecap="round" {...p}><circle cx="10.5" cy="10.5" r="7"/><line x1="15.6" y1="15.6" x2="21" y2="21"/></svg>),
  Bell: (p) => (<svg viewBox="0 0 24 24" width={p.s||22} height={p.s||22} fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round" {...p}><path d="M6 9a6 6 0 0 1 12 0c0 5 2 6 2 6H4s2-1 2-6z"/><path d="M10 20a2 2 0 0 0 4 0"/></svg>),
  Chev: (p) => (<svg viewBox="0 0 24 24" width={p.s||16} height={p.s||16} fill="none" stroke="currentColor" strokeWidth="2.2" strokeLinecap="round" strokeLinejoin="round" {...p}><polyline points="6 9 12 15 18 9"/></svg>),
  ChevR: (p) => (<svg viewBox="0 0 24 24" width={p.s||26} height={p.s||26} fill="none" stroke="currentColor" strokeWidth="2.4" strokeLinecap="round" strokeLinejoin="round" {...p}><polyline points="9 6 15 12 9 18"/></svg>),
  ChevL: (p) => (<svg viewBox="0 0 24 24" width={p.s||26} height={p.s||26} fill="none" stroke="currentColor" strokeWidth="2.4" strokeLinecap="round" strokeLinejoin="round" {...p}><polyline points="15 6 9 12 15 18"/></svg>),
  Close: (p) => (<svg viewBox="0 0 24 24" width={p.s||20} height={p.s||20} fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" {...p}><line x1="6" y1="6" x2="18" y2="18"/><line x1="18" y1="6" x2="6" y2="18"/></svg>),
  Replay: (p) => (<svg viewBox="0 0 24 24" width={p.s||24} height={p.s||24} fill="none" stroke="currentColor" strokeWidth="1.7" strokeLinecap="round" strokeLinejoin="round" {...p}><path d="M3 12a9 9 0 1 0 2.6-6.3"/><polyline points="3 4 3 9 8 9"/></svg>),
  Back: (p) => (<svg viewBox="0 0 24 24" width={p.s||30} height={p.s||30} fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" {...p}><line x1="20" y1="12" x2="5" y2="12"/><polyline points="11 5 4 12 11 19"/></svg>),
  Quote: (p) => (<svg viewBox="0 0 24 24" width={p.s||20} height={p.s||20} fill="currentColor" {...p}><path d="M3 11.5C3 7.9 5.6 5.3 9 5v2.4c-1.9.3-3.2 1.7-3.2 3.4 0 .1 0 .3.1.4.3-.2.7-.3 1.2-.3 1.7 0 3 1.3 3 3.1 0 1.8-1.4 3.1-3.2 3.1C5 17.1 3 14.9 3 11.5zm10.5 0C13.5 7.9 16.1 5.3 19.5 5v2.4c-1.9.3-3.2 1.7-3.2 3.4 0 .1 0 .3.1.4.3-.2.7-.3 1.2-.3 1.7 0 3 1.3 3 3.1 0 1.8-1.4 3.1-3.2 3.1-2.9 0-4.9-2.2-4.9-5.6z"/></svg>),
  Mic: (p) => (<svg viewBox="0 0 24 24" width={p.s||20} height={p.s||20} fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round" {...p}><rect x="9" y="2" width="6" height="12" rx="3"/><path d="M5 11a7 7 0 0 0 14 0"/><line x1="12" y1="18" x2="12" y2="22"/><line x1="8" y1="22" x2="16" y2="22"/></svg>),
  Pin: (p) => (<svg viewBox="0 0 24 24" width={p.s||20} height={p.s||20} fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round" {...p}><path d="M12 22s7-6.4 7-12a7 7 0 1 0-14 0c0 5.6 7 12 7 12z"/><circle cx="12" cy="10" r="2.6"/></svg>),
  Trophy: (p) => (<svg viewBox="0 0 24 24" width={p.s||20} height={p.s||20} fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round" {...p}><path d="M7 4h10v4a5 5 0 0 1-10 0V4z"/><path d="M7 5H4v2a3 3 0 0 0 3 3M17 5h3v2a3 3 0 0 1-3 3"/><line x1="12" y1="13" x2="12" y2="17"/><path d="M9 20h6M10 20l.4-3h3.2l.4 3"/></svg>),
  Download: (p) => (<svg viewBox="0 0 24 24" width={p.s||20} height={p.s||20} fill="none" stroke="currentColor" strokeWidth="1.9" strokeLinecap="round" strokeLinejoin="round" {...p}><path d="M12 3v12"/><polyline points="7 10 12 15 17 10"/><path d="M4 19h16"/></svg>),
  Mail: (p) => (<svg viewBox="0 0 24 24" width={p.s||20} height={p.s||20} fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round" {...p}><rect x="3" y="5" width="18" height="14" rx="2"/><path d="M3 7l9 6 9-6"/></svg>),
  Shuffle: (p) => (<svg viewBox="0 0 24 24" width={p.s||20} height={p.s||20} fill="none" stroke="currentColor" strokeWidth="1.9" strokeLinecap="round" strokeLinejoin="round" {...p}><path d="M16 3h5v5"/><path d="M4 20L21 3"/><path d="M21 16v5h-5"/><path d="M15 15l6 6"/><path d="M4 4l5 5"/></svg>),
  Dice: (p) => (<svg viewBox="0 0 24 24" width={p.s||21} height={p.s||21} fill="none" stroke="currentColor" strokeWidth="1.8" {...p}><rect x="3" y="3" width="18" height="18" rx="5"/><circle cx="8" cy="8" r="1.4" fill="currentColor" stroke="none"/><circle cx="16" cy="8" r="1.4" fill="currentColor" stroke="none"/><circle cx="12" cy="12" r="1.4" fill="currentColor" stroke="none"/><circle cx="8" cy="16" r="1.4" fill="currentColor" stroke="none"/><circle cx="16" cy="16" r="1.4" fill="currentColor" stroke="none"/></svg>),
  IG: (p) => (<svg viewBox="0 0 24 24" width={p.s||22} height={p.s||22} fill="none" stroke="currentColor" strokeWidth="1.8" {...p}><rect x="3" y="3" width="18" height="18" rx="5"/><circle cx="12" cy="12" r="4"/><circle cx="17.2" cy="6.8" r="1.1" fill="currentColor" stroke="none"/></svg>),
  YT: (p) => (<svg viewBox="0 0 24 24" width={p.s||22} height={p.s||22} fill="currentColor" {...p}><path d="M23 12s0-3.2-.4-4.7a2.5 2.5 0 0 0-1.7-1.8C19.3 5 12 5 12 5s-7.3 0-8.9.5A2.5 2.5 0 0 0 1.4 7.3C1 8.8 1 12 1 12s0 3.2.4 4.7a2.5 2.5 0 0 0 1.7 1.8C4.7 19 12 19 12 19s7.3 0 8.9-.5a2.5 2.5 0 0 0 1.7-1.8C23 15.2 23 12 23 12zM9.8 15.1V8.9l5.3 3.1z"/></svg>),
  FB: (p) => (<svg viewBox="0 0 24 24" width={p.s||22} height={p.s||22} fill="currentColor" {...p}><path d="M14 8.5V7c0-.8.5-1 1-1h2V3h-3c-2.2 0-3.5 1.4-3.5 3.7V8.5H8V12h2.5v9H14v-9h2.6l.4-3.5H14z"/></svg>),
  TikTok: (p) => (<svg viewBox="0 0 24 24" width={p.s||22} height={p.s||22} fill="currentColor" {...p}><path d="M16.5 3c.3 2.1 1.5 3.6 3.5 3.9v2.6c-1.3.1-2.5-.3-3.6-1v5.7c0 4-3.3 6.6-6.8 5.6-2.4-.7-3.9-3-3.6-5.5.3-2.6 2.6-4.5 5.3-4.3v2.8c-.4-.1-.8-.2-1.3-.1-1.2.1-2 1-2 2.2 0 1.3 1 2.2 2.3 2.1 1.3-.1 2-1 2-2.4V3h2.5z"/></svg>)
};

/* ARKHAM "A" isotype (real brand asset) */
function ArkhamMark({ size = 26 }) {
  return (
    <img src="assets/arkham-iso-white.png" alt="ARKHAM"
      style={{ height: size, width: "auto", display: "block", objectFit: "contain" }} />
  );
}

/* poster background — foto de portada real si existe, si no el degradado placeholder */
function posterStyle(p) {
  const cover = p.media && p.media.cover;
  if (cover && cover.src) {
    const fx = cover.focal ? Math.round(cover.focal.x * 100) : 50;
    const fy = cover.focal ? Math.round(cover.focal.y * 100) : 50;
    return {
      backgroundImage: `url("${cover.src}")`,
      backgroundSize: "cover",
      backgroundPosition: `${fx}% ${fy}%`,
      backgroundRepeat: "no-repeat"
    };
  }
  const h = p.hue, s = p.sat;
  return {
    background: `linear-gradient(145deg, hsl(${h} ${s}% ${p.dark1}%) 0%, hsl(${h} ${Math.max(s-6,4)}% ${p.dark2}%) 100%)`
  };
}

function Poster({ p, showTitle = true, showBadges = true, showLogo = true }) {
  const hasCover = !!(p.media && p.media.cover && p.media.cover.src);
  return (
    <div className="poster-img-wrap" style={{ position: "absolute", inset: 0 }}>
      <div className="poster-img" style={posterStyle(p)} />
      <div className="poster-tex" />
      <div className="poster-vig" />
      {showLogo && !hasCover && <div className="poster-logo"><ArkhamMark size={26} /></div>}
      {showTitle && (
        <div className={"poster-title " + p.titleClass}>
          {p.title}
          {p.sub && <span className="poster-sub">{p.sub}</span>}
        </div>
      )}
      {showBadges && p.top10 && (
        <div className="badge-top10"><span className="t">TOP</span><span className="n">10</span></div>
      )}
      {showBadges && p.nuevo && <div className="badge-nuevo">Proyecto Nuevo</div>}
      {showBadges && p.progress != null && (
        <div className="progress"><span style={{ width: p.progress + "%" }} /></div>
      )}
    </div>
  );
}

/* ------------------------- hover preview ------------------------- */
function HoverPreview({ p, rect, onClose }) {
  const ctx = useContext(AppCtx);
  const inList = ctx.myList.includes(p.id);
  const pw = 360;
  let left = rect.left + rect.width / 2 - pw / 2;
  left = Math.max(16, Math.min(left, window.innerWidth - pw - 16));
  let top = rect.top - 36;
  top = Math.max(80, top);
  return (
    <div className="preview" style={{ left, top, width: pw }}
      onMouseLeave={onClose}
      onClick={() => { onClose(); ctx.openDetail(p.id); }}>
      <div className="preview-poster">
        <Poster p={p} />
      </div>
      <div className="preview-body" onClick={(e) => e.stopPropagation()}>
        <div className="preview-actions">
          <button className="circle-btn solid" title="Reproducir" onClick={() => { onClose(); ctx.play(p.id); }}><Icon.Play s={18} /></button>
          <button className={"circle-btn" + (inList ? " green" : "")} title={inList ? "En Mi lista" : "Agregar a Mi lista"}
            onClick={(e) => { e.stopPropagation(); ctx.toggleList(p.id); }}>
            {inList ? <Icon.Check s={18} /> : <Icon.Plus s={18} />}
          </button>
          <button className="circle-btn" title="Me gusta" onClick={(e) => e.stopPropagation()}><Icon.Like s={17} /></button>
          <button className="circle-btn last" title="Más información" onClick={() => { onClose(); ctx.openDetail(p.id); }}><Icon.Chev s={18} /></button>
        </div>
        <div className="preview-meta">
          <span className="match">{p.match}% para ti</span>
          <span className="age-pill">{p.rating}</span>
          <span style={{ color: "var(--txt-2)", fontSize: 13 }}>{p.year}</span>
          {p.progress != null && <span style={{ color: "var(--red)", fontSize: 12.5, fontWeight: 600 }}>WIP {p.progress}%</span>}
        </div>
        <div className="preview-genres">
          {p.genres.slice(0, 3).map((g) => <span key={g}>{g}</span>)}
        </div>
      </div>
    </div>
  );
}

/* ----------------------------- card ----------------------------- */
function Card({ p, tall = false }) {
  const ctx = useContext(AppCtx);
  const ref = useRef(null);
  const timer = useRef(null);
  const [hover, setHover] = useState(false);
  const [rect, setRect] = useState(null);

  const enter = () => {
    clearTimeout(timer.current);
    timer.current = setTimeout(() => {
      if (ref.current) { setRect(ref.current.getBoundingClientRect()); setHover(true); }
    }, 380);
  };
  const leave = () => { clearTimeout(timer.current); };
  useEffect(() => () => clearTimeout(timer.current), []);

  return (
    <>
      <div className={"card" + (tall ? " tall" : "")} ref={ref}
        onMouseEnter={enter} onMouseLeave={leave}
        onClick={() => ctx.openDetail(p.id)}>
        <div className="poster"><Poster p={p} /></div>
      </div>
      {hover && rect && <HoverPreview p={p} rect={rect} onClose={() => setHover(false)} />}
    </>
  );
}

/* ----------------------------- row ----------------------------- */
function Row({ title, ids, explore }) {
  const trackRef = useRef(null);
  const data = window.ARKHAM.byId;
  const scrollBy = (dir) => {
    const el = trackRef.current;
    if (el) el.scrollBy({ left: dir * (el.clientWidth * 0.82), behavior: "smooth" });
  };
  return (
    <div className="row">
      <h2 className="row-title">{title}{explore && <span className="row-explore">Explorar todo ›</span>}</h2>
      <div className="row-track-wrap">
        <button className="row-arrow left" onClick={() => scrollBy(-1)} aria-label="anterior"><Icon.ChevL /></button>
        <div className="row-track" ref={trackRef}>
          {ids.map((id) => data[id] ? <Card key={id} p={data[id]} /> : null)}
        </div>
        <button className="row-arrow right" onClick={() => scrollBy(1)} aria-label="siguiente"><Icon.ChevR /></button>
      </div>
    </div>
  );
}

Object.assign(window, { AppCtx, Icon, ArkhamMark, Poster, HoverPreview, Card, Row, posterStyle });
