/* Adeyy app — shared components. Loaded before views. */

const AdeyyIcons = {
  link: <path d="M10 14a4 4 0 0 0 6 0l3-3a4 4 0 1 0-6-6l-1 1M14 10a4 4 0 0 0-6 0l-3 3a4 4 0 1 0 6 6l1-1" />,
  qr: <g><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" /><path d="M14 14h3v3M21 14v7h-7M17 21h.01M21 17h.01" /></g>,
  folder: <path d="M3 7a1 1 0 0 1 1-1h5l2 2.5h8a1 1 0 0 1 1 1V18a1 1 0 0 1-1 1H4a1 1 0 0 1-1-1z" />,
  chart: <path d="M4 19V11M10 19V5M16 19v-6M21 19H3" />,
  card: <g><rect x="3" y="5" width="18" height="14" rx="2" /><path d="M3 10h18" /></g>,
  settings: <g><circle cx="12" cy="12" r="3" /><path d="M12 2v3M12 19v3M2 12h3M19 12h3M4.9 4.9l2.1 2.1M17 17l2.1 2.1M19.1 4.9L17 7M7 17l-2.1 2.1" /></g>,
  plus: <path d="M12 5v14M5 12h14" />,
  search: <g><circle cx="11" cy="11" r="6.5" /><path d="M20 20l-4-4" /></g>,
  copy: <g><rect x="9" y="9" width="11" height="11" rx="1.5" /><path d="M5 15H4a1 1 0 0 1-1-1V4a1 1 0 0 1 1-1h10a1 1 0 0 1 1 1v1" /></g>,
  check: <path d="M5 12.5l4.5 4.5L19 7" />,
  close: <path d="M6 6l12 12M18 6L6 18" />,
  back: <path d="M19 12H5M11 6l-6 6 6 6" />,
  download: <path d="M12 3v12M7 10l5 5 5-5M4 21h16" />,
  edit: <path d="M4 20l4-1L20 7a2 2 0 0 0-3-3L5 16l-1 4zM14 6l3 3" />,
  trash: <path d="M4 7h16M9 7V4h6v3M6 7l1 13h10l1-13M10 11v6M14 11v6" />,
  upload: <path d="M12 15V3M7 8l5-5 5 5M4 21h16" />,
  users: <g><circle cx="9" cy="9" r="3" /><path d="M3 19c1-3 3.5-4.5 6-4.5S14 16 15 19" /><path d="M16 6.2a3 3 0 0 1 0 5.6M18 14.5c1.8.5 3.2 1.8 3.8 4" /></g>,
  external: <path d="M7 17L17 7M9 7h8v8" />,
  clock: <g><circle cx="12" cy="12" r="9" /><path d="M12 7v5l3 2" /></g>,
  bolt: <path d="M13 2L5 13h6l-1 9 8-11h-6z" />,
  history: <path d="M3 12a9 9 0 1 0 3-6.7L3 8M3 3v5h5M12 7v5l3 2" />
};

function Icon({ name, size = 17 }) {
  return (
    <svg width={size} height={size} viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true">
      {AdeyyIcons[name] || null}
    </svg>
  );
}

function StatusPill({ on }) {
  return (
    <span className={'status ' + (on ? 'on' : 'off')}>
      <span className="sdot"></span>{on ? 'Active' : 'Inactive'}
    </span>
  );
}

function Toggle({ on, onChange, disabled }) {
  return (
    <button
      type="button"
      className={'atoggle' + (on ? ' on' : '')}
      disabled={disabled}
      aria-pressed={on}
      onClick={() => !disabled && onChange(!on)}
    ></button>
  );
}

function CopyBtn({ text, toast, label, onCopied }) {
  return (
    <button className="abtn abtn-ghost abtn-sm" onClick={() => {
      if (navigator.clipboard) navigator.clipboard.writeText(text);
      toast('Copied ' + (label || text));
      if (onCopied) onCopied();
    }}><Icon name="copy" size={14} />Copy</button>
  );
}

function Modal({ title, children, onClose, width }) {
  return (
    <div className="amodal-scrim" onClick={(e) => { if (e.target === e.currentTarget) onClose(); }}>
      <div className="amodal" style={width ? { maxWidth: width } : null}>
        <div className="row-between" style={{ marginBottom: 4 }}>
          <h3>{title}</h3>
          <button className="abtn abtn-quiet abtn-sm" onClick={onClose} aria-label="Close"><Icon name="close" size={15} /></button>
        </div>
        {children}
      </div>
    </div>
  );
}

function QrSvg({ slug, config, style }) {
  const html = React.useMemo(() => {
    return AdeyyQR.svgString('https://adeyy.com/' + slug + '?s=q', {
      fg: config.fg, bg: config.bg, modules: config.modules, eyes: config.eyes,
      logo: config.logo, quiet: 3
    });
  }, [slug, config.fg, config.bg, config.modules, config.eyes, config.logo]);
  return <div style={style} dangerouslySetInnerHTML={{ __html: html }} />;
}

function Seg({ value, options, onChange }) {
  return (
    <div className="seg">
      {options.map((o) => {
        const v = typeof o === 'string' ? o : o.value;
        const l = typeof o === 'string' ? o : o.label;
        return (
          <button key={v} type="button" className={value === v ? 'sel' : ''} onClick={() => onChange(v)}>{l}</button>
        );
      })}
    </div>
  );
}

function Swatches({ value, options, onChange }) {
  return (
    <div className="swatches">
      {options.map((o) => (
        <button key={o.hex} type="button" title={o.name}
          className={'swatch' + (value === o.hex ? ' sel' : '')}
          style={{ background: o.hex }}
          onClick={() => onChange(o.hex)}></button>
      ))}
    </div>
  );
}

/* Stacked time-series bars (scans ink, clicks teal). */
function SeriesChart({ data, height = 150 }) {
  const max = Math.max(...data.map((d) => d.scans + d.clicks), 1);
  return (
    <div style={{ display: 'flex', alignItems: 'flex-end', gap: 3, height }}>
      {data.map((d, i) => (
        <div key={i} style={{ flex: 1, display: 'flex', flexDirection: 'column', justifyContent: 'flex-end', gap: 1, height: '100%' }}>
          <div style={{ background: 'var(--adeyy)', borderRadius: '2px 2px 0 0', height: Math.max((d.clicks / max) * 100, 1.5) + '%' }}></div>
          <div style={{ background: 'var(--ink)', borderRadius: d.clicks > 0 ? 0 : '2px 2px 0 0', height: Math.max((d.scans / max) * 100, 2) + '%' }}></div>
        </div>
      ))}
    </div>
  );
}

function HBar({ label, value, max, alt, fmt }) {
  return (
    <div className={'hbar' + (alt ? ' alt' : '')}>
      <span className="hl" title={label}>{label}</span>
      <span className="ht"><i style={{ width: Math.round((value / Math.max(max, 1)) * 100) + '%' }}></i></span>
      <span className="hv">{fmt ? fmt(value) : value}</span>
    </div>
  );
}

function Kpi({ label, value, sub, unit, accent }) {
  return (
    <div className={'kpi' + (accent ? ' accent' : '')}>
      <div className="lbl">{label}</div>
      <div className="num">{value}{unit ? <span className="unit">{unit}</span> : null}</div>
      {sub ? <div className="sub">{sub}</div> : null}
    </div>
  );
}

function EmptyState({ title, body, cta, onCta }) {
  return (
    <div className="aempty">
      <div className="serif">{title}</div>
      <p>{body}</p>
      {cta ? <button className="abtn abtn-primary" onClick={onCta}><Icon name="plus" size={15} />{cta}</button> : null}
    </div>
  );
}

function SkeletonTable({ rows = 5 }) {
  return (
    <div style={{ display: 'flex', flexDirection: 'column', gap: 10, padding: '14px 0' }}>
      {Array.from({ length: rows }).map((_, i) => (
        <div key={i} style={{ display: 'flex', gap: 14 }}>
          <div className="skel" style={{ height: 16, width: 130 }}></div>
          <div className="skel" style={{ height: 16, flex: 2 }}></div>
          <div className="skel" style={{ height: 16, flex: 1 }}></div>
          <div className="skel" style={{ height: 16, width: 70 }}></div>
        </div>
      ))}
    </div>
  );
}

/* Toast holder — render once in App. */
function Toasts({ items }) {
  return (
    <div className="atoast-wrap">
      {items.map((t) => (
        <div className="atoast" key={t.id}><span className="tdot"></span>{t.msg}</div>
      ))}
    </div>
  );
}

Object.assign(window, {
  AdeyyIcons, Icon, StatusPill, Toggle, CopyBtn, Modal, QrSvg, Seg, Swatches,
  SeriesChart, HBar, Kpi, EmptyState, SkeletonTable, Toasts
});
