// Shared icon set + tiny UI atoms used everywhere.
// Stroke icons in the style of Lucide/Phosphor.

const Icon = ({ name, size = 16, stroke = 1.75, ...rest }) => {
  const paths = {
    dashboard: <><rect x="3" y="3" width="7" height="9" rx="1.5"/><rect x="14" y="3" width="7" height="5" rx="1.5"/><rect x="14" y="12" width="7" height="9" rx="1.5"/><rect x="3" y="16" width="7" height="5" rx="1.5"/></>,
    globe:    <><circle cx="12" cy="12" r="9"/><path d="M3 12h18"/><path d="M12 3c2.5 3 2.5 15 0 18"/><path d="M12 3c-2.5 3-2.5 15 0 18"/></>,
    server:   <><rect x="3" y="4" width="18" height="7" rx="1.5"/><rect x="3" y="13" width="18" height="7" rx="1.5"/><circle cx="7" cy="7.5" r=".7" fill="currentColor" stroke="none"/><circle cx="7" cy="16.5" r=".7" fill="currentColor" stroke="none"/></>,
    approval: <><path d="M9 12l2 2 4-4"/><circle cx="12" cy="12" r="9"/></>,
    clients:  <><circle cx="9" cy="9" r="3.2"/><path d="M3.5 19c.5-2.7 3-4.5 5.5-4.5s5 1.8 5.5 4.5"/><circle cx="17" cy="8" r="2.5"/><path d="M15 14.4c2-.6 4 .6 5 2.6"/></>,
    employee: <><circle cx="12" cy="8" r="3.5"/><path d="M5 20c.5-3.5 3.5-6 7-6s6.5 2.5 7 6"/></>,
    plus:     <><path d="M12 5v14"/><path d="M5 12h14"/></>,
    search:   <><circle cx="11" cy="11" r="7"/><path d="M20 20l-3.5-3.5"/></>,
    edit:     <><path d="M4 20h4l10-10-4-4L4 16v4z"/><path d="M14 6l4 4"/></>,
    trash:    <><path d="M4 7h16"/><path d="M9 7V4h6v3"/><path d="M6 7l1 13h10l1-13"/></>,
    check:    <><path d="M5 12l5 5L20 7"/></>,
    x:        <><path d="M6 6l12 12"/><path d="M18 6L6 18"/></>,
    chevron:  <><path d="M9 6l6 6-6 6"/></>,
    clock:    <><circle cx="12" cy="12" r="9"/><path d="M12 7v5l3.5 2"/></>,
    alert:    <><path d="M12 3l10 18H2L12 3z"/><path d="M12 10v4"/><circle cx="12" cy="17.5" r=".8" fill="currentColor" stroke="none"/></>,
    cash:     <><rect x="3" y="6" width="18" height="12" rx="2"/><circle cx="12" cy="12" r="2.5"/><path d="M6 9v6M18 9v6"/></>,
    sort:     <><path d="M7 4v16"/><path d="M3 8l4-4 4 4"/><path d="M17 20V4"/><path d="M13 16l4 4 4-4"/></>,
    filter:   <><path d="M3 5h18l-7 9v6l-4-2v-4L3 5z"/></>,
    info:     <><circle cx="12" cy="12" r="9"/><path d="M12 11v5"/><circle cx="12" cy="8" r=".9" fill="currentColor" stroke="none"/></>,
    refresh:  <><path d="M4 12a8 8 0 0 1 14-5.3L20 9"/><path d="M20 4v5h-5"/><path d="M20 12a8 8 0 0 1-14 5.3L4 15"/><path d="M4 20v-5h5"/></>,
    eye:      <><path d="M2 12s3.5-7 10-7 10 7 10 7-3.5 7-10 7S2 12 2 12z"/><circle cx="12" cy="12" r="3"/></>,
    key:      <><circle cx="9" cy="14" r="3.5"/><path d="M12 11l8-8"/><path d="M16 7l2 2"/></>,
    mail:     <><rect x="3" y="5" width="18" height="14" rx="2"/><path d="M3 7l9 7 9-7"/></>,
    pending:  <><circle cx="12" cy="12" r="9"/><path d="M12 7v5"/><path d="M12 16h.01"/></>,
    history:  <><path d="M3 12a9 9 0 1 0 3-6.7L3 8"/><path d="M3 4v4h4"/><path d="M12 8v4l3 2"/></>,
    archive:  <><rect x="3" y="4" width="18" height="4" rx="1"/><path d="M5 8v11a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1V8"/><path d="M10 12h4"/></>,
    moreH:    <><circle cx="6" cy="12" r="1.2" fill="currentColor" stroke="none"/><circle cx="12" cy="12" r="1.2" fill="currentColor" stroke="none"/><circle cx="18" cy="12" r="1.2" fill="currentColor" stroke="none"/></>,
    shield:   <><path d="M12 3l8 3v6c0 5-4 8-8 9-4-1-8-4-8-9V6l8-3z"/></>,
    download: <><path d="M12 4v12"/><path d="M7 11l5 5 5-5"/><path d="M4 20h16"/></>,
    bell:     <><path d="M18 8A6 6 0 0 0 6 8c0 7-3 9-3 9h18s-3-2-3-9"/><path d="M13.73 21a2 2 0 0 1-3.46 0"/></>,
    send:     <><path d="M22 2L11 13"/><path d="M22 2L15 22l-4-9-9-4 20-7z"/></>,
  };
  return (
    <svg viewBox="0 0 24 24" width={size} height={size} fill="none" stroke="currentColor" strokeWidth={stroke} strokeLinecap="round" strokeLinejoin="round" {...rest}>
      {paths[name] || null}
    </svg>
  );
};

const StatusBadge = ({ iso }) => {
  const s = window.expiryStatus(iso);
  return <span className={`badge dot ${s.tone}`}>{s.label}</span>;
};

const KindPill = ({ kind }) => (
  <span className={`kind-pill ${kind}`}>
    <Icon name={kind === 'domain' ? 'globe' : 'server'} size={11} stroke={2} />
    {kind === 'domain' ? 'Domain' : 'Server'}
  </span>
);

// Avatar from a name (initials + colored swatch)
const initials = (s) => s.split(' ').map(p => p[0]).slice(0, 2).join('').toUpperCase();
const avatarColors = [
  ['#fbbf24', '#f97316'],
  ['#60a5fa', '#2563eb'],
  ['#34d399', '#059669'],
  ['#f472b6', '#db2777'],
  ['#a78bfa', '#7c3aed'],
  ['#fb7185', '#e11d48'],
];
const hashCode = (s) => { let h = 0; for (const c of s) h = (h * 31 + c.charCodeAt(0)) | 0; return Math.abs(h); };
const Avatar = ({ name, size = 26 }) => {
  const [a, b] = avatarColors[hashCode(name) % avatarColors.length];
  return (
    <div className="avatar" style={{ width: size, height: size, fontSize: Math.round(size * 0.42), background: `linear-gradient(135deg, ${a}, ${b})` }}>
      {initials(name)}
    </div>
  );
};

// Sortable table header
const Th = ({ label, field, sort, onSort, align, noSort }) => {
  const active = sort && sort.field === field;
  return (
    <th
      className={`${active ? 'sorted' : ''} ${noSort ? 'no-sort' : ''}`}
      style={{ textAlign: align || 'left' }}
      onClick={noSort ? undefined : () => onSort(field)}
    >
      {label}
      {!noSort && <span className="sort-arrow">{active ? (sort.dir === 'asc' ? '▲' : '▼') : '↕'}</span>}
    </th>
  );
};

const SectionTitle = ({ children }) => (
  <div className="section-head"><span>{children}</span><span className="line"></span></div>
);

const Empty = ({ icon = 'archive', title, body, action }) => (
  <div className="empty">
    <div className="empty-icon"><Icon name={icon} size={20} /></div>
    <h4>{title}</h4>
    <p>{body}</p>
    {action && <div style={{ marginTop: 14 }}>{action}</div>}
  </div>
);

window.Icon = Icon;
window.StatusBadge = StatusBadge;
window.KindPill = KindPill;
window.Avatar = Avatar;
window.Th = Th;
window.SectionTitle = SectionTitle;
window.Empty = Empty;

// ── Styled dropdown ──────────────────────────────────────────────
// options: [{ value, label, meta?, icon?, tone?, swatch? }] OR plain strings
// Pass an `icon` (lucide name) to render as a leading icon; pass `placeholder`
// to render unselected state; pass `clearable` to allow resetting to ''.
const StyledSelect = ({
  label, value, options, onChange,
  placeholder = 'Any', icon, clearable = false,
  align = 'left', minWidth, leadingTone, renderValue,
}) => {
  const [open, setOpen] = React.useState(false);
  const ref = React.useRef(null);

  React.useEffect(() => {
    if (!open) return;
    const onDoc = (e) => { if (ref.current && !ref.current.contains(e.target)) setOpen(false); };
    const onEsc = (e) => { if (e.key === 'Escape') setOpen(false); };
    document.addEventListener('mousedown', onDoc);
    document.addEventListener('keydown', onEsc);
    return () => {
      document.removeEventListener('mousedown', onDoc);
      document.removeEventListener('keydown', onEsc);
    };
  }, [open]);

  const norm = options.map(o => typeof o === 'string' ? { value: o, label: o } : o);
  const current = norm.find(o => o.value === value);
  const showPlaceholder = !current;

  const display = renderValue
    ? renderValue(current, showPlaceholder)
    : (current?.label || placeholder);

  return (
    <div className="dd" ref={ref} style={{ minWidth }}>
      <button
        type="button"
        className={`dd-trigger ${open ? 'open' : ''} ${showPlaceholder ? 'placeholder' : ''}`}
        onClick={() => setOpen(o => !o)}
      >
        {icon && (
          <span className={`dd-leading ${leadingTone || ''}`}>
            <Icon name={icon} size={11} stroke={2} />
          </span>
        )}
        {label && <span className="dd-label">{label}:</span>}
        <span className="dd-value">{display}</span>
        {clearable && current && (
          <span
            className="dd-clear"
            onClick={(e) => { e.stopPropagation(); onChange(''); }}
            role="button"
            aria-label="Clear"
          >
            <Icon name="x" size={11} stroke={2.2} />
          </span>
        )}
        <span className="dd-chev"><Icon name="chevron" size={11} stroke={2.2} style={{ transform: 'rotate(90deg)' }} /></span>
      </button>
      {open && (
        <div className={`dd-menu ${align === 'right' ? 'align-right' : ''}`}>
          {norm.map((o, i) => (
            o.section ? (
              <div className="dd-menu-section" key={'s' + i}>{o.section}</div>
            ) : o.divider ? (
              <div className="dd-divider" key={'d' + i} />
            ) : (
              <div
                key={o.value}
                className={`dd-option ${o.value === value ? 'selected' : ''}`}
                onClick={() => { onChange(o.value); setOpen(false); }}
              >
                {o.icon && (
                  <span className="dd-opt-icon">
                    <Icon name={o.icon} size={12} stroke={2} />
                  </span>
                )}
                {o.swatch && (
                  <span className="dd-swatch" style={{ color: o.swatch }} />
                )}
                <span>{o.label}</span>
                {o.meta && <span className="dd-opt-meta">{o.meta}</span>}
                <span className="dd-check"><Icon name="check" size={12} stroke={2.4} /></span>
              </div>
            )
          ))}
        </div>
      )}
    </div>
  );
};

window.StyledSelect = StyledSelect;
