// ui-kit.jsx — sbor/ka canonical React component library (window.UI.*)
// ------------------------------------------------------------------
// One source of truth. The website pages AND the /ui-kit gallery both
// consume these components. Styles live in css/ui-kit.css; markup here.
// Tile primitives are reused from src/tiles.jsx (loaded just before).

const cx = (...a) => a.filter(Boolean).join(" ");

/* ---------- brand ---------- */
const LOGO_SRC = {
  latin: "assets/icons/logo-sborka-word-latin.svg",
  cyrillic: "assets/icons/logo-sborka-word-cyrillic.svg",
  mark: "assets/icons/logo-sborka-mark.svg",
};
const Logo = ({ variant = "latin", height = 32, invert = false, alt = "sbor/ka", style, ...rest }) => (
  <img src={LOGO_SRC[variant] || LOGO_SRC.latin} alt={alt}
    style={{ height, width: "auto", display: "block", filter: invert ? "invert(1)" : undefined, ...style }} {...rest} />
);

/* ---------- actions ---------- */
const Button = ({ variant, size, arrow, children, href, className, ...rest }) => {
  const cls = cx("btn", variant, size, className);
  const inner = <>{children}{arrow && <span className="arr">{arrow === true ? "→" : arrow}</span>}</>;
  return href
    ? <a className={cls} href={href} {...rest}>{inner}</a>
    : <button className={cls} {...rest}>{inner}</button>;
};
const IconButton = ({ surface, size, children, className, ...rest }) => (
  <button className={cx("icon-btn", surface, size, className)} {...rest}>{children}</button>
);

/* ---------- badges ---------- */
const Tag = ({ color, children, className, ...rest }) => (
  <span className={cx("tag", color, className)} {...rest}>{children}</span>
);
const BracketBadge = ({ color, children, className, ...rest }) => (
  <span className={cx("tag-lg bracket", color, className)} {...rest}>{children}</span>
);
const Chip = ({ on, removable, children, className, ...rest }) => (
  <span className={cx("chip", on && "on", className)} {...rest}>{children}{(on || removable) && <span className="x">×</span>}</span>
);
const PillNum = ({ children, ink, className, ...rest }) => (
  <span className={cx("pill-num", className)} style={ink ? { background: "var(--sb-ink)" } : undefined} {...rest}>{children}</span>
);

/* ---------- forms ---------- */
const Field = ({ label, state, wide, multiline, options, className, ...rest }) => (
  <div className={cx("f-field", state, wide && "wide", className)}>
    {label && <div className="f-label">{label}</div>}
    {options ? <select className="f-sel" {...rest}>{options.map((o, i) => <option key={i}>{o}</option>)}</select>
      : multiline ? <textarea className="f-tex" {...rest} />
      : <input className="f-in" {...rest} />}
  </div>
);
const FieldGrid = ({ children, className, ...rest }) => <div className={cx("f-grid", className)} {...rest}>{children}</div>;
const HairInput = ({ label, className, ...rest }) => (
  <div>
    {label && <div style={{ fontFamily: "var(--sb-font-ui)", fontSize: 13, color: "var(--sb-ink)", opacity: 0.6, marginBottom: 6 }}>{label}</div>}
    <input className={cx("f-hair", className)} {...rest} />
  </div>
);
const Check = ({ on, label, ...rest }) => <label className="box-label" {...rest}><span className={cx("sb-check", on && "on")} />{label}</label>;
const Radio = ({ on, label, ...rest }) => <label className="box-label" {...rest}><span className={cx("sb-radio", on && "on")} />{label}</label>;
const Switch = ({ on, ...rest }) => <span className={cx("sb-switch", on && "on")} {...rest} />;
const Segmented = ({ options = [], value, onChange }) => (
  <div className="segmented">{options.map((o) => <div key={o} className={value === o ? "on" : ""} onClick={() => onChange && onChange(o)}>{o}</div>)}</div>
);
const Search = ({ placeholder = "найти", button = "найти", ...rest }) => (
  <div className="search"><span className="ic">⌕</span><input placeholder={placeholder} {...rest} /><button>{button}</button></div>
);
const Slider = ({ value = 42, ticks = [] }) => (
  <div className="sb-slider">
    <div className="track"><div className="fill" style={{ width: value + "%" }} /></div>
    <div className="thumb" style={{ left: `calc(${value}% - 9px)` }} />
    {ticks.length > 0 && <div className="ticks">{ticks.map((t) => <span key={t}>{t}</span>)}</div>}
  </div>
);

/* ---------- navigation ---------- */
const LangSwitch = ({ langs = ["ru", "en", "ca", "es"], value, onChange }) => (
  <div className="lang-2x2">{langs.map((c) => <button key={c} className={value === c ? "on" : ""} onClick={() => onChange && onChange(c)}>{c}</button>)}</div>
);
const NavBar = ({ logoVariant = "cyrillic", links = [], lang, langs, onLang }) => (
  <div className="nav-bar">
    <div className="wm"><Logo variant={logoVariant} height={28} /></div>
    <div className="links">{links.map((l, i) => <a key={i} className={l.active ? "active" : ""} href={l.href || "#"}>{l.label}</a>)}</div>
    <div className="end"><LangSwitch langs={langs} value={lang} onChange={onLang} /></div>
  </div>
);
const Tabs = ({ tabs = [], value, onChange }) => (
  <div className="tabs">
    {tabs.map((t) => {
      const item = typeof t === "string" ? { id: t, label: t } : t;
      return (
        <div key={item.id} className={value === item.id ? "on" : ""} onClick={() => onChange && onChange(item.id)}>
          <span className="n">{item.label}</span>
          {item.count != null && <span className="c">{item.count}</span>}
        </div>
      );
    })}
  </div>
);
const Breadcrumb = ({ items = [] }) => (
  <div className="breadcrumb">{items.map((it, i) => (
    <React.Fragment key={i}>
      {i > 0 && <span className="s">/</span>}
      {i === items.length - 1 ? <span className="cur">{it}</span> : <a>{it}</a>}
    </React.Fragment>
  ))}</div>
);
const Paginator = ({ pages = [], current }) => (
  <div className="paginator">{pages.map((p, i) => <div key={i} className={p === current ? "on" : ""}>{p}</div>)}</div>
);

/* ---------- cards ---------- */
const ArtCard = ({ fmt, title, author, meta, color = "bone", onClick }) => (
  <div className={cx("art-card", color)} onClick={onClick}>
    <div className="fmt">[{fmt}]</div>
    <h3>{title}</h3>
    <div className="foot"><span>{author}</span><span>{meta}</span></div>
  </div>
);
const EventCard = ({ tag, time, title, place, date, color = "peri" }) => (
  <div className={cx("event-card", color)}>
    <div className="top"><span>{tag}</span><span>{time}</span></div>
    <div className="ttl">{title}</div>
    <div className="foot"><span>{place}</span><span>{date}</span></div>
  </div>
);
const EventTile = ({ fmt, day, time, color = "teal" }) => (
  <div className={cx("event-tile", color)}>
    <div className="fmt">[{fmt}]</div>
    <div className="dt">{day}<br />{time}</div>
  </div>
);
const StatCard = ({ lab, idx, num, desc, color = "bone" }) => (
  <div className={cx("stat-card", color)}>
    <div className="lab"><span>{lab}</span>{idx && <span className="idx">{idx}</span>}</div>
    <div className="num">{num}</div>
    <div className="desc">{desc}</div>
  </div>
);
const CourseCard = ({ code, title, lang, weeks, color = "coral", motif }) => (
  <div className={cx("course-card", color)}>
    <div className="code">{code}</div>
    <div className="ttl">{title}</div>
    <div className="meta"><span>{lang}</span><span>{weeks}</span></div>
    {typeof motif === "number" && window.LevelMotif ? <window.LevelMotif kind={motif} />
      : motif ? <div className="motif">{motif}</div> : null}
  </div>
);

/* ---------- data / identity ---------- */
const Avatar = ({ children, color, lg, style }) => <div className={cx("av", color, lg && "lg")} style={style}>{children}</div>;
const AvatarStack = ({ children }) => <div className="av-stack">{children}</div>;
const List = ({ head = [], rows = [] }) => (
  <div className="sb-list">
    <div className="row head">{head.map((h, i) => <div key={i}>{h}</div>)}</div>
    {rows.map((r, i) => <div className="row body" key={i}>{r.map((c, j) => <div key={j}>{c}</div>)}</div>)}
  </div>
);
const Progress = ({ value = 60, stripes, caption }) => (
  <div>
    <div className={cx("progress", stripes && "stripes")}><div className="bar" style={{ width: value + "%" }} /></div>
    {caption && <div className="sb-caption" style={{ marginTop: 8, opacity: 0.6 }}>{caption}</div>}
  </div>
);
const Loader = () => <div className="loader"><div /><div /><div /><div /></div>;

/* ---------- feedback ---------- */
const Toast = ({ color, children }) => <div className={cx("toast", color)}><span className="ic" />{children}</div>;
const Alert = ({ kind = "info", icon, title, children, dismiss = "закрыть" }) => (
  <div className={cx("alert", kind)}>
    <span className="ic">{icon}</span>
    <span className="msg">{title && <b>{title} </b>}{children}</span>
    <span className="x">{dismiss}</span>
  </div>
);

/* ---------- iconography — 16 house icons, 1.5px stroke on 24-grid ---------- */
const ICON_PATHS = {
  "arrow-r": "M4 12h16M14 6l6 6-6 6",
  "arrow-l": "M20 12H4M10 6l-6 6 6 6",
  "arrow-up-r": "M6 18L18 6M9 6h9v9",
  "arrow-d": "M12 4v16M6 14l6 6 6-6",
  close: "M6 6l12 12M18 6L6 18",
  plus: "M12 4v16M4 12h16",
  minus: "M4 12h16",
  "chevron-d": "M5 7l7 7 7-7",
  mail: "M4 6l8 7 8-7M4 6h16v12H4z",
  doc: "M6 4h9l5 5v11H6z M15 4v5h5",
  clock: "M12 8v5l3 2",
  user: "M18 20c0-3.5-2.7-6-6-6s-6 2.5-6 6",
  heart: "M12 21C8 17 4 13.5 4 9.5 4 6.5 6.5 4 9.5 4c1.5 0 3 .8 2.5 2.5C12.5 4.8 14 4 15.5 4 18.5 4 21 6.5 21 9.5c0 4-4 7.5-8 11.5",
  star: "M12 2l3 6.5 7 1-5 5 1.5 7L12 18l-6.5 3.5L7 14.5 2 9.5l7-1z",
};
const ICON_EXTRA = {
  search: <><circle cx="11" cy="11" r="6" /><path d="M16 16l4 4" /></>,
  calendar: <><rect x="4" y="5" width="16" height="16" /><path d="M4 9h16M9 3v4M15 3v4" /></>,
  user: <><circle cx="12" cy="9" r="3.5" /><path d="M18 20c0-3.5-2.7-6-6-6s-6 2.5-6 6" /></>,
  clock: <><circle cx="12" cy="12" r="8" /><path d="M12 8v5l3 2" /></>,
};
const ICON_NAMES = ["arrow-r", "arrow-l", "arrow-up-r", "arrow-d", "close", "plus", "minus", "chevron-d", "search", "mail", "calendar", "doc", "clock", "user", "heart", "star"];
const ICON_LABELS = {
  "arrow-r": "стрелка вправо",
  "arrow-l": "стрелка влево",
  "arrow-up-r": "стрелка вверх",
  "arrow-d": "стрелка вниз",
  close: "закрыть",
  plus: "плюс",
  minus: "минус",
  "chevron-d": "шеврон вниз",
  search: "поиск",
  mail: "почта",
  calendar: "календарь",
  doc: "документ",
  clock: "время",
  user: "пользователь",
  heart: "сердце",
  star: "звезда",
};
const Icon = ({ name, size = 24, style }) => (
  <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.5" strokeLinecap="square" strokeLinejoin="miter"
    style={{ width: size, height: size, display: "block", ...style }}>
    {ICON_EXTRA[name] || <path d={ICON_PATHS[name]} />}
  </svg>
);

/* ---------- section head (site composition, promoted into the kit) ---------- */
const SectionHead = ({ num, lab, meta }) => (
  <div className="section-head">
    <div className="num">{num}</div>
    <div className="lab">{lab}</div>
    <div className="meta">{meta}</div>
  </div>
);

/* ---------- gallery reference data ---------- */
const PALETTE = {
  primary: [
    { name: "молочный", hex: "#F8F6F1", fg: "var(--sb-ink)" },
    { name: "жёлтый", hex: "#FFCC4D", fg: "var(--sb-ink)" },
    { name: "красный", hex: "#E85E30", fg: "var(--sb-bone)" },
    { name: "синий", hex: "#7D8FF4", fg: "var(--sb-ink)" },
    { name: "хвойный", hex: "#25A78F", fg: "var(--sb-bone)" },
    { name: "черный", hex: "#000000", fg: "var(--sb-bone)" },
  ],
  secondary: [
    { name: "персиковый", hex: "#FDA492", fg: "var(--sb-ink)" },
    { name: "голубой", hex: "#B7D7F8", fg: "var(--sb-ink)" },
    { name: "оливковый", hex: "#AAE9AB", fg: "var(--sb-ink)" },
    { name: "каменный", hex: "#AD8B48", fg: "var(--sb-bone)" },
  ],
};
const TYPE_SCALE = [
  { sz: "герой · 94", style: { fontSize: 72, lineHeight: 0.82, letterSpacing: "-0.045em" }, sample: "собираем жизнь в новом городе", desc: "герой" },
  { sz: "дисплей · 87", style: { fontSize: 56, lineHeight: 0.82, letterSpacing: "-0.04em" }, sample: "нам важно каждое имя", desc: "заголовок первого уровня" },
  { sz: "постер · 47", style: { fontSize: 40, letterSpacing: "-0.035em" }, sample: "курсы · помощь · события", desc: "крупный раздел" },
  { sz: "заголовок · 43.5", style: { fontSize: 30, letterSpacing: "-0.03em" }, sample: "как проходит первая встреча", desc: "подзаголовок" },
  { sz: "текст · 22", style: { fontSize: 20, letterSpacing: "-0.02em", lineHeight: 1.2 }, sample: "независимое сообщество и медиа для русскоязычных в барселоне.", desc: "основной текст" },
  { sz: "интерфейс · 17", style: { fontSize: 15, fontFamily: "var(--sb-font-ui)", letterSpacing: 0 }, sample: "навигация · статусы · подписи", desc: "интерфейсный текст" },
  { sz: "подпись · 12", style: { fontSize: 12, fontFamily: "var(--sb-font-ui)", letterSpacing: "0.02em" }, sample: "дата · время · служебные пометки", desc: "мелкая подпись" },
];

const UI = {
  cx, Logo,
  Button, IconButton,
  Tag, BracketBadge, Chip, PillNum,
  Field, FieldGrid, HairInput, Check, Radio, Switch, Segmented, Search, Slider,
  NavBar, LangSwitch, Tabs, Breadcrumb, Paginator,
  ArtCard, EventCard, EventTile, StatCard, CourseCard,
  Avatar, AvatarStack, List, Progress, Loader,
  Toast, Alert,
  Icon, ICON_NAMES, ICON_LABELS,
  SectionHead,
  PALETTE, TYPE_SCALE,
  // tile primitives re-exported from tiles.jsx
  get Stripes() { return window.Stripes; },
  get FlowerTile() { return window.FlowerTile; },
  get DotGrid() { return window.DotGrid; },
  get Checker() { return window.Checker; },
  get TilePanel() { return window.TilePanel; },
};
window.UI = UI;

// Keep SectionHead available as a bare global too (sections.jsx references it).
window.SectionHead = SectionHead;
