/* ═══════════════════════════════════════════════════════════════════════════
   ESBART — Shared <Accordion> component (acordió únic del page-kit)
   Un sol motor de comportament per a tots els acordions del site.

   Props:
     items        — [{ id, title?, num?, titleStyle?, content?, ...lliure }]
     defaultOpen  — id obert inicialment (mode no controlat)
     open         — id obert (mode controlat; amb onChange)
     onChange     — callback(id | null) quan canvia l'obert
     classes      — override de classes { root, head, body, inner, open }
                    (default: pk-acc / pk-acc__head / pk-acc__body / pk-acc__inner / is-open)
     containerClass — classe del contenidor (default "pk-accordion")
     as           — element de cada ítem ('div' default, 'section' per files de pàgina)
     renderHead   — opcional (item, isOpen) => JSX del capçal (sense <button>)
     renderBody   — opcional (item, isOpen) => JSX del cos (default: item.content)
     hashOpen     — si true (default), obre l'ítem si location.hash hi coincideix
     scrollOnOpen — si true, scroll suau al capçal en obrir (default false)
     scrollOffset — px d'offset per a l'scroll (default 110)
     idPrefix     — prefix d'ids ARIA (default 'eacc')

   ARIA: botó amb aria-expanded + aria-controls; cos amb role="region" +
   aria-labelledby, i `inert` quan està tancat (no rep focus de teclat ni
   l'exposa als lectors de pantalla). Teclat: ↑/↓/Home/End entre capçals (patró APG).
   Animació: CSS (grid-template-rows 0fr→1fr) via la classe is-open.

   Exporta window.EsbartAccordion.
   ═══════════════════════════════════════════════════════════════════════════ */

function EsbartAccordion({
  items,
  defaultOpen = null,
  open: openProp,
  onChange,
  classes: classesProp,
  containerClass = "pk-accordion",
  as = "div",
  renderHead,
  renderBody,
  hashOpen = true,
  scrollOnOpen = false,
  scrollOffset = 110,
  idPrefix = "eacc",
}) {
  const cls = Object.assign(
    { root: "pk-acc", head: "pk-acc__head", body: "pk-acc__body", inner: "pk-acc__inner", open: "is-open" },
    classesProp || {}
  );
  const controlled = openProp !== undefined;
  const [openState, setOpenState] = React.useState(defaultOpen);
  const open = controlled ? openProp : openState;
  const rootRef = React.useRef(null);
  const firstRender = React.useRef(true);

  const setOpen = (id) => {
    if (!controlled) setOpenState(id);
    if (onChange) onChange(id);
  };
  const toggle = (id) => setOpen(open === id ? null : id);

  /* Expansió per àncora en arribar amb hash */
  React.useEffect(() => {
    if (!hashOpen) return;
    const apply = () => {
      const id = (location.hash || "").slice(1);
      if (!id || !items.some((it) => it.id === id)) return;
      setOpen(id);
      setTimeout(() => {
        const el = document.getElementById(id);
        if (el) {
          window.scrollTo({ top: el.getBoundingClientRect().top + window.scrollY - scrollOffset, behavior: "smooth" });
        }
      }, 350);
    };
    apply();
    window.addEventListener("hashchange", apply);
    return () => window.removeEventListener("hashchange", apply);
  }, []);

  /* Scroll suau al capçal en obrir (mai al primer render) */
  React.useEffect(() => {
    if (firstRender.current) { firstRender.current = false; return; }
    if (!scrollOnOpen || !open) return;
    const el = document.getElementById(open);
    if (el) {
      window.scrollTo({ top: el.getBoundingClientRect().top + window.scrollY - scrollOffset, behavior: "smooth" });
    }
  }, [open]);

  /* Teclat entre capçals (patró WAI-ARIA APG) */
  const onKeyDown = (e, idx) => {
    if (!rootRef.current) return;
    const heads = rootRef.current.querySelectorAll("button[data-acc-head]");
    let to = null;
    if (e.key === "ArrowDown") to = (idx + 1) % heads.length;
    else if (e.key === "ArrowUp") to = (idx - 1 + heads.length) % heads.length;
    else if (e.key === "Home") to = 0;
    else if (e.key === "End") to = heads.length - 1;
    if (to !== null) { e.preventDefault(); heads[to].focus(); }
  };

  if (!items || !items.length) return null;
  const ItemEl = as;

  return (
    <div className={containerClass} ref={rootRef}>
      {items.map((it, i) => {
        const isOpen = open === it.id;
        const hid = `${idPrefix}-h-${it.id}`;
        const bid = `${idPrefix}-b-${it.id}`;
        return (
          <ItemEl key={it.id} id={it.id} className={`${cls.root} ${isOpen ? cls.open : ""}`}>
            <button
              type="button"
              data-acc-head="true"
              id={hid}
              className={cls.head}
              aria-expanded={isOpen}
              aria-controls={bid}
              onClick={() => toggle(it.id)}
              onKeyDown={(e) => onKeyDown(e, i)}
            >
              {renderHead ? renderHead(it, isOpen) : (
                <>
                  <span className="pk-acc__num">{it.num != null ? it.num : String(i + 1).padStart(2, "0")}</span>
                  <span className="pk-acc__title" style={it.titleStyle}>{it.title}</span>
                  <span className="pk-acc__icon" aria-hidden="true"></span>
                </>
              )}
            </button>
            <div
              id={bid}
              role="region"
              aria-labelledby={hid}
              className={cls.body}
              inert={isOpen ? undefined : ""}
            >
              <div className={cls.inner}>
                {renderBody ? renderBody(it, isOpen) : <div className="pk-acc__content">{it.content}</div>}
              </div>
            </div>
          </ItemEl>
        );
      })}
    </div>
  );
}

window.EsbartAccordion = EsbartAccordion;
