// ui.jsx — small, reusable primitives shared across the app.
// Style hooks live in index.html's <style> block (class names with `ai-` prefix).

const { useState, useEffect, useRef, useMemo, useCallback } = React;

// ─── Tooltip ──────────────────────────────────────────────────────────────
function Tooltip({ label, side = 'right', children }) {
  const [open, setOpen] = useState(false);
  const ref = useRef(null);
  return (
    <span
      ref={ref}
      className="ai-tt-host"
      onMouseEnter={() => setOpen(true)}
      onMouseLeave={() => setOpen(false)}
      onFocus={() => setOpen(true)}
      onBlur={() => setOpen(false)}
    >
      {children}
      {open && label && (
        <span className={`ai-tt ai-tt-${side}`} role="tooltip">{label}</span>
      )}
    </span>
  );
}

// ─── Buttons ──────────────────────────────────────────────────────────────
function Button({ variant = 'surface', size = 'md', icon, children, className = '', ...rest }) {
  const cls = `ai-btn ai-btn-${variant} ai-btn-${size} ${className}`;
  return (
    <button className={cls} {...rest}>
      {icon ? <span className="ai-btn-i">{icon}</span> : null}
      {children ? <span>{children}</span> : null}
    </button>
  );
}

function IconButton({ label, side = 'bottom', children, active, className = '', ...rest }) {
  return (
    <Tooltip label={label} side={side}>
      <button
        className={`ai-iconbtn ${active ? 'is-active' : ''} ${className}`}
        aria-label={label}
        {...rest}
      >
        {children}
      </button>
    </Tooltip>
  );
}

// ─── Slider ───────────────────────────────────────────────────────────────
function Slider({ value, min = 0, max = 100, step = 1, onChange, fmt }) {
  const pct = ((value - min) / (max - min)) * 100;
  return (
    <div className="ai-slider">
      <div className="ai-slider-track">
        <div className="ai-slider-fill" style={{ width: `${pct}%` }} />
      </div>
      <input
        type="range"
        min={min}
        max={max}
        step={step}
        value={value}
        onChange={(e) => onChange(Number(e.target.value))}
      />
      {fmt && <span className="ai-slider-val">{fmt(value)}</span>}
    </div>
  );
}

// ─── Segmented control ────────────────────────────────────────────────────
function Segmented({ value, options, onChange }) {
  // options: [{value, label, icon?}]
  return (
    <div className="ai-seg" role="tablist">
      {options.map((o) => (
        <button
          key={o.value}
          role="tab"
          aria-selected={value === o.value}
          className={`ai-seg-item ${value === o.value ? 'is-active' : ''}`}
          onClick={() => onChange(o.value)}
        >
          {o.icon ? <span className="ai-seg-i">{o.icon}</span> : null}
          {o.label}
        </button>
      ))}
    </div>
  );
}

// ─── Toggle / Switch ──────────────────────────────────────────────────────
function Switch({ value, onChange, label }) {
  return (
    <label className="ai-switch">
      <input type="checkbox" checked={value} onChange={(e) => onChange(e.target.checked)} />
      <span className="ai-switch-track"><span className="ai-switch-thumb" /></span>
      {label && <span className="ai-switch-lbl">{label}</span>}
    </label>
  );
}

// ─── Dropdown (model picker etc) ──────────────────────────────────────────
function Dropdown({ value, options, onChange, renderItem, renderValue, align = 'left' }) {
  const [open, setOpen] = useState(false);
  const ref = useRef(null);
  useEffect(() => {
    const close = (e) => {
      if (ref.current && !ref.current.contains(e.target)) setOpen(false);
    };
    document.addEventListener('mousedown', close);
    return () => document.removeEventListener('mousedown', close);
  }, []);
  const current = options.find((o) => o.value === value) || options[0];
  return (
    <div className="ai-dd" ref={ref}>
      <button className="ai-dd-trigger" onClick={() => setOpen((v) => !v)}>
        {renderValue ? renderValue(current) : current?.label}
        <IconChevron size={16} />
      </button>
      {open && (
        <div className={`ai-dd-menu ai-dd-menu-${align}`}>
          {options.map((o) => (
            <button
              key={o.value}
              className={`ai-dd-item ${o.value === value ? 'is-active' : ''}`}
              onClick={() => { onChange(o.value); setOpen(false); }}
            >
              {renderItem ? renderItem(o) : o.label}
              {o.value === value ? <IconCheck size={14} /> : null}
            </button>
          ))}
        </div>
      )}
    </div>
  );
}

// ─── Card / Section ───────────────────────────────────────────────────────
function Field({ label, hint, children, action }) {
  return (
    <div className="ai-field">
      <div className="ai-field-lbl">
        <span>{label}</span>
        {action}
      </div>
      {children}
      {hint && <p className="ai-field-hint">{hint}</p>}
    </div>
  );
}

// ─── Spinner ──────────────────────────────────────────────────────────────
function Spinner({ size = 18 }) {
  return (
    <span className="ai-spinner" style={{ width: size, height: size }}>
      <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2"
           strokeLinecap="round">
        <circle cx="12" cy="12" r="9" opacity="0.18" />
        <path d="M21 12a9 9 0 0 0-9-9" />
      </svg>
    </span>
  );
}

// ─── Avatar / mini composition for history items ─────────────────────────
function Thumb({ prompt, seed, imageUrl, size = 56, radius = 10, onClick, favorite, selected }) {
  return (
    <button
      className={`ai-thumb ${selected ? 'is-selected' : ''}`}
      style={{ width: size, height: size, borderRadius: radius }}
      onClick={onClick}
      title={prompt}
    >
      {imageUrl ? (
        <img src={imageUrl} alt={prompt}
             style={{ width: '100%', height: '100%', objectFit: 'cover', display: 'block' }} />
      ) : (
        <GenSVG prompt={prompt} seed={seed} style={{ width: '100%', height: '100%', display: 'block' }} />
      )}
      {favorite ? <span className="ai-thumb-fav"><IconHeartFill size={11} /></span> : null}
    </button>
  );
}

// ─── Aspect ratio swatches ────────────────────────────────────────────────
const ASPECTS = [
  { value: '1:1',  w: 1,    h: 1 },
  { value: '3:2',  w: 1.5,  h: 1 },
  { value: '2:3',  w: 1,    h: 1.5 },
  { value: '16:9', w: 1.78, h: 1 },
  { value: '9:16', w: 1,    h: 1.78 },
  { value: '4:5',  w: 0.8,  h: 1 },
];

function AspectPicker({ value, onChange }) {
  return (
    <div className="ai-aspect-grid">
      {ASPECTS.map((a) => {
        const max = 22;
        const w = a.w >= a.h ? max : max * (a.w / a.h);
        const h = a.h >= a.w ? max : max * (a.h / a.w);
        const isActive = value === a.value;
        return (
          <button
            key={a.value}
            className={`ai-aspect ${isActive ? 'is-active' : ''}`}
            onClick={() => onChange(a.value)}
          >
            <span className="ai-aspect-glyph"
                  style={{ width: w, height: h, borderRadius: 3 }} />
            <span className="ai-aspect-lbl">{a.value}</span>
          </button>
        );
      })}
    </div>
  );
}

// ─── Utility hooks ────────────────────────────────────────────────────────
function useLocalState(key, initial) {
  const [v, setV] = useState(() => {
    try {
      const raw = localStorage.getItem(key);
      if (raw != null) return JSON.parse(raw);
    } catch (_) {}
    return initial;
  });
  useEffect(() => {
    try { localStorage.setItem(key, JSON.stringify(v)); } catch (_) {}
  }, [key, v]);
  return [v, setV];
}

// Aspect → ratio number (w / h) helper
function aspectRatio(value) {
  const a = ASPECTS.find((x) => x.value === value) || ASPECTS[0];
  return a.w / a.h;
}

Object.assign(window, {
  Tooltip, Button, IconButton, Slider, Segmented, Switch, Dropdown,
  Field, Spinner, Thumb, AspectPicker, ASPECTS, aspectRatio, useLocalState,
});
