// Overlay primitives: Modal, Drawer, Popover, Tooltip, Toast stack, Dropdown, ConfirmDialog

// Portal
const Portal = ({ children }) => {
  const [el] = React.useState(() => {
    const d = document.createElement('div');
    d.className = '__portal';
    return d;
  });
  React.useEffect(() => {
    document.body.appendChild(el);
    return () => { el.remove(); };
  }, [el]);
  return ReactDOM.createPortal(children, el);
};

// --- MODAL ---
const Modal = ({ open, onClose, title, desc, children, footer, size = 'md', closeOnBackdrop = true, zIndex = 1000 }) => {
  const render = useDelayUnmount(open, MOTION.dur.base);
  const widths = { sm: 380, md: 480, lg: 640, xl: 820 };
  React.useEffect(() => {
    if (!open) return;
    const prev = document.body.style.overflow;
    document.body.style.overflow = 'hidden';
    const onKey = e => e.key === 'Escape' && onClose?.();
    window.addEventListener('keydown', onKey);
    return () => { document.body.style.overflow = prev; window.removeEventListener('keydown', onKey); };
  }, [open, onClose]);
  if (!render) return null;
  return (
    <Portal>
      <div
        onClick={closeOnBackdrop ? onClose : undefined}
        style={{
          position: 'fixed', inset: 0, zIndex,
          background: 'oklch(0.1 0.01 60 / 0.5)',
          backdropFilter: 'blur(6px)', WebkitBackdropFilter: 'blur(6px)',
          display: 'flex', alignItems: 'center', justifyContent: 'center',
          padding: 20,
          opacity: open ? 1 : 0,
          transition: `opacity ${MOTION.dur.base}ms ${MOTION.ease.out}`,
        }}>
        <div
          onClick={e => e.stopPropagation()}
          style={{
            background: 'var(--bg-raised)',
            border: '1px solid var(--line)',
            borderRadius: 16,
            boxShadow: 'var(--shadow-lg)',
            width: '100%', maxWidth: widths[size],
            maxHeight: 'calc(100vh - 80px)', overflow: 'hidden',
            display: 'flex', flexDirection: 'column',
            transform: open ? 'scale(1) translateY(0)' : 'scale(0.96) translateY(8px)',
            opacity: open ? 1 : 0,
            transition: `transform ${MOTION.dur.base}ms ${MOTION.ease.out}, opacity ${MOTION.dur.base}ms ${MOTION.ease.out}`,
          }}>
          {(title || desc) && (
            <div style={{ padding: '20px 24px 8px', position: 'relative' }}>
              {title && <h2 className="display" style={{ margin: 0, fontSize: 22, fontWeight: 500, letterSpacing: '-0.01em' }}>{title}</h2>}
              {desc && <p style={{ margin: '6px 0 0', fontSize: 13.5, color: 'var(--ink-3)', lineHeight: 1.5 }}>{desc}</p>}
              <button onClick={onClose} aria-label="Close" style={{
                position: 'absolute', top: 14, right: 14,
                width: 28, height: 28, border: 0, borderRadius: 7,
                background: 'transparent', color: 'var(--ink-3)',
                display: 'flex', alignItems: 'center', justifyContent: 'center', cursor: 'pointer',
              }}><Icon name="x" size={16}/></button>
            </div>
          )}
          <div style={{ padding: '12px 24px 20px', overflow: 'auto', flex: 1 }}>{children}</div>
          {footer && <div style={{
            padding: '14px 24px', borderTop: '1px solid var(--line)',
            background: 'var(--bg-sunken)',
            display: 'flex', gap: 8, justifyContent: 'flex-end',
          }}>{footer}</div>}
        </div>
      </div>
    </Portal>
  );
};

// --- DRAWER (side panel) ---
const Drawer = ({ open, onClose, title, desc, children, side = 'right', width = 460, footer }) => {
  const render = useDelayUnmount(open, MOTION.dur.slow);
  React.useEffect(() => {
    if (!open) return;
    const prev = document.body.style.overflow;
    document.body.style.overflow = 'hidden';
    const onKey = e => e.key === 'Escape' && onClose?.();
    window.addEventListener('keydown', onKey);
    return () => { document.body.style.overflow = prev; window.removeEventListener('keydown', onKey); };
  }, [open, onClose]);
  if (!render) return null;
  const translate = side === 'right' ? `translateX(${open ? 0 : 100}%)` : `translateX(${open ? 0 : -100}%)`;
  return (
    <Portal>
      <div onClick={onClose} style={{
        position: 'fixed', inset: 0, zIndex: 1000,
        background: 'oklch(0.1 0.01 60 / 0.4)',
        opacity: open ? 1 : 0,
        transition: `opacity ${MOTION.dur.slow}ms ${MOTION.ease.out}`,
      }}/>
      <div
        onClick={e => e.stopPropagation()}
        style={{
          position: 'fixed', top: 0, bottom: 0,
          [side]: 0,
          width, maxWidth: '95vw',
          background: 'var(--bg-raised)',
          borderLeft: side === 'right' ? '1px solid var(--line)' : 'none',
          borderRight: side === 'left' ? '1px solid var(--line)' : 'none',
          boxShadow: side === 'right' ? '-20px 0 60px oklch(0 0 0 / 0.15)' : '20px 0 60px oklch(0 0 0 / 0.15)',
          zIndex: 1001,
          transform: translate,
          transition: `transform ${MOTION.dur.slow}ms ${MOTION.ease.out}`,
          display: 'flex', flexDirection: 'column',
        }}>
        {(title || desc) && (
          <div style={{ padding: '20px 24px 16px', borderBottom: '1px solid var(--line)', position: 'relative' }}>
            {title && <h2 className="display" style={{ margin: 0, fontSize: 20, fontWeight: 500, letterSpacing: '-0.01em' }}>{title}</h2>}
            {desc && <p style={{ margin: '4px 0 0', fontSize: 13, color: 'var(--ink-3)' }}>{desc}</p>}
            <button onClick={onClose} aria-label="Close" style={{
              position: 'absolute', top: 14, right: 14,
              width: 30, height: 30, border: 0, borderRadius: 7,
              background: 'var(--bg-muted)', color: 'var(--ink-2)',
              display: 'flex', alignItems: 'center', justifyContent: 'center', cursor: 'pointer',
            }}><Icon name="x" size={16}/></button>
          </div>
        )}
        <div style={{ flex: 1, overflow: 'auto', padding: '20px 24px' }}>{children}</div>
        {footer && <div style={{
          padding: '14px 24px', borderTop: '1px solid var(--line)',
          background: 'var(--bg-sunken)',
          display: 'flex', gap: 8, justifyContent: 'flex-end',
        }}>{footer}</div>}
      </div>
    </Portal>
  );
};

// --- POPOVER ---
const Popover = ({ open, anchor, onClose, children, placement = 'bottom-start', offset = 6, style = {} }) => {
  const render = useDelayUnmount(open, MOTION.dur.fast);
  const [pos, setPos] = React.useState({ top: 0, left: 0 });
  React.useEffect(() => {
    if (!open || !anchor?.current) return;
    const r = anchor.current.getBoundingClientRect();
    const top = placement.startsWith('bottom') ? r.bottom + offset : r.top - offset;
    let left = r.left;
    if (placement.endsWith('end')) left = r.right;
    else if (placement.endsWith('center')) left = r.left + r.width / 2;
    setPos({ top, left });
  }, [open, anchor, placement, offset]);
  React.useEffect(() => {
    if (!open) return;
    const onClick = e => {
      if (!anchor.current?.contains(e.target)) onClose?.();
    };
    setTimeout(() => document.addEventListener('mousedown', onClick), 0);
    return () => document.removeEventListener('mousedown', onClick);
  }, [open, anchor, onClose]);
  if (!render) return null;
  const align = placement.endsWith('end') ? 'translateX(-100%)' : placement.endsWith('center') ? 'translateX(-50%)' : '';
  return (
    <Portal>
      <div
        onMouseDown={e => e.stopPropagation()}
        style={{
          position: 'fixed', zIndex: 900,
          top: pos.top, left: pos.left,
          transform: `${align} ${open ? 'translateY(0)' : 'translateY(-4px)'}`,
          opacity: open ? 1 : 0,
          transformOrigin: placement.startsWith('bottom') ? 'top' : 'bottom',
          transition: `opacity ${MOTION.dur.fast}ms ${MOTION.ease.out}, transform ${MOTION.dur.fast}ms ${MOTION.ease.out}`,
          ...style,
        }}>
        <div style={{
          background: 'var(--bg-raised)',
          border: '1px solid var(--line-2)',
          borderRadius: 10,
          boxShadow: 'var(--shadow-lg)',
          overflow: 'hidden',
        }}>{children}</div>
      </div>
    </Portal>
  );
};

// --- DROPDOWN MENU ---
const DropdownMenu = ({ trigger, items, align = 'start' }) => {
  const anchor = React.useRef(null);
  const [open, setOpen] = React.useState(false);
  return (
    <>
      <div ref={anchor} onClick={() => setOpen(o => !o)} style={{ display: 'inline-block' }}>
        {trigger}
      </div>
      <Popover open={open} anchor={anchor} onClose={() => setOpen(false)} placement={`bottom-${align}`}>
        <div style={{ padding: 4, minWidth: 180 }}>
          {items.map((item, i) => item === '---' ? (
            <div key={i} style={{ height: 1, background: 'var(--line)', margin: '4px 0' }}/>
          ) : item.label ? (
            <button
              key={i}
              onClick={() => { item.onClick?.(); setOpen(false); }}
              disabled={item.disabled}
              style={{
                display: 'flex', alignItems: 'center', gap: 10, width: '100%',
                padding: '8px 10px', border: 0, background: 'transparent',
                color: item.danger ? 'var(--danger)' : 'var(--ink)',
                fontFamily: 'inherit', fontSize: 13, fontWeight: 500,
                borderRadius: 6, textAlign: 'left', cursor: 'pointer',
                opacity: item.disabled ? 0.4 : 1,
              }}
              onMouseEnter={e => !item.disabled && (e.currentTarget.style.background = 'var(--bg-muted)')}
              onMouseLeave={e => (e.currentTarget.style.background = 'transparent')}
            >
              {item.icon && <Icon name={item.icon} size={15} style={{ color: item.danger ? 'var(--danger)' : 'var(--ink-3)' }}/>}
              <span style={{ flex: 1 }}>{item.label}</span>
              {item.kbd && <Kbd>{item.kbd}</Kbd>}
            </button>
          ) : (
            <div key={i} style={{ padding: '6px 10px 2px', fontSize: 10.5, fontWeight: 600, color: 'var(--ink-4)', textTransform: 'uppercase', letterSpacing: '0.08em' }}>
              {item.section}
            </div>
          ))}
        </div>
      </Popover>
    </>
  );
};

// --- TOOLTIP ---
const Tooltip = ({ children, label, side = 'top', delay = 400 }) => {
  const [open, setOpen] = React.useState(false);
  const ref = React.useRef(null);
  const [pos, setPos] = React.useState({ top: 0, left: 0 });
  const timer = React.useRef();
  const show = () => {
    timer.current = setTimeout(() => {
      if (!ref.current) return;
      const r = ref.current.getBoundingClientRect();
      const map = {
        top:    { top: r.top - 8, left: r.left + r.width/2 },
        bottom: { top: r.bottom + 8, left: r.left + r.width/2 },
        left:   { top: r.top + r.height/2, left: r.left - 8 },
        right:  { top: r.top + r.height/2, left: r.right + 8 },
      };
      setPos(map[side]);
      setOpen(true);
    }, delay);
  };
  const hide = () => { clearTimeout(timer.current); setOpen(false); };
  const translate = {
    top: 'translate(-50%, -100%)', bottom: 'translate(-50%, 0)',
    left: 'translate(-100%, -50%)', right: 'translate(0, -50%)',
  }[side];
  const child = React.Children.only(children);
  const cloned = React.cloneElement(child, {
    ref,
    onMouseEnter: show, onMouseLeave: hide,
    onFocus: show, onBlur: hide,
  });
  return <>
    {cloned}
    {open && <Portal>
      <div style={{
        position: 'fixed', top: pos.top, left: pos.left,
        transform: translate,
        background: 'var(--ink)', color: 'var(--bg)',
        padding: '5px 9px', borderRadius: 6,
        fontSize: 11.5, fontWeight: 500,
        pointerEvents: 'none', zIndex: 1200,
        whiteSpace: 'nowrap',
        animation: `scaleIn 100ms ${MOTION.ease.out}`,
      }}>{label}</div>
    </Portal>}
  </>;
};

// --- TOAST STACK ---
const ToastContext = React.createContext(null);
const useToast = () => React.useContext(ToastContext);

const ToastProvider = ({ children }) => {
  const [toasts, setToasts] = React.useState([]);
  const push = React.useCallback((t) => {
    const id = Date.now() + Math.random();
    setToasts(tt => [...tt, { id, ...t }]);
    setTimeout(() => setToasts(tt => tt.filter(x => x.id !== id)), t.duration || 3500);
  }, []);
  return (
    <ToastContext.Provider value={push}>
      {children}
      <Portal>
        <div style={{
          position: 'fixed', bottom: 20, right: 20, zIndex: 2000,
          display: 'flex', flexDirection: 'column', gap: 8,
          pointerEvents: 'none',
        }}>
          {toasts.map(t => <ToastItem key={t.id} {...t}/>)}
        </div>
      </Portal>
    </ToastContext.Provider>
  );
};

const ToastItem = ({ title, desc, tone = 'neutral', icon }) => {
  const tones = {
    neutral: { bg: 'var(--ink)', color: 'var(--bg)', dot: 'var(--accent)' },
    success: { bg: 'var(--ink)', color: 'var(--bg)', dot: 'var(--success)' },
    danger:  { bg: 'var(--ink)', color: 'var(--bg)', dot: 'var(--danger)' },
  };
  const t = tones[tone];
  return (
    <div style={{
      background: t.bg, color: t.color,
      padding: '12px 16px', borderRadius: 12,
      boxShadow: 'var(--shadow-lg)',
      display: 'flex', alignItems: 'flex-start', gap: 12,
      minWidth: 280, maxWidth: 380,
      pointerEvents: 'auto',
      animation: `slideInRight ${MOTION.dur.slow}ms ${MOTION.ease.out}`,
    }}>
      {icon ? (
        <Icon name={icon} size={18} style={{ flexShrink: 0, marginTop: 1 }}/>
      ) : (
        <span style={{ width: 8, height: 8, borderRadius: 99, background: t.dot, marginTop: 6, flexShrink: 0 }}/>
      )}
      <div style={{ flex: 1 }}>
        <div style={{ fontSize: 13, fontWeight: 600 }}>{title}</div>
        {desc && <div style={{ fontSize: 12, opacity: 0.7, marginTop: 2 }}>{desc}</div>}
      </div>
    </div>
  );
};

// --- CONFIRM DIALOG ---
const ConfirmDialog = ({ open, onClose, onConfirm, title, desc, confirmLabel = 'Confirm', danger }) => (
  <Modal open={open} onClose={onClose} size="sm" title={title} desc={desc}
    footer={<>
      <Button variant="ghost" onClick={onClose}>Cancel</Button>
      <Button variant={danger ? 'primary' : 'accent'} onClick={() => { onConfirm?.(); onClose?.(); }}
        style={danger ? { background: 'var(--danger)', borderColor: 'var(--danger)' } : {}}>
        {confirmLabel}
      </Button>
    </>}
  />
);

Object.assign(window, { Portal, Modal, Drawer, Popover, DropdownMenu, Tooltip, ToastProvider, useToast, ConfirmDialog });
