/* global React */
const { useState, useEffect, useRef, createContext, useContext } = React;

// ============================================================
// GA4 event helpers
// ============================================================
function trackPdfDownload() {
  if (typeof gtag === "function") {
    gtag("event", "file_download", {
      file_name: "guia-empleo-2026.pdf",
      file_extension: "pdf",
      link_text: "Descargar PDF Guía de Empleo 2026",
    });
  }
}

// ============================================================
// UTM campaign tracking
// ============================================================
const UTM_PARAMS = "utm_source=guia-empleo-2026&utm_medium=web&utm_campaign=guia-empleo-tercer-sector-2026";
function utmLink(url) {
  if (!url || url.startsWith("mailto:") || url.startsWith("assets/") || url.startsWith("/") || url.startsWith("#")) return url;
  return url + (url.includes("?") ? "&" : "?") + UTM_PARAMS;
}

// ============================================================
// Router (static-pages mode)
// ============================================================
// Internal route key (e.g. "/general/datos") → public URL (e.g. "conocer-el-sector/datos/")
const AREA_MAP = { "general": "conocer-el-sector", "busco-empleo": "busco-empleo", "ong": "soy-una-ong" };

function publicHref(to) {
  if (!to || to === "/") return "index.html";
  const segs = to.replace(/^\//, "").split("/").filter(Boolean);
  if (segs.length) segs[0] = AREA_MAP[segs[0]] || segs[0];
  return segs.join("/") + "/index.html";
}

const RouterCtx = createContext(null);
function useRoute() { return useContext(RouterCtx); }

function Link({ to, children, className = "", ...rest }) {
  return <a href={publicHref(to)} className={className} {...rest}>{children}</a>;
}

// ============================================================
// Top bar
// ============================================================
function TopBar() {
  const { path } = useRoute();
  const area = (path.split("/")[1] || "home");
  const [open, setOpen] = useState(false);
  const isActive = (key) => area === key;
  const close = () => setOpen(false);
  useEffect(() => {
    document.body.style.overflow = open ? "hidden" : "";
    if (!open) return () => { document.body.style.overflow = ""; };
    const onKey = (e) => { if (e.key === "Escape") { setOpen(false); } };
    document.addEventListener("keydown", onKey);
    return () => { document.body.style.overflow = ""; document.removeEventListener("keydown", onKey); };
  }, [open]);
  const Btn = ({ to, label, areaKey }) => (
    <a href={publicHref(to)} className={isActive(areaKey) ? "active" : ""} onClick={close}>{label}</a>
  );
  return (
    <React.Fragment>
      <header className="topbar">
        <div className="topbar-inner">
          <a href={publicHref("/")} aria-label="Hacesfalta.org" className="topbar-brand">
            <img src="assets/logo-hacesfalta.svg" alt="Hacesfalta.org" className="logo" />
          </a>
          <button
            className={"nav-toggle" + (open ? " open" : "")}
            aria-label={open ? "Cerrar menú" : "Abrir menú"}
            aria-expanded={open}
            onClick={() => setOpen(o => !o)}
          >
            <span></span><span></span><span></span>
          </button>
        </div>
      </header>
      {open && <div className="nav-backdrop" onClick={close}></div>}
      <nav className={"mobile-nav" + (open ? " open" : "")} aria-label="Navegación principal">
        <Btn to="/general" label="Conocer el sector" areaKey="general" />
        <Btn to="/busco-empleo" label="Busco empleo" areaKey="busco-empleo" />
        <Btn to="/ong" label="Soy una ONG" areaKey="ong" />
      </nav>
      <nav className="desktop-nav" aria-label="Navegación principal">
        <Btn to="/general" label="Conocer el sector" areaKey="general" />
        <Btn to="/busco-empleo" label="Busco empleo" areaKey="busco-empleo" />
        <Btn to="/ong" label="Soy una ONG" areaKey="ong" />
      </nav>
    </React.Fragment>
  );
}

// ============================================================
// Breadcrumbs
// ============================================================
function Breadcrumbs({ trail }) {
  return (
    <nav className="breadcrumbs wrap" aria-label="Migas de pan">
      <ol style={{ display: "contents", listStyle: "none", margin: 0, padding: 0 }}>
        {trail.map((t, i) => (
          <li key={i} style={{ display: "inline-flex", alignItems: "center", gap: 8 }}>
            {i > 0 && <span className="sep" aria-hidden="true">/</span>}
            {t.to ? <Link to={t.to}>{t.label}</Link> : <span className="here" aria-current="page">{t.label}</span>}
          </li>
        ))}
      </ol>
    </nav>
  );
}

// ============================================================
// Sidebar
// ============================================================
function SideNav({ area, items, currentSlug }) {
  return (
    <aside className="side-nav">
      <div className="area-label">{area.label}</div>
      <ul>
        {items.map((it) => (
          <li key={it.slug}>
            <a href={publicHref(`/${area.base}/${it.slug}`)}
               className={currentSlug === it.slug ? "active" : ""}>
              {it.label}
            </a>
          </li>
        ))}
      </ul>
    </aside>
  );
}

// ============================================================
// Icons (used in landing card grids)
// ============================================================
const ICON_PATHS = {
  // General
  "presentacion": <><path d="M2 4h7a3 3 0 0 1 3 3v13a2 2 0 0 0-2-2H2z"/><path d="M22 4h-7a3 3 0 0 0-3 3v13a2 2 0 0 1 2-2h8z"/></>,
  "datos": <><path d="M6 20v-6"/><path d="M12 20V10"/><path d="M18 20V4"/><path d="M3 20h18"/></>,
  "tendencias": <><path d="M3 17l6-6 4 4 8-8"/><path d="M14 7h7v7"/></>,
  "entidades": <><path d="M3 21h18"/><path d="M5 21V8l7-4 7 4v13"/><path d="M10 21v-6h4v6"/><path d="M9 11h.01"/><path d="M15 11h.01"/></>,
  "dei": <><circle cx="9" cy="8" r="3"/><circle cx="17" cy="9" r="2.5"/><path d="M3 20c.7-3 3.2-5 6-5s5.3 2 6 5"/><path d="M14 19c.5-2 2-3.5 4-3.5s3.5 1.5 4 3.5"/></>,
  // Busco empleo
  "que-necesito": <><circle cx="12" cy="12" r="10"/><path d="M15.5 8.5l-2 5-5 2 2-5z"/></>,
  "areas": <><path d="M21 12A9 9 0 1 1 8 3.5"/><path d="M22 12A10 10 0 0 0 12 2v10z"/></>,
  "categorias": <><rect x="3" y="3" width="7" height="7" rx="1"/><rect x="14" y="3" width="7" height="7" rx="1"/><rect x="3" y="14" width="7" height="7" rx="1"/><rect x="14" y="14" width="7" height="7" rx="1"/></>,
  "ofertas": <><rect x="4" y="4" width="16" height="16" rx="2"/><path d="M8 9h8"/><path d="M8 13h8"/><path d="M8 17h5"/></>,
  "como-buscar": <><circle cx="11" cy="11" r="7"/><path d="M21 21l-4.3-4.3"/></>,
  "soft-skills": <><path d="M12 3l1.9 5.4L19 10l-5.1 1.6L12 17l-1.9-5.4L5 10l5.1-1.6z"/><path d="M19 17v4"/><path d="M17 19h4"/><path d="M5 5v3"/></>,
  "cv": <><path d="M14 3H6a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V9z"/><path d="M14 3v6h6"/><path d="M8 13h8"/><path d="M8 17h5"/></>,
  "carta": <><path d="M3 8l9-5 9 5v12a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z"/><path d="M3 8l9 6 9-6"/></>,
  "email": <><rect x="3" y="5" width="18" height="14" rx="2"/><path d="M3 7l9 7 9-7"/></>,
  "entrevista": <><path d="M21 14a2 2 0 0 1-2 2H8l-5 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z"/><path d="M8 9h8"/><path d="M8 12h5"/></>,
  "portal": <><path d="M5 16c-1 1-1.5 5-1.5 5s4-.5 5-1.5"/><path d="M12 15l-3-3a20 20 0 0 1 2-4 12 12 0 0 1 11-6c0 3-1 7-6 11a20 20 0 0 1-4 2z"/><circle cx="15" cy="9" r="1.5"/></>,
  // Soy una ONG
  "contexto": <><circle cx="12" cy="12" r="9"/><path d="M3 12h18"/><path d="M12 3a14 14 0 0 1 0 18M12 3a14 14 0 0 0 0 18"/></>,
  "perfiles": <><circle cx="9" cy="8" r="3"/><path d="M3 20c.7-3.5 3.4-6 6-6s5.3 2.5 6 6"/><circle cx="17" cy="9" r="2.5"/><path d="M15 20c.5-3 2-5 4-5"/></>,
  "valoran": <><path d="M20.8 5.6a5 5 0 0 0-7 0L12 7.1l-1.8-1.5a5 5 0 0 0-7 7L12 21l8.8-8.4a5 5 0 0 0 0-7z"/></>,
  "seleccion": <><path d="M3 4h18l-7 9v6l-4 2v-8z"/></>,
  "transparencia": <><path d="M2 12s4-7 10-7 10 7 10 7-4 7-10 7S2 12 2 12z"/><circle cx="12" cy="12" r="3"/></>,
  "inclusion": <><circle cx="12" cy="5" r="1.5"/><path d="M10 9h4l1 5 3 2"/><path d="M11 14a4 4 0 1 0 4 4"/></>,
  "talento": <><path d="M12 3l2.6 5.4L20 9.3l-4 4 1 5.7L12 16.5 6.9 19l1-5.7-4-4 5.4-.9z"/></>,
  "publicar": <><path d="M3 10v4l14 4V6z"/><path d="M17 8v8"/><path d="M11 18c-.5 2-2 3-3.5 3S5 20 5 18"/></>,
};

function Icon({ slug, area }) {
  // ofertas appears in both busco and ong areas - use same icon, fine
  const p = ICON_PATHS[slug] || <circle cx="12" cy="12" r="9"/>;
  return (
    <svg className="card-icon" width="32" height="32" viewBox="0 0 24 24" fill="none"
         stroke="currentColor" strokeWidth="1.6" strokeLinecap="round" strokeLinejoin="round"
         aria-hidden="true">
      {p}
    </svg>
  );
}

// ============================================================
// Generic UI
// ============================================================
function Eyebrow({ children }) { return <div className="eyebrow">{children}</div>; }

function Callout({ kind = "tip", label, children }) {
  return (
    <div className={`callout ${kind}`}>
      {label && <div className="label">{label}</div>}
      <div>{children}</div>
    </div>
  );
}

function Stat({ big, label, src }) {
  return (
    <div className="stat">
      <div className="big">{big}</div>
      <div className="lbl">{label}</div>
      {src && <div className="src">Fte.: {src}</div>}
    </div>
  );
}

function Bar({ label, value, max = 100, suffix = "%" }) {
  return (
    <div className="bar-row" role="img" aria-label={`${label}: ${value}${suffix}`}>
      <div aria-hidden="true">{label}</div>
      <div className="bar-bg" aria-hidden="true"><div className="bar-fg" style={{ width: `${value/max*100}%` }} /></div>
      <div className="val" aria-hidden="true">{value}{suffix}</div>
    </div>
  );
}

// Proportional area chart: a hero segment for "atención directa" and
// the remaining areas as a stacked horizontal bar below.
function AreaProportionChart({ segments }) {
  const hero = segments.find(s => s.big) || segments[0];
  const rest = segments.filter(s => s !== hero);
  const restTotal = rest.reduce((a, s) => a + s.value, 0);
  const palette = ["#5b8def","#3aa78a","#e7a52e","#b06ed8","#e5717a","#4e7cbf","#7aa441","#c47a3a"];
  const summary = segments.map(s => `${s.label}: ${s.value}%`).join(", ");
  return (
    <div className="prop-chart" role="img" aria-label={`Distribución por área: ${summary}`}>
      <div className="prop-hero" style={{ flexBasis: `${hero.value}%` }}>
        <div className="prop-hero-num">{hero.value}<span>%</span></div>
        <div className="prop-hero-label">{hero.label}</div>
      </div>
      <div className="prop-rest" style={{ flexBasis: `${restTotal}%` }}>
        <div className="prop-rest-label">El otro <strong>{restTotal}%</strong>, repartido entre 8 áreas</div>
        <div className="prop-rest-bar">
          {rest.map((s, i) => (
            <div key={i} className="prop-seg" title={`${s.label} · ${s.value}%`}
              style={{ flex: s.value, background: palette[i % palette.length] }}>
              <span>{s.value}%</span>
            </div>
          ))}
        </div>
        <ul className="prop-legend">
          {rest.map((s, i) => (
            <li key={i}><span className="dot" style={{ background: palette[i % palette.length] }} />{s.label}<em>{s.value}%</em></li>
          ))}
        </ul>
      </div>
    </div>
  );
}

// Stacked bar showing salary distribution per professional level (Guía p.32).
function SalaryBreakdown({ rows }) {
  const bands = [
    { key: "becas",    label: "Becas / sin remunerar",     color: "#d9d4cb" },
    { key: "low",      label: "Hasta 18 k€",               color: "#f0c5cb" },
    { key: "mid",      label: "18 – 24 k€",                color: "#e98ea0" },
    { key: "high",     label: "24 – 36 k€",                color: "#9a4d6b" },
    { key: "top",      label: "Más de 36 k€",              color: "#3e2638" },
  ];
  const summary = rows.map(r => {
    const parts = bands.filter(b => r[b.key]).map(b => `${b.label}: ${r[b.key]}%`);
    return `${r.level} (${parts.join(", ")})`;
  }).join("; ");
  return (
    <div className="salary-chart" role="img" aria-label={`Distribución salarial: ${summary}`}>
      <div className="salary-rows">
        {rows.map((r, i) => (
          <div key={i} className="salary-row">
            <div className="salary-row-label">{r.level}</div>
            <div className="salary-row-bar">
              {bands.map(b => r[b.key] ? (
                <div key={b.key} className="salary-seg"
                  style={{ flex: r[b.key], background: b.color, color: b.color === "#3e2638" || b.color === "#9a4d6b" ? "#fff" : "var(--ink-1)" }}>
                  <span>{r[b.key]}%</span>
                </div>
              ) : null)}
            </div>
          </div>
        ))}
      </div>
      <ul className="salary-legend">
        {bands.map(b => (
          <li key={b.key}><span className="dot" style={{ background: b.color }} />{b.label}</li>
        ))}
      </ul>
    </div>
  );
}

let _accIdCounter = 0;
function Accordion({ items }) {
  const [open, setOpen] = useState(null);
  const [prefix] = useState(() => `acc-${++_accIdCounter}`);
  return (
    <div className="acc">
      {items.map((it, i) => (
        <div key={i} className={`acc-item ${open === i ? "open" : ""}`}>
          <button className="acc-toggle" id={`${prefix}-btn-${i}`}
                  aria-expanded={open === i} aria-controls={`${prefix}-panel-${i}`}
                  onClick={() => setOpen(open === i ? null : i)}>
            <span>{it.q}</span><span className="ico" aria-hidden="true">+</span>
          </button>
          <div className="acc-body" id={`${prefix}-panel-${i}`}
               role="region" aria-labelledby={`${prefix}-btn-${i}`}>{it.a}</div>
        </div>
      ))}
    </div>
  );
}

let _tabIdCounter = 0;
function Tabs({ tabs }) {
  const [i, setI] = useState(0);
  const [prefix] = useState(() => `tabs-${++_tabIdCounter}`);
  return (
    <div>
      <div className="tabs-bar" role="tablist">
        {tabs.map((t, idx) => (
          <button key={idx} role="tab" id={`${prefix}-tab-${idx}`}
                  aria-selected={i === idx} aria-controls={`${prefix}-panel-${idx}`}
                  className={i === idx ? "active" : ""} onClick={() => setI(idx)}>{t.label}</button>
        ))}
      </div>
      <div role="tabpanel" id={`${prefix}-panel-${i}`} aria-labelledby={`${prefix}-tab-${i}`}>
        {tabs[i].content}
      </div>
    </div>
  );
}

function Checklist({ items }) {
  const [done, setDone] = useState(new Set());
  const toggle = (i) => { const n = new Set(done); n.has(i) ? n.delete(i) : n.add(i); setDone(n); };
  const handleKey = (i) => (e) => { if (e.key === "Enter" || e.key === " ") { e.preventDefault(); toggle(i); } };
  return (
    <ul className="checklist" role="list">
      {items.map((it, i) => (
        <li key={i} className={done.has(i) ? "done" : ""} role="checkbox" aria-checked={done.has(i)}
            tabIndex={0} onClick={() => toggle(i)} onKeyDown={handleKey(i)}>{it}</li>
      ))}
    </ul>
  );
}

function CTABlock({ title, sub, btnLabel, btnTo, btnHref }) {
  return (
    <div className="cta-block">
      <div><h3>{title}</h3><p>{sub}</p></div>
      <div>
        {btnHref ?
          <a className="btn btn-pink" href={utmLink(btnHref)} target="_blank" rel="noopener">{btnLabel} →</a> :
          <a className="btn btn-pink" href={publicHref(btnTo)}>{btnLabel} →</a>
        }
      </div>
    </div>
  );
}

function Related({ items }) {
  return (
    <div className="related">
      <h3>También te puede interesar</h3>
      <div className="related-grid">
        {items.map((it, i) => (
          <a key={i} className="related-card" href={publicHref(it.to)}>
            <div className="area">{it.area}</div>
            <div className="ttl">{it.title}</div>
          </a>
        ))}
      </div>
    </div>
  );
}

function ImagePh({ label, height = 220 }) {
  return <div className="image-ph" style={{ minHeight: height }}>{label}</div>;
}

let _chipIdCounter = 0;
function ChipRow({ chips }) {
  const [active, setActive] = useState(0);
  const [prefix] = useState(() => `chips-${++_chipIdCounter}`);
  return (
    <>
      <div className="chip-row" role="tablist">
        {chips.map((c, i) => (
          <button key={i} role="tab" id={`${prefix}-tab-${i}`}
                  aria-selected={active === i} aria-controls={`${prefix}-panel-${i}`}
                  className={`chip ${active === i ? "active" : ""}`} onClick={() => setActive(i)}>{c.label}</button>
        ))}
      </div>
      <div role="tabpanel" id={`${prefix}-panel-${active}`} aria-labelledby={`${prefix}-tab-${active}`}>
        {chips[active].content}
      </div>
    </>
  );
}

// ============================================================
// Section nav (prev / next within the same guide section)
// ============================================================
function SectionNav({ area, items, slug }) {
  const idx = items.findIndex(i => i.slug === slug);
  if (idx < 0) return null;
  const prev = idx > 0 ? items[idx - 1] : null;
  const next = idx < items.length - 1 ? items[idx + 1] : null;
  if (!prev && !next) return null;
  return (
    <nav className="section-nav" aria-label="Navegación de sección">
      {prev && (
        <a className="sn-prev sn-prev-only" href={publicHref(`/${area.base}/${prev.slug}`)}>
          <span className="sn-eyebrow">
            <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.2" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true"><path d="M19 12H5"/><path d="M12 19l-7-7 7-7"/></svg>
            Sección anterior
          </span>
          <span className="sn-title">{prev.label}</span>
        </a>
      )}
      {next && (
        <a className="sn-next sn-next-only" href={publicHref(`/${area.base}/${next.slug}`)}>
          <span className="sn-eyebrow">
            Siguiente sección
            <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.2" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true"><path d="M5 12h14"/><path d="M12 5l7 7-7 7"/></svg>
          </span>
          <span className="sn-title">{next.label}</span>
        </a>
      )}
    </nav>
  );
}

// ============================================================
// ArticlePage shell
// ============================================================
function ArticlePage({ area, items, slug, trail, children, related }) {
  const cur = items.find(i => i.slug === slug) || items[0];
  const trailFull = [
    { label: "Inicio", to: "/" },
    { label: area.label, to: `/${area.base}` },
    { label: cur.label }
  ];
  return (
    <>
      <Breadcrumbs trail={trail || trailFull} />
      <div className="wrap with-sidebar">
        <SideNav area={area} items={items} currentSlug={cur.slug} />
        <article className="article-body">
          {children}
          <SectionNav area={area} items={items} slug={cur.slug} />
          {related && <Related items={related} />}
        </article>
      </div>
    </>
  );
}

// Helper for landing card grids – button "go to" with full nav
function navigate(to) { window.location.href = publicHref(to); }

Object.assign(window, {
  RouterCtx, useRoute, Link, TopBar, Breadcrumbs, SideNav,
  Eyebrow, Callout, Stat, Bar, AreaProportionChart, SalaryBreakdown, Accordion, Tabs, Checklist,
  CTABlock, Related, ImagePh, ChipRow, ArticlePage, SectionNav, Icon,
  publicHref, navigate, utmLink, trackPdfDownload, AREA_MAP
});
