// extras2.jsx — batch 2: NavigationMenu, Menubar, Carousel, Resizable, ScrollArea,
// Collapsible, RadioCards, NumberInput, TagsInput, Rating, Timeline, Banner,
// AspectRatio, Kbd, CodeBlock, RangeCalendar, BarChart, Donut
const { useState: useStateY, useRef: useRefY, useEffect: useEffectY } = React;
const MONTHS_PT = ["Janeiro","Fevereiro","Março","Abril","Maio","Junho","Julho","Agosto","Setembro","Outubro","Novembro","Dezembro"];
const DOW_PT = ["D","S","T","Q","Q","S","S"];

/* ---------- Navigation Menu ---------- */
function NavigationMenu({ menus }) {
  const [open, setOpen] = useStateY(null);
  const ref = useRefY(null);
  useOutside(ref, () => setOpen(null));
  return (
    <div className="navmenu" ref={ref}>
      {menus.map((m, i) => (
        <div key={m.label} style={{ position: "static" }}>
          <button className="navmenu-item" data-open={open === i} onClick={() => setOpen(open === i ? null : i)} onMouseEnter={() => open !== null && setOpen(i)}>
            {m.label}{m.links && <Icon name="chevron-down" className="caret" />}
          </button>
        </div>
      ))}
      {open !== null && menus[open].links && (
        <div className="navmenu-panel" onMouseLeave={() => setOpen(null)}>
          {menus[open].links.map((l) => (
            <div key={l.title} className="navmenu-link" onClick={() => setOpen(null)}>
              <div className="nl-ic"><Icon name={l.icon || "layers"} /></div>
              <div><div className="t">{l.title}</div><div className="d">{l.desc}</div></div>
            </div>
          ))}
        </div>
      )}
    </div>
  );
}

/* ---------- Menubar ---------- */
function Menubar({ menus }) {
  const [open, setOpen] = useStateY(null);
  const ref = useRefY(null);
  useOutside(ref, () => setOpen(null));
  return (
    <div className="menubar" ref={ref}>
      {menus.map((m, i) => (
        <div key={m.label} style={{ position: "relative" }}>
          <button className="menubar-trigger" data-open={open === i} onClick={() => setOpen(open === i ? null : i)} onMouseEnter={() => open !== null && setOpen(i)}>{m.label}</button>
          {open === i && (
            <div className="menu" style={{ top: "calc(100% + 6px)", left: 0, minWidth: 190 }} onClick={() => setOpen(null)}>
              {m.items.map((it, j) => it.sep ? <div key={j} className="menu-sep" /> : (
                <div key={j} className="menu-item">{it.icon && <Icon name={it.icon} />}<span>{it.label}</span>{it.shortcut && <span className="shortcut">{it.shortcut}</span>}</div>
              ))}
            </div>
          )}
        </div>
      ))}
    </div>
  );
}

/* ---------- Carousel ---------- */
function Carousel({ slides }) {
  const [i, setI] = useStateY(0);
  const n = slides.length;
  return (
    <div className="carousel">
      <div className="carousel-viewport">
        <div className="carousel-track" style={{ transform: `translateX(-${i * 100}%)` }}>
          {slides.map((s, k) => <div className="carousel-slide" key={k}>{s}</div>)}
        </div>
      </div>
      <button className="carousel-btn prev" onClick={() => setI((v) => Math.max(0, v - 1))} disabled={i === 0}><Icon name="chevron-left" /></button>
      <button className="carousel-btn next" onClick={() => setI((v) => Math.min(n - 1, v + 1))} disabled={i === n - 1}><Icon name="chevron-right" /></button>
      <div className="carousel-dots">{slides.map((_, k) => <button key={k} className="carousel-dot" data-active={k === i} onClick={() => setI(k)} />)}</div>
    </div>
  );
}

/* ---------- Resizable ---------- */
function Resizable({ left, right, initial = 50 }) {
  const [pct, setPct] = useStateY(initial);
  const ref = useRefY(null);
  const [drag, setDrag] = useStateY(false);
  const down = () => {
    setDrag(true);
    const move = (e) => {
      const r = ref.current.getBoundingClientRect();
      let p = ((e.clientX - r.left) / r.width) * 100;
      setPct(Math.max(15, Math.min(85, p)));
    };
    const up = () => { setDrag(false); window.removeEventListener("pointermove", move); window.removeEventListener("pointerup", up); };
    window.addEventListener("pointermove", move); window.addEventListener("pointerup", up);
  };
  return (
    <div className="resizable" ref={ref}>
      <div className="resizable-pane" style={{ flexBasis: pct + "%" }}>{left}</div>
      <div className={"resizable-handle" + (drag ? " dragging" : "")} onPointerDown={down} />
      <div className="resizable-pane" style={{ flex: 1 }}>{right}</div>
    </div>
  );
}

/* ---------- Scroll Area ---------- */
function ScrollArea({ children, style }) { return <div className="scrollarea" style={style}>{children}</div>; }

/* ---------- Collapsible ---------- */
function Collapsible({ label, children, defaultOpen }) {
  const [open, setOpen] = useStateY(!!defaultOpen);
  const ref = useRefY(null);
  const [h, setH] = useStateY(0);
  useEffectY(() => { setH(open && ref.current ? ref.current.scrollHeight : 0); }, [open, children]);
  return (
    <div className="collapsible" data-open={open}>
      <button className="collapsible-trigger" onClick={() => setOpen((o) => !o)}><Icon name="chevron-down" />{label}</button>
      <div className="collapsible-content" style={{ height: h }}><div ref={ref}>{children}</div></div>
    </div>
  );
}

/* ---------- Radio Cards ---------- */
function RadioCards({ options, value, onChange }) {
  return (
    <div className="radio-cards">
      {options.map((o) => (
        <label key={o.value} className="radio-card" data-selected={value === o.value} onClick={() => onChange(o.value)}>
          <span className="checkbox radio" data-checked={value === o.value} style={{ marginTop: 2 }}><span className="radio-dot" /></span>
          <div className="rc-body">
            <div className="rc-title">{o.title}{o.badge && <Badge variant="soft">{o.badge}</Badge>}</div>
            {o.desc && <div className="rc-desc">{o.desc}</div>}
          </div>
          {o.price && <span className="rc-price">{o.price}</span>}
        </label>
      ))}
    </div>
  );
}

/* ---------- Number Input ---------- */
function NumberInput({ value, onChange, min = 0, max = 9999, step = 1 }) {
  const set = (v) => onChange(Math.max(min, Math.min(max, v)));
  return (
    <div className="number-input">
      <button onClick={() => set(value - step)} disabled={value <= min}><Icon name="chevron-down" /></button>
      <input type="number" value={value} onChange={(e) => set(Number(e.target.value) || 0)} />
      <button onClick={() => set(value + step)} disabled={value >= max}><Icon name="chevron-up" /></button>
    </div>
  );
}

/* ---------- Tags Input ---------- */
function TagsInput({ tags, onChange, placeholder = "Adicionar tag..." }) {
  const [v, setV] = useStateY("");
  const add = () => { const t = v.trim(); if (t && !tags.includes(t)) onChange([...tags, t]); setV(""); };
  const key = (e) => {
    if (e.key === "Enter") { e.preventDefault(); add(); }
    else if (e.key === "Backspace" && !v && tags.length) onChange(tags.slice(0, -1));
  };
  return (
    <div className="tags-input">
      {tags.map((t) => <span key={t} className="tag-chip">{t}<span className="x" onClick={() => onChange(tags.filter((x) => x !== t))}><Icon name="x" /></span></span>)}
      <input value={v} onChange={(e) => setV(e.target.value)} onKeyDown={key} onBlur={add} placeholder={tags.length ? "" : placeholder} />
    </div>
  );
}

/* ---------- Rating ---------- */
function Rating({ value, onChange, max = 5 }) {
  const [hover, setHover] = useStateY(0);
  return (
    <div className="rating" onMouseLeave={() => setHover(0)}>
      {Array.from({ length: max }).map((_, i) => {
        const on = (hover || value) > i;
        return <button key={i} onMouseEnter={() => setHover(i + 1)} onClick={() => onChange(i + 1)}><Icon name={on ? "star-fill" : "star"} className={on ? "on" : ""} /></button>;
      })}
    </div>
  );
}

/* ---------- Timeline ---------- */
function Timeline({ items }) {
  return (
    <div className="timeline">
      {items.map((it, i) => (
        <div className="timeline-item" key={i}>
          <div className="timeline-time">{it.time}</div>
          <div className="timeline-title">{it.title}</div>
          {it.desc && <div className="timeline-desc">{it.desc}</div>}
        </div>
      ))}
    </div>
  );
}

/* ---------- Banner ---------- */
function Banner({ variant = "brand", icon = "rocket", children, action }) {
  return (
    <div className={"banner banner-" + variant}>
      <Icon name={icon} className="b-ic" />
      <div className="b-text">{children}</div>
      {action}
    </div>
  );
}

/* ---------- Aspect Ratio ---------- */
function AspectRatio({ ratio = 16 / 9, children, label }) {
  return (
    <div className="aspect" style={{ paddingTop: 100 / ratio + "%" }}>
      <div className="aspect-inner">{children || <><Icon name="image" /></>}{label && <span style={{ marginLeft: 8 }}>{label}</span>}</div>
    </div>
  );
}

/* ---------- Kbd & CodeBlock ---------- */
function Kbd({ children }) { return <kbd className="kbd">{children}</kbd>; }
function CodeBlock({ children }) { return <pre className="codeblock"><code>{children}</code></pre>; }

/* ---------- Range Calendar / Date Range Picker ---------- */
function RangeCalendar({ range, onChange }) {
  const today = new Date();
  const [view, setView] = useStateY(() => new Date((range && range.start ? range.start : today).getFullYear(), (range && range.start ? range.start : today).getMonth(), 1));
  const year = view.getFullYear(), month = view.getMonth();
  const firstDow = new Date(year, month, 1).getDay();
  const daysInMonth = new Date(year, month + 1, 0).getDate();
  const prevDays = new Date(year, month, 0).getDate();
  const cells = [];
  for (let i = 0; i < firstDow; i++) cells.push({ day: prevDays - firstDow + 1 + i, outside: true, date: new Date(year, month - 1, prevDays - firstDow + 1 + i) });
  for (let d = 1; d <= daysInMonth; d++) cells.push({ day: d, date: new Date(year, month, d) });
  while (cells.length % 7 !== 0) { const d = cells.length - (firstDow + daysInMonth) + 1; cells.push({ day: d, outside: true, date: new Date(year, month + 1, d) }); }
  const same = (a, b) => a && b && a.toDateString() === b.toDateString();
  const pick = (date) => {
    if (!range || !range.start || (range.start && range.end)) onChange({ start: date, end: null });
    else { if (date < range.start) onChange({ start: date, end: range.start }); else onChange({ start: range.start, end: date }); }
  };
  const cls = (date) => {
    if (!range) return "";
    if (same(date, range.start)) return "range-start";
    if (same(date, range.end)) return "range-end";
    if (range.start && range.end && date > range.start && date < range.end) return "range-mid";
    return "";
  };
  return (
    <div className="calendar" style={{ width: 300 }}>
      <div className="cal-head">
        <div className="cal-title">{MONTHS_PT[month]} {year}</div>
        <div className="cal-nav"><Button variant="ghost" size="sm" icon="chevron-left" onClick={() => setView(new Date(year, month - 1, 1))} /><Button variant="ghost" size="sm" icon="chevron-right" onClick={() => setView(new Date(year, month + 1, 1))} /></div>
      </div>
      <div className="cal-grid">
        {DOW_PT.map((d, i) => <div key={i} className="cal-dow">{d}</div>)}
        {cells.map((c, i) => <button key={i} className={["cal-day", c.outside ? "outside" : "", same(c.date, today) ? "today" : "", cls(c.date)].filter(Boolean).join(" ")} onClick={() => pick(c.date)}>{c.day}</button>)}
      </div>
    </div>
  );
}
function DateRangePicker({ range, onChange }) {
  const fmt = (d) => d ? `${String(d.getDate()).padStart(2, "0")}/${String(d.getMonth() + 1).padStart(2, "0")}` : "";
  const label = range && range.start ? (range.end ? `${fmt(range.start)} – ${fmt(range.end)}` : `${fmt(range.start)} – ...`) : "Selecione o período";
  return (
    <Popover width={320} trigger={
      <button type="button" className="select-trigger" style={{ width: 260 }}>
        <span className={range && range.start ? "" : "placeholder"} style={{ display: "inline-flex", alignItems: "center", gap: 8 }}><Icon name="calendar" style={{ width: 16 }} />{label}</span>
      </button>
    }>
      <RangeCalendar range={range} onChange={onChange} />
    </Popover>
  );
}

/* ---------- Bar Chart ---------- */
function BarChart({ data, highlight }) {
  const max = Math.max(...data.map((d) => d.value));
  return (
    <div className="bars">
      {data.map((d, i) => (
        <div className="bar-col" key={d.label}>
          <div className={"bar" + (highlight != null && i !== highlight ? " muted" : "")} style={{ height: (d.value / max) * 100 + "%" }} title={d.value} />
          <div className="bar-label">{d.label}</div>
        </div>
      ))}
    </div>
  );
}

/* ---------- Donut ---------- */
function Donut({ segments, size = 150 }) {
  const total = segments.reduce((a, s) => a + s.value, 0);
  const r = size / 2 - 14, c = 2 * Math.PI * r, cx = size / 2;
  let offset = 0;
  return (
    <div className="donut-wrap">
      <svg width={size} height={size} viewBox={`0 0 ${size} ${size}`}>
        <circle cx={cx} cy={cx} r={r} fill="none" stroke="var(--secondary)" strokeWidth="14" />
        {segments.map((s, i) => {
          const len = (s.value / total) * c;
          const el = <circle key={i} cx={cx} cy={cx} r={r} fill="none" stroke={s.color} strokeWidth="14" strokeDasharray={`${len} ${c - len}`} strokeDashoffset={-offset} transform={`rotate(-90 ${cx} ${cx})`} strokeLinecap="butt" />;
          offset += len; return el;
        })}
        <text x={cx} y={cx - 4} textAnchor="middle" style={{ fontSize: 22, fontWeight: 700, fill: "var(--foreground)", fontFamily: "var(--ui-font)" }}>{total}</text>
        <text x={cx} y={cx + 14} textAnchor="middle" style={{ fontSize: 11, fill: "var(--muted-foreground)", fontFamily: "var(--ui-font)" }}>total</text>
      </svg>
      <div className="donut-legend">
        {segments.map((s) => <div className="lg" key={s.label}><span className="dot" style={{ background: s.color }} /><span>{s.label}</span><span className="val">{s.value}</span></div>)}
      </div>
    </div>
  );
}

Object.assign(window, { NavigationMenu, Menubar, Carousel, Resizable, ScrollArea, Collapsible, RadioCards, NumberInput, TagsInput, Rating, Timeline, Banner, AspectRatio, Kbd, CodeBlock, RangeCalendar, DateRangePicker, BarChart, Donut });
