/* Overlay & form primitives shared across Monolit screens:
   Modal, Drawer, Dropdown (popover), ConfirmDialog + form controls. */
const { useState: useStateOv, useEffect: useEffectOv, useRef: useRefOv } = React;

// ---------- scroll-lock + Esc helper ---------------------------------------
function useDismiss(open, onClose) {
  useEffectOv(() => {
    if (!open) return;
    function onKey(e) { if (e.key === 'Escape') { e.stopPropagation(); onClose && onClose(); } }
    document.addEventListener('keydown', onKey, true);
    const prev = document.body.style.overflow;
    document.body.style.overflow = 'hidden';
    return () => { document.removeEventListener('keydown', onKey, true); document.body.style.overflow = prev; };
  }, [open]);
}

// ---------- Modal (centered) ------------------------------------------------
// Focus-managed: autofocuses the first control on open and traps Tab inside the
// dialog (NFR-BA-05 keyboard accessibility).
function Modal({ open, onClose, title, subtitle, eyebrow, icon, iconTone, footer, size = 'md', children, dismissable = true }) {
  useDismiss(open, dismissable ? onClose : undefined);
  const boxRef = useRefOv(null);
  useEffectOv(() => {
    if (!open || !boxRef.current) return;
    const el = boxRef.current.querySelector('[data-autofocus], .mn-modal-body input:not([disabled]), .mn-modal-body select:not([disabled]), .mn-modal-body textarea, .mn-modal-body button') || boxRef.current;
    if (el && el.focus) el.focus();
  }, [open]);
  function onTrapKey(e) {
    if (e.key !== 'Tab' || !boxRef.current) return;
    const f = Array.from(boxRef.current.querySelectorAll('button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])')).filter(x => !x.disabled && x.offsetParent !== null);
    if (!f.length) return;
    const first = f[0], last = f[f.length - 1];
    if (e.shiftKey && document.activeElement === first) { e.preventDefault(); last.focus(); }
    else if (!e.shiftKey && document.activeElement === last) { e.preventDefault(); first.focus(); }
  }
  if (!open) return null;
  return ReactDOM.createPortal(
    <div className="mn-overlay" onMouseDown={(e) => { if (dismissable && e.target === e.currentTarget) onClose && onClose(); }}>
      <div ref={boxRef} tabIndex={-1} onKeyDown={onTrapKey} className={`mn-modal mn-modal--${size}`} role="dialog" aria-modal="true">
        {(title || eyebrow) ? (
          <header className="mn-modal-h">
            {icon ? <span className={`mn-modal-icon mn-modal-icon--${iconTone || 'neutral'}`}><Icon name={icon} size="md" /></span> : null}
            <div style={{ flex: 1, minWidth: 0 }}>
              {eyebrow ? <div className="mn-eyebrow">{eyebrow}</div> : null}
              {title ? <h2 className="title-3 mn-modal-title">{title}</h2> : null}
              {subtitle ? <p className="mn-modal-sub">{subtitle}</p> : null}
            </div>
            {dismissable ? <IconButton icon="x" size="md" title="Close" onClick={onClose} /> : null}
          </header>
        ) : null}
        <div className="mn-modal-body">{children}</div>
        {footer ? <footer className="mn-modal-foot">{footer}</footer> : null}
      </div>
    </div>,
    document.body
  );
}

// ---------- Drawer (right side panel) --------------------------------------
function Drawer({ open, onClose, title, subtitle, eyebrow, footer, width = 480, children, dismissable = true }) {
  useDismiss(open, dismissable ? onClose : undefined);
  if (!open) return null;
  return ReactDOM.createPortal(
    <div className="mn-overlay mn-overlay--right" onMouseDown={(e) => { if (dismissable && e.target === e.currentTarget) onClose && onClose(); }}>
      <div className="mn-drawer" style={{ width }} role="dialog" aria-modal="true">
        <header className="mn-drawer-h">
          <div style={{ flex: 1, minWidth: 0 }}>
            {eyebrow ? <div className="mn-eyebrow">{eyebrow}</div> : null}
            {title ? <h2 className="title-3 mn-modal-title">{title}</h2> : null}
            {subtitle ? <p className="mn-modal-sub">{subtitle}</p> : null}
          </div>
          <IconButton icon="x" size="md" title="Close" onClick={onClose} />
        </header>
        <div className="mn-drawer-body">{children}</div>
        {footer ? <footer className="mn-modal-foot">{footer}</footer> : null}
      </div>
    </div>,
    document.body
  );
}

// ---------- Dropdown / popover (self-managed) ------------------------------
function Dropdown({ trigger, children, align = 'right', width = 300, panelClass }) {
  const [open, setOpen] = useStateOv(false);
  const ref = useRefOv(null);
  useEffectOv(() => {
    if (!open) return;
    function onDoc(e) { if (ref.current && !ref.current.contains(e.target)) setOpen(false); }
    function onKey(e) { if (e.key === 'Escape') setOpen(false); }
    document.addEventListener('mousedown', onDoc);
    document.addEventListener('keydown', onKey);
    return () => { document.removeEventListener('mousedown', onDoc); document.removeEventListener('keydown', onKey); };
  }, [open]);
  return (
    <div className="mn-dd" ref={ref}>
      {trigger({ open, toggle: () => setOpen(o => !o), close: () => setOpen(false) })}
      {open ? (
        <div className={'mn-dd-panel mn-dd-panel--' + align + (panelClass ? ' ' + panelClass : '')} style={{ width }}>
          {typeof children === 'function' ? children({ close: () => setOpen(false) }) : children}
        </div>
      ) : null}
    </div>
  );
}

// ---------- ConfirmDialog ---------------------------------------------------
function ConfirmDialog({ open, onClose, onConfirm, title, body, confirmLabel = 'Confirm', cancelLabel = 'Cancel', tone = 'primary', icon = 'alert-triangle' }) {
  return (
    <Modal open={open} onClose={onClose} title={title} icon={icon} iconTone={tone === 'destructive' ? 'error' : 'warning'} size="sm"
      footer={<React.Fragment>
        <Button variant="ghost" size="md" onClick={onClose}>{cancelLabel}</Button>
        <Button variant={tone === 'destructive' ? 'destructive' : 'primary'} size="md" onClick={onConfirm}>{confirmLabel}</Button>
      </React.Fragment>}>
      <div style={{ font: 'var(--font-weight-default) 14px/22px var(--font-sans)', color: 'var(--text-1)' }}>{body}</div>
    </Modal>
  );
}

// ---------- Form controls ---------------------------------------------------
function Select({ value, onChange, options, placeholder, fullWidth, size = 'md', disabled }) {
  // options: ['a'] or [{value,label}]
  const norm = options.map(o => (typeof o === 'string' ? { value: o, label: o } : o));
  const cls = ['mn-select', `mn-input--${size}`];
  if (fullWidth) cls.push('mn-input--full');
  return (
    <label className={cls.join(' ')}>
      <select value={value} disabled={disabled} onChange={(e) => onChange && onChange(e.target.value)}>
        {placeholder ? <option value="" disabled>{placeholder}</option> : null}
        {norm.map(o => <option key={o.value} value={o.value}>{o.label}</option>)}
      </select>
      <Icon name="chevron-down" size="xs" color="text-3" />
    </label>
  );
}

function Textarea({ value, onChange, placeholder, rows = 3, maxLength, fullWidth }) {
  return (
    <div className={'mn-textarea' + (fullWidth ? ' mn-input--full' : '')}>
      <textarea value={value} placeholder={placeholder} rows={rows} maxLength={maxLength}
                onChange={(e) => onChange && onChange(e.target.value)} />
      {maxLength ? <span className="mn-textarea-count">{(value || '').length}/{maxLength}</span> : null}
    </div>
  );
}

function RadioGroup({ value, onChange, options, name }) {
  const norm = options.map(o => (typeof o === 'string' ? { value: o, label: o } : o));
  return (
    <div className="mn-radiogroup">
      {norm.map(o => (
        <label key={o.value} className={'mn-radio' + (value === o.value ? ' mn-radio--on' : '')}>
          <input type="radio" name={name} checked={value === o.value} onChange={() => onChange && onChange(o.value)} />
          <span className="mn-radio-dot" />
          <span style={{ flex: 1 }}>
            <span className="mn-radio-lbl">{o.label}</span>
            {o.hint ? <span className="mn-radio-hint">{o.hint}</span> : null}
          </span>
        </label>
      ))}
    </div>
  );
}

function SegControl({ value, onChange, options }) {
  const norm = options.map(o => (typeof o === 'string' ? { value: o, label: o } : o));
  return (
    <div className="mn-seg" role="tablist">
      {norm.map(o => (
        <button key={o.value} type="button" role="tab" aria-selected={value === o.value}
                className={'mn-seg-btn' + (value === o.value ? ' mn-seg-btn--on' : '')}
                onClick={() => onChange && onChange(o.value)}>{o.label}</button>
      ))}
    </div>
  );
}

function Checkbox({ checked, onChange, label, hint }) {
  return (
    <label className="mn-check-row">
      <input type="checkbox" className="mn-checkbox" checked={checked} onChange={(e) => onChange && onChange(e.target.checked)} />
      <span>
        <span className="mn-check-lbl">{label}</span>
        {hint ? <span className="mn-check-hint">{hint}</span> : null}
      </span>
    </label>
  );
}

function TagInput({ tags, onChange, suggestions = [], placeholder = 'Add tag…' }) {
  const [draft, setDraft] = useStateOv('');
  function add(t) {
    t = (t || '').trim();
    if (!t || tags.includes(t)) { setDraft(''); return; }
    onChange([...tags, t]); setDraft('');
  }
  return (
    <div className="mn-taginput">
      <div className="mn-taginput-row">
        {tags.map(t => (
          <span key={t} className="mn-chip mn-chip--tag">{t}
            <button type="button" className="mn-chip-x" onClick={() => onChange(tags.filter(x => x !== t))}><Icon name="x" size="xs" stroke="2" /></button>
          </span>
        ))}
        <input value={draft} placeholder={tags.length ? '' : placeholder}
               onChange={(e) => setDraft(e.target.value)}
               onKeyDown={(e) => { if (e.key === 'Enter') { e.preventDefault(); add(draft); } if (e.key === 'Backspace' && !draft && tags.length) onChange(tags.slice(0, -1)); }} />
      </div>
      {suggestions.filter(s => !tags.includes(s)).length ? (
        <div className="mn-taginput-sug">
          {suggestions.filter(s => !tags.includes(s)).slice(0, 6).map(s => (
            <button key={s} type="button" className="mn-chip mn-chip--tag mn-chip--btn" onClick={() => add(s)}>+ {s}</button>
          ))}
        </div>
      ) : null}
    </div>
  );
}

// Owner picker — active users scoped by role
function OwnerPicker({ value, onChange, role, allowUnassigned }) {
  const RB = window.MonolitRBAC;
  const D = window.MonolitData;
  let pool = D.owners;
  if (role === 'Manager') pool = D.owners.filter(o => RB.TEAM_IDS.includes(o.id));
  const opts = pool.map(o => ({ value: o.id, label: o.name }));
  if (allowUnassigned) opts.unshift({ value: '', label: 'Unassigned (intake pool)' });
  return <Select fullWidth value={value} onChange={onChange} options={opts} placeholder="Select owner…" />;
}

Object.assign(window, {
  Modal, Drawer, Dropdown, ConfirmDialog,
  Select, Textarea, RadioGroup, SegControl, Checkbox, TagInput, OwnerPicker,
});
