/* global React, Ic */
// shared.jsx — reusable primitives

const { useState, useEffect } = React;

function Btn({ variant = "primary", size, block, children, onClick, icon, iconRight, disabled, type = "button" }) {
  return (
    <button
      type={type}
      disabled={disabled}
      aria-disabled={disabled || undefined}
      className={`btn btn-${variant} ${size === "sm" ? "btn-small" : ""} ${block ? "btn-block" : ""}`}
      onClick={disabled ? undefined : onClick}
    >
      {icon}{children}{iconRight}
    </button>
  );
}

function Field({ label, children, required, error, hint }) {
  // m-11 · pass aria-required into Input when required + child is an Input
  const kids = React.Children.map(children, child =>
    required && child && child.type === Input
      ? React.cloneElement(child, { ariaRequired: true })
      : child
  );
  return (
    <div className="field">
      <label>
        {label}
        {required && <span aria-hidden="true" style={{ color: "var(--alert)", marginLeft: 4 }}>*</span>}
        {required && <span className="sr-only">(required)</span>}
      </label>
      {kids}
      {error && (
        <div role="alert" style={{ font: "500 12px/1.3 var(--font-ui)", color: "var(--alert)", marginTop: 4 }}>
          {error}
        </div>
      )}
      {hint && !error && (
        <div style={{ font: "500 12px/1.3 var(--font-ui)", color: "var(--ink-2)", marginTop: 4 }}>
          {hint}
        </div>
      )}
    </div>
  );
}

function Input({ value, onChange, placeholder, leftIcon, rightIcon, type = "text", disabled, min, max, autoComplete, ariaRequired }) {
  return (
    <div className="input-icon" style={disabled ? { opacity: .5 } : undefined}>
      {leftIcon}
      <input
        type={type}
        value={value || ""}
        disabled={disabled}
        min={min}
        max={max}
        autoComplete={autoComplete}
        aria-required={ariaRequired || undefined}
        onChange={e => onChange && onChange(e.target.value)}
        placeholder={placeholder}
        style={{
          outlineOffset: "var(--focus-offset)",
        }}
        onFocus={e => { e.target.style.outline = "var(--focus-ring)"; }}
        onBlur={e => { e.target.style.outline = "none"; }}
      />
      {rightIcon}
    </div>
  );
}

// SB4 m-10 · Textarea primitive — replaces inline <textarea> chrome in GA-061 / GA-071
function Textarea({ value, onChange, placeholder, rows = 4, disabled, required, ariaRequired }) {
  return (
    <textarea
      value={value || ""}
      disabled={disabled}
      aria-required={ariaRequired || required || undefined}
      placeholder={placeholder}
      rows={rows}
      onChange={e => onChange && onChange(e.target.value)}
      className="input"
      style={{
        height: "auto",
        minHeight: rows * 24,
        padding: "12px 18px",
        fontFamily: "var(--font-ui)",
        resize: "vertical",
      }}
    />
  );
}

function Select({ value, onChange, children, placeholder, disabled }) {
  return (
    <div className="input-icon" style={{ position: "relative", opacity: disabled ? 0.5 : 1 }}>
      <select
        value={value || ""}
        disabled={disabled}
        onChange={e => onChange && onChange(e.target.value)}
        style={{
          flex: 1, border: 0, background: "transparent", appearance: "none",
          height: "100%", color: value ? "var(--forest)" : "var(--mint)",
          fontWeight: 500, fontSize: 15,
          cursor: disabled ? "not-allowed" : "pointer",
        }}>
        <option value="" disabled hidden>{placeholder}</option>
        {children}
      </select>
      <span style={{ color: "var(--forest)" }}>{Ic.chevD(18)}</span>
    </div>
  );
}

function SearchBar({ value, onChange, placeholder = "Search" }) {
  return (
    <div className="row ai-c" style={{ gap: 12 }}>
      <span style={{ color: "var(--forest)" }}>{Ic.search(28)}</span>
      <div className="input-icon grow">
        <input value={value || ""} onChange={e => onChange && onChange(e.target.value)} placeholder={placeholder}/>
      </div>
    </div>
  );
}

function Checkbox({ on, onToggle }) {
  return (
    <span className={`check ${on ? "on" : ""}`} onClick={e => { e.stopPropagation(); onToggle && onToggle(); }}>
      {on && (
        <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="#FFF9ED" strokeWidth="3.2" strokeLinecap="round" strokeLinejoin="round">
          <path d="M5 12l5 5L20 7"/>
        </svg>
      )}
    </span>
  );
}

function Pagination({ page = 1, total = 10, onPage }) {
  const pages = [1, 2, 3, 4, 5, "...", total];
  return (
    <div className="pager">
      <button className={`nav ${page <= 1 ? "disabled" : ""}`} onClick={() => page > 1 && onPage && onPage(page - 1)}>
        {Ic.chevL(18)} Previous
      </button>
      <div className="pages">
        {pages.map((p, i) =>
          p === "..." ? <span key={i}>…</span> :
          <button key={i} className={p === page ? "active" : ""} onClick={() => onPage && onPage(p)}>{p}</button>
        )}
      </div>
      <button className={`nav ${page >= total ? "disabled" : ""}`} onClick={() => page < total && onPage && onPage(page + 1)}>
        Next {Ic.chevR(18)}
      </button>
    </div>
  );
}

function Showing({ count, onCountChange }) {
  return (
    <div className="row jc-e ai-c" style={{ gap: 12 }}>
      <span style={{ fontWeight: 700, color: "var(--forest)", fontSize: 15 }}>Showing</span>
      <div className="input-icon" style={{ width: 110, height: 44 }}>
        <select value={count} onChange={e => onCountChange(+e.target.value)} style={{ flex: 1, border: 0, background: "transparent", appearance: "none", fontWeight: 700, color: "var(--forest)" }}>
          {[10, 20, 50, 100].map(n => <option key={n} value={n}>{n}</option>)}
        </select>
        <span style={{ color: "var(--forest)" }}>{Ic.chevD(16)}</span>
      </div>
    </div>
  );
}

function Table({ columns, rows, onRow, selected, onToggleSelected, emptyText = "No records" }) {
  return (
    <div className="table">
      <div className="table-scroll">
      <table>
        <thead>
          <tr>
            {onToggleSelected && (
              <th style={{ width: 48 }}>
                <Checkbox on={selected && selected.all} onToggle={() => onToggleSelected("all")}/>
              </th>
            )}
            {columns.map((c, i) => (
              <th key={i} style={{ width: c.width }}>
                <span className="th-inner">{c.label} {c.sortable && Ic.sort(14)}</span>
              </th>
            ))}
          </tr>
        </thead>
        <tbody>
          {rows.length === 0 && <tr><td colSpan={columns.length + (onToggleSelected ? 1 : 0)} className="text-center text-muted" style={{ padding: 40 }}>{emptyText}</td></tr>}
          {rows.map((r, i) => (
            <tr
              key={r.id || i}
              className={selected && selected[r.id] ? "selected" : ""}
              onClick={() => onRow && onRow(r)}
              tabIndex={onRow ? 0 : undefined}
              role={onRow ? "button" : undefined}
              onKeyDown={onRow ? (e => { if (e.key === "Enter" || e.key === " ") { e.preventDefault(); onRow(r); } }) : undefined}
            >
              {onToggleSelected && (
                <td onClick={e => e.stopPropagation()}>
                  <Checkbox on={selected && (selected[r.id] || selected.all)} onToggle={() => onToggleSelected(r.id)}/>
                </td>
              )}
              {columns.map((c, j) => <td key={j}>{c.render ? c.render(r) : r[c.key]}</td>)}
            </tr>
          ))}
        </tbody>
      </table>
      </div>
    </div>
  );
}

function PageHead({ title, actions }) {
  return (
    <div className="page-head">
      <h1 className="h-page">{title}</h1>
      {actions}
    </div>
  );
}

// SB5 rectification · m-5 — Mono primitive (replaces ~25 inline _MONO spans)
function Mono({ children, size = "md", muted }) {
  const fs = size === "sm" ? 12 : 13;
  return (
    <span style={{
      fontFamily: "ui-monospace, Menlo, monospace",
      fontFeatureSettings: '"tnum"',
      fontWeight: 600,
      fontSize: fs,
      color: muted ? "var(--ink-2)" : "inherit",
    }}>{children}</span>
  );
}

function Toast({ message, show }) {
  return (
    <div className={`toast ${show ? "show" : ""}`} role="status" aria-live="polite">
      <span style={{ color: "var(--lime)" }}>{Ic.check(18)}</span>
      <span>{message}</span>
    </div>
  );
}

Object.assign(window, { Btn, Field, Input, Textarea, Select, SearchBar, Checkbox, Pagination, Showing, Table, PageHead, Toast, Mono });
