/* Common UI Primitives */
(function () {
  const { useState, useEffect, useRef } = React;

  /* ---- Modal ---- */
  function Modal({ open, onClose, title, children, actions, wide }) {
    useEffect(() => {
      if (!open) return;
      const handler = (e) => { if (e.key === 'Escape') onClose(); };
      document.addEventListener('keydown', handler);
      return () => document.removeEventListener('keydown', handler);
    }, [open, onClose]);

    if (!open) return null;

    return (
      <div className="modal-overlay" onClick={(e) => { if (e.target === e.currentTarget) onClose(); }}>
        <div className="modal-box" style={wide ? { maxWidth: 780 } : {}} onClick={(e) => e.stopPropagation()}>
          <div className="modal-header">
            <span className="modal-title">{title}</span>
            <button className="modal-close" onClick={onClose} aria-label="閉じる">✕</button>
          </div>
          <div className="modal-body">{children}</div>
          {actions && <div className="modal-footer">{actions}</div>}
        </div>
      </div>
    );
  }

  /* ---- Toast ---- */
  let _setToast = null;

  function Toast() {
    const [toasts, setToasts] = useState([]);
    _setToast = (msg, kind) => {
      const id = Date.now();
      setToasts((prev) => [...prev, { id, msg, kind: kind || 'default' }]);
      setTimeout(() => setToasts((prev) => prev.filter((t) => t.id !== id)), 2800);
    };

    return (
      <div className="toast-container">
        {toasts.map((t) => (
          <div key={t.id} className={'toast ' + t.kind}>{t.msg}</div>
        ))}
      </div>
    );
  }

  function showToast(msg, kind) {
    if (_setToast) _setToast(msg, kind);
  }

  /* ---- StatusTag ---- */
  function StatusTag({ status }) {
    const { STATUS_LABELS } = window.AppStore;
    return (
      <span className={'status-tag ' + status}>{STATUS_LABELS[status] || status}</span>
    );
  }

  /* ---- ViewSwitch ---- */
  function ViewSwitch({ value, onChange, options }) {
    return (
      <div className="view-switch">
        {options.map((opt) => (
          <button
            key={opt.value}
            className={'view-switch-btn' + (value === opt.value ? ' active' : '')}
            onClick={() => onChange(opt.value)}
          >
            {opt.label}
          </button>
        ))}
      </div>
    );
  }

  /* ---- Field ---- */
  function Field({ label, children, hint, required }) {
    return (
      <div className="field">
        {label && (
          <label className="field-label">
            {label}
            {required && <span style={{ color: 'var(--danger)', marginLeft: 2 }}>*</span>}
          </label>
        )}
        {children}
        {hint && <span className="field-hint">{hint}</span>}
      </div>
    );
  }

  /* ---- StaffInput ---- */
  function StaffInput({ value, onChange }) {
    const [input, setInput] = useState('');

    function add() {
      const name = input.trim();
      if (!name) return;
      if (!value.includes(name)) onChange([...value, name]);
      setInput('');
    }

    function remove(name) {
      onChange(value.filter((n) => n !== name));
    }

    return (
      <div>
        <div className="staff-tags">
          {value.map((name) => (
            <span key={name} className="staff-tag">
              {name}
              <button className="staff-tag-remove" onClick={() => remove(name)} type="button">×</button>
            </span>
          ))}
        </div>
        <div style={{ display: 'flex', gap: 6 }}>
          <input
            value={input}
            onChange={(e) => setInput(e.target.value)}
            onKeyDown={(e) => { if (e.key === 'Enter') { e.preventDefault(); add(); } }}
            placeholder="名前を入力してEnter"
            style={{ flex: 1 }}
          />
          <button type="button" className="btn btn-secondary btn-sm" onClick={add}>追加</button>
        </div>
      </div>
    );
  }

  window.Common = { Modal, Toast, showToast, StatusTag, ViewSwitch, Field, StaffInput };
})();
