// ============================================================
// Boletins de Serviço — primitivos de UI compartilhados (window.*)
// Estilizados a partir dos tokens do Design System (styles.css).
// ============================================================
const { useState, useRef, useEffect } = React

// ---- Ícone via fonte ckl-icon --------------------------------------------
function Ic({ name, size = 18, color = 'currentColor', style, onClick }) {
  return <i className={'icon-font-' + name} onClick={onClick}
    style={{ fontSize: size, color, lineHeight: 1, display: 'inline-flex', cursor: onClick ? 'pointer' : undefined, ...style }} />
}

// ---- Botão (espelha atoms/Button: uppercase, hover→900, active→200) ------
function Btn({ label, children, type = 'primary', size = 'large', icon, iconRight, onClick, disabled, block, style, upper = false }) {
  const [h, setH] = useState(false)
  const pad = size === 'large' ? '13px 24px' : size === 'small' ? '7px 14px' : '11px 18px'
  const font = size === 'small' ? 14 : 16
  const variants = {
    primary: { bg: h ? 'var(--color-primary-900)' : 'var(--color-primary)', fg: '#fff', bd: 'transparent' },
    outline: { bg: h ? 'var(--color-primary-30)' : '#fff', fg: 'var(--color-primary)', bd: 'var(--color-primary)' },
    ghost: { bg: h ? 'var(--color-primary-30)' : 'transparent', fg: 'var(--color-primary)', bd: 'transparent' },
    destructive: { bg: h ? 'var(--color-danger-dark)' : 'var(--color-danger)', fg: '#fff', bd: 'transparent' },
    neutral: { bg: h ? 'var(--color-neutral-light-500)' : '#fff', fg: 'var(--color-grayish)', bd: 'var(--color-neutral-200)' },
  }
  const v = variants[type] || variants.primary
  return (
    <button type="button" onClick={disabled ? undefined : onClick} disabled={disabled}
      onMouseEnter={() => setH(true)} onMouseLeave={() => setH(false)}
      style={{ display: 'inline-flex', alignItems: 'center', justifyContent: 'center', gap: 8, padding: pad, width: block ? '100%' : undefined,
        border: '1px solid ' + v.bd, borderRadius: 'var(--border-radius-default)', background: disabled ? 'var(--color-neutral-light-500)' : v.bg,
        color: disabled ? 'var(--color-grayish-light)' : v.fg, fontFamily: 'inherit', fontSize: font, fontWeight: 500,
        textTransform: upper ? 'uppercase' : 'none', letterSpacing: upper ? '0.4px' : 0, cursor: disabled ? 'not-allowed' : 'pointer',
        transition: 'all .15s ease', whiteSpace: 'nowrap', ...style }}>
      {icon && (icon === 'renew'
        ? <svg width={font + 2} height={font + 2} viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" style={{ display: 'block' }}>
            <path d="M20 12a8 8 0 1 1-2.4-5.7" /><path d="M20 3.6V7h-3.4" />
          </svg>
        : <Ic name={icon} size={font + 2} />)}{label || children}{iconRight && <Ic name={iconRight} size={font + 2} />}
    </button>
  )
}

// ---- Dropdown (botão + popover de itens) ---------------------------------
// items: [{ title, subTitle, icon, action, hasDivider }]
function Dropdown({ label, selected, items, type = 'neutral', size = 'large', iconRight = 'chevron-down', width, menuWidth = 240, loading, align = 'right', btnStyle }) {
  const [open, setOpen] = useState(false)
  const ref = useRef(null)
  useEffect(() => {
    const h = (e) => { if (ref.current && !ref.current.contains(e.target)) setOpen(false) }
    document.addEventListener('mousedown', h); return () => document.removeEventListener('mousedown', h)
  }, [])
  return (
    <div ref={ref} style={{ position: 'relative', width }}>
      <Btn type={type} size={size} label={loading ? 'Exportando…' : (selected || label)} iconRight={loading ? undefined : iconRight}
        upper={false} onClick={() => setOpen(o => !o)} disabled={loading} block={!!width} style={btnStyle} />
      {open && (
        <div style={{ position: 'absolute', top: 'calc(100% + 6px)', [align]: 0, zIndex: 120, minWidth: menuWidth, background: '#fff',
          borderRadius: 'var(--border-radius-default)', border: '1px solid var(--color-primary-200)', boxShadow: '0 12px 30px rgba(0,0,0,0.16)', overflow: 'hidden', padding: 6 }}>
          {items.map((it, i) => (
            <React.Fragment key={i}>
              {it.hasDivider && <div style={{ height: 1, background: 'var(--color-neutral-100)', margin: '4px 0' }} />}
              <div onClick={() => { it.action && it.action(); setOpen(false) }}
                onMouseEnter={e => e.currentTarget.style.background = 'var(--color-primary-30)'}
                onMouseLeave={e => e.currentTarget.style.background = 'transparent'}
                style={{ display: 'flex', alignItems: 'center', gap: 12, padding: '12px 14px', borderRadius: 6, cursor: 'pointer' }}>
                {it.icon && <Ic name={it.icon} size={19} color="var(--color-primary)" />}
                <span style={{ display: 'flex', flexDirection: 'column' }}>
                  {it.title && <span style={{ fontSize: 11, textTransform: 'uppercase', letterSpacing: '0.5px', color: 'var(--color-grayish-light)', fontWeight: 600 }}>{it.title}</span>}
                  <span style={{ fontSize: 15, color: 'var(--color-grayish-dark)', fontWeight: 600, whiteSpace: 'nowrap' }}>{it.subTitle || it.label}</span>
                </span>
              </div>
            </React.Fragment>
          ))}
        </div>
      )}
    </div>
  )
}

// ---- Sobreposição escura + painel --------------------------------------
function Overlay({ onClose, children, align = 'right' }) {
  return (
    <React.Fragment>
      <div onClick={onClose} style={{ position: 'absolute', inset: 0, background: 'rgba(21,21,21,0.42)', zIndex: 190, animation: 'fgFade .15s ease' }} />
      {align === 'right'
        ? <div style={{ position: 'absolute', top: 0, right: 0, bottom: 0, zIndex: 200, animation: 'fgSlide .24s ease' }}>{children}</div>
        : <div style={{ position: 'absolute', inset: 0, zIndex: 200, display: 'flex', alignItems: 'center', justifyContent: 'center', pointerEvents: 'none' }}>
            <div style={{ pointerEvents: 'auto', animation: 'fgPop .18s ease' }}>{children}</div></div>}
    </React.Fragment>
  )
}

// ---- Modal (espelha molecules/CustomModal) -------------------------------
function Modal({ header, text, children, onClose, primaryLabel, primaryAction, primaryType = 'primary', secondaryLabel, secondaryAction, width = 560 }) {
  return (
    <Overlay onClose={onClose} align="center">
      <div style={{ width, maxWidth: '92vw', maxHeight: '86vh', overflowY: 'auto', background: '#fff', borderRadius: 'var(--border-radius-large)', boxShadow: '0 24px 60px rgba(0,0,0,0.28)' }}>
        <div style={{ padding: '28px 32px 24px' }}>
          <div style={{ display: 'flex', alignItems: 'flex-start', justifyContent: 'space-between', gap: 16 }}>
            <h2 style={{ margin: 0, fontSize: 20, fontWeight: 600, color: 'var(--color-grayish-dark)' }}>{header}</h2>
            <Ic name="close" size={20} color="var(--color-grayish)" onClick={onClose} />
          </div>
          {text && <p style={{ margin: '12px 0 0', fontSize: 14, lineHeight: 1.5, color: 'var(--color-grayish)' }}>{text}</p>}
          {children}
        </div>
        {(primaryLabel || secondaryLabel) && (
          <div style={{ display: 'flex', justifyContent: 'space-between', gap: 12, padding: '16px 32px 28px' }}>
            {secondaryLabel ? <Btn type="ghost" label={secondaryLabel} onClick={secondaryAction || onClose} /> : <span />}
            {primaryLabel && <Btn type={primaryType} label={primaryLabel} onClick={primaryAction} />}
          </div>
        )}
      </div>
    </Overlay>
  )
}

// ---- Switch (Status Ativo) -----------------------------------------------
function Switch({ checked, onChange, label }) {
  return (
    <label style={{ display: 'inline-flex', alignItems: 'center', gap: 8, cursor: 'pointer' }} onClick={() => onChange && onChange(!checked)}>
      <span style={{ width: 38, height: 22, borderRadius: 100, background: checked ? 'var(--color-primary)' : 'var(--color-neutral-200)', position: 'relative', transition: 'background .15s' }}>
        <span style={{ position: 'absolute', top: 2, left: checked ? 18 : 2, width: 18, height: 18, borderRadius: '50%', background: '#fff', transition: 'left .15s', boxShadow: '0 1px 2px rgba(0,0,0,.25)' }} />
      </span>
      {label && <span style={{ fontSize: 14, color: 'var(--color-grayish)', fontWeight: 500 }}>{label}</span>}
    </label>
  )
}

// ---- Checkbox de filtro (espelha CheckboxButton — quadrado + rótulo) -----
function CheckboxBtn({ label, checked, onChange }) {
  return (
    <label onClick={() => onChange(!checked)} style={{ display: 'inline-flex', alignItems: 'center', gap: 8, cursor: 'pointer',
      fontSize: 14, fontWeight: 500, color: checked ? 'var(--color-grayish-dark)' : 'var(--color-grayish)', whiteSpace: 'nowrap', userSelect: 'none' }}>
      <Ic name={checked ? 'checkbox-checked' : 'checkbox-unchecked'} size={20} color={checked ? 'var(--color-primary)' : 'var(--color-neutral-300)'} />{label}
    </label>
  )
}

// ---- Campo de busca (rounded, ícone limpar à esquerda) -------------------
function SearchInput({ value, onChange, width = 440, height = 48, placeholder = 'Buscar' }) {
  const ph = placeholder
  return (
    <div style={{ position: 'relative', width }}>
      <span onClick={() => value && onChange('')} style={{ position: 'absolute', left: 12, top: '50%', transform: 'translateY(-50%)', opacity: value ? 0.55 : 0.28, cursor: value ? 'pointer' : 'default' }}>
        <Ic name={value ? 'close-circle-outline' : 'search'} size={18} /></span>
      <input value={value} onChange={e => onChange(e.target.value)} placeholder={ph}
        style={{ ...inputStyle, height, width: '100%', paddingLeft: 40, borderRadius: 'var(--border-radius-default)' }} />
    </div>
  )
}

// ---- Selo "Pendente" (destaque vermelho como no card real) ---------------
function Pendente() {
  return (
    <span style={{ display: 'inline-flex', alignItems: 'center', gap: 4, color: 'var(--color-danger-dark)' }}>
      <span style={{ fontSize: 15, fontWeight: 600, color: 'var(--color-danger-dark)' }}>Pendente</span>
      <Ic name="warning-outline" size={17} color="var(--color-danger-dark)" />
    </span>
  )
}

// ---- Caption (rótulo de campo, cinza) ------------------------------------
function Cap({ children, style }) {
  return <span style={{ display: 'block', fontSize: 12, color: 'var(--color-neutral-500)', marginBottom: 4, ...style }}>{children}</span>
}

// ---- Input básico ---------------------------------------------------------
function Field({ label, children }) {
  return <label style={{ display: 'flex', flexDirection: 'column', gap: 6 }}>
    {label && <span style={{ fontSize: 13, fontWeight: 500, color: 'var(--color-grayish-dark)' }}>{label}</span>}{children}</label>
}
const inputStyle = { height: 48, padding: '0 12px', border: '1px solid var(--color-neutral-200)', borderRadius: 'var(--border-radius-input)',
  fontFamily: 'inherit', fontSize: 14, color: 'var(--color-grayish-dark)', background: '#fff', outline: 'none', boxSizing: 'border-box', width: '100%' }
function Input(props) { return <input {...props} style={{ ...inputStyle, ...(props.style || {}) }} /> }
function Select({ options = [], value, onChange, placeholder }) {
  return (
    <span style={{ position: 'relative', display: 'block' }}>
      <select value={value} onChange={onChange} style={{ ...inputStyle, appearance: 'none', paddingRight: 38, cursor: 'pointer', color: value ? 'var(--color-grayish-dark)' : 'var(--color-grayish-light)' }}>
        {placeholder && <option value="">{placeholder}</option>}
        {options.map(o => <option key={o} value={o}>{o}</option>)}
      </select>
      <span style={{ position: 'absolute', right: 12, top: '50%', transform: 'translateY(-50%)', pointerEvents: 'none', display: 'flex', color: 'var(--color-grayish-light)' }}>
        <Ic name="chevron-down" size={16} />
      </span>
    </span>
  )
}

// ---- Formatação -----------------------------------------------------------
function fmtDuration(min) { if (min == null) return ''; const h = Math.floor(min / 60), m = min % 60; return String(h).padStart(2, '0') + 'h ' + String(m).padStart(2, '0') + 'min' }
function fmtDate(iso, withTime) {
  const d = new Date(iso); const p = n => String(n).padStart(2, '0')
  const base = `${p(d.getDate())}/${p(d.getMonth() + 1)}/${String(d.getFullYear()).slice(2)}`
  return withTime ? `${base} ${p(d.getHours())}:${p(d.getMinutes())}` : base
}

// ---- Estilos de tabela (Revisão / Parâmetros) ----------------------------
const cellTH = { textAlign: 'left', padding: '18px 14px', fontSize: 14, fontWeight: 500, color: 'var(--color-grayish-dark)',
  background: '#fff', borderBottom: '1px solid var(--color-neutral-100)', whiteSpace: 'nowrap' }
const cellTD = { padding: '15px 14px', fontSize: 14, fontWeight: 500, color: 'var(--color-grayish)', borderBottom: '1px solid var(--color-neutral-100)', whiteSpace: 'nowrap' }

Object.assign(window, { Ic, Btn, Dropdown, Overlay, Modal, Switch, CheckboxBtn, SearchInput, Pendente, Cap, Field, Input, Select, inputStyle, fmtDuration, fmtDate, cellTH, cellTD })
