/* ============================================================
   <Accordion /> — animated, single-or-multi open.
   Modeled after animate-ui's Radix accordion: spring-like height
   tween, chevron rotation, content slides in from top.

   Usage:
     <Accordion type="single" defaultValue="q1">
       <AccordionItem value="q1">
         <AccordionTrigger>Question</AccordionTrigger>
         <AccordionContent>Answer body…</AccordionContent>
       </AccordionItem>
     </Accordion>
   ============================================================ */

const AccordionCtx = React.createContext(null);
const AccordionItemCtx = React.createContext(null);

function Accordion({ children, type = "single", defaultValue = null, collapsible = true, className = "" }) {
  const initial = type === "single"
    ? defaultValue
    : (Array.isArray(defaultValue) ? defaultValue : (defaultValue ? [defaultValue] : []));
  const [openValue, setOpenValue] = React.useState(initial);

  const toggle = React.useCallback((value) => {
    if (type === "single") {
      setOpenValue((cur) => (cur === value ? (collapsible ? null : cur) : value));
    } else {
      setOpenValue((cur) => (cur.includes(value)
        ? cur.filter((v) => v !== value)
        : [...cur, value]));
    }
  }, [type, collapsible]);

  const isOpen = React.useCallback((value) => (
    type === "single" ? openValue === value : openValue.includes(value)
  ), [type, openValue]);

  return (
    <AccordionCtx.Provider value={{ isOpen, toggle }}>
      <div className={`accordion ${className}`} data-type={type}>
        {children}
      </div>
    </AccordionCtx.Provider>
  );
}

function AccordionItem({ value, children, className = "" }) {
  const acc = React.useContext(AccordionCtx);
  const open = acc?.isOpen(value) ?? false;
  const ctx = React.useMemo(() => ({
    value,
    open,
    toggle: () => acc?.toggle(value),
  }), [value, open, acc]);

  return (
    <AccordionItemCtx.Provider value={ctx}>
      <div className={`accordion__item ${open ? "is-open" : ""} ${className}`} data-state={open ? "open" : "closed"}>
        {children}
      </div>
    </AccordionItemCtx.Provider>
  );
}

function AccordionTrigger({ children, showArrow = true, meta = null }) {
  const item = React.useContext(AccordionItemCtx);
  const open = item?.open ?? false;
  return (
    <button
      type="button"
      className="accordion__trigger"
      aria-expanded={open}
      onClick={() => item?.toggle()}
      data-cursor={open ? "Collapse" : "Expand"}
    >
      <span className="accordion__trigger-text">{children}</span>
      {meta ? <span className="accordion__trigger-meta mono-meta">{meta}</span> : null}
      {showArrow ? (
        <span className={`accordion__chev ${open ? "is-open" : ""}`} aria-hidden="true">
          <svg width="14" height="14" viewBox="0 0 14 14" fill="none">
            <path d="M3 5.5 L7 9.5 L11 5.5" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round" strokeLinejoin="round"/>
          </svg>
        </span>
      ) : null}
    </button>
  );
}

function AccordionContent({ children, keepRendered = false }) {
  const item = React.useContext(AccordionItemCtx);
  const open = item?.open ?? false;
  const innerRef = React.useRef(null);
  const [height, setHeight] = React.useState(0);

  // Re-measure inner content height whenever it changes or the item opens.
  React.useLayoutEffect(() => {
    if (!innerRef.current) return;
    const measure = () => setHeight(innerRef.current.scrollHeight);
    measure();
    const ro = new ResizeObserver(measure);
    ro.observe(innerRef.current);
    return () => ro.disconnect();
  }, [children]);

  // For SEO, the content can remain rendered even when collapsed (just visually hidden).
  const shouldRender = open || keepRendered;

  return (
    <div
      className="accordion__content"
      style={{ height: open ? `${height}px` : "0px" }}
      aria-hidden={!open}
    >
      <div ref={innerRef} className="accordion__content-inner">
        {shouldRender ? children : null}
      </div>
    </div>
  );
}

Object.assign(window, { Accordion, AccordionItem, AccordionTrigger, AccordionContent });
