/* admin_users_components.jsx — sub-componentes reutilizáveis para Admin · Users.
   Sem state global. Cada componente é puro/controlled.

   Expostos em window:
     AdminUsers.Avatar
     AdminUsers.EmpresaTags          — tag única ou "N empresas (FBS, DDI...)" com tooltip
     AdminUsers.RelativeTime         — "há 4h" + tooltip absoluto
     AdminUsers.TipoBadge            — pill colorido por tipo
     AdminUsers.PortalBadge          — Activo verde / Sem acesso cinza
     AdminUsers.SSOBadge             — ✓ se portal_activo + tooltip
     AdminUsers.ApolloBadge          — chip
     AdminUsers.SectionHeader
     AdminUsers.FieldRow             — label esq · valor dir · edit inline opcional
     AdminUsers.EmpresaJunctionTable — tabela editável colaborador_empresa
     AdminUsers.PermissoesEditor     — editor RBAC (collapsed por default)
     AdminUsers.ModosAcessoEditor    — checkboxes dev/interno/clientes/board
     AdminUsers.PortalAccessCard
     AdminUsers.AuditLogList
     AdminUsers.SessionsList
     AdminUsers.ConversasList
*/

const D = window.AdminUsersData;

// ════════════════════════════════════════════════════════════════
// Helpers
// ════════════════════════════════════════════════════════════════
const fmtAbs = (iso) => {
  if (!iso) return '—';
  const d = new Date(iso);
  return d.toLocaleString('pt-PT', { day: '2-digit', month: '2-digit', year: 'numeric', hour: '2-digit', minute: '2-digit' });
};
const fmtRel = (iso) => {
  if (!iso) return '—';
  const diff = Date.now() - new Date(iso).getTime();
  const m = Math.floor(diff / 60_000);
  if (m < 1)   return 'agora';
  if (m < 60)  return `há ${m}m`;
  const h = Math.floor(m / 60);
  if (h < 24)  return `há ${h}h`;
  const d = Math.floor(h / 24);
  if (d < 30)  return `há ${d}d`;
  const mo = Math.floor(d / 30);
  if (mo < 12) return `há ${mo}m`;
  const y = Math.floor(d / 365);
  return `há ${y}a`;
};
const initials = (nome) => {
  if (!nome) return '··';
  return nome.split(' ').filter(Boolean).slice(0, 2).map(s => s[0]?.toUpperCase()).join('') || '··';
};

// ════════════════════════════════════════════════════════════════
// Avatar — colored bubble com iniciais. Se foto_url existir, mock photo (gradient).
// ════════════════════════════════════════════════════════════════
const Avatar = ({ user, size = 32 }) => {
  const has = !!user?.foto_url;
  const ini = initials(user?.nome_apresentar || user?.nome_completo);
  // Hash-based hue para diversificar
  const hash = [...(user?.nome_completo || 'X')].reduce((a, c) => a + c.charCodeAt(0), 0);
  const hue = hash % 360;
  const bg = has
    ? `linear-gradient(135deg, oklch(0.65 0.13 ${hue}), oklch(0.45 0.16 ${(hue + 40) % 360}))`
    : `oklch(0.30 0.04 ${hue})`;
  return (
    <div style={{
      width: size, height: size, borderRadius: size <= 28 ? 6 : 8,
      background: bg,
      display: 'grid', placeItems: 'center', flexShrink: 0,
      color: has ? '#fff' : 'var(--text)',
      fontSize: size * 0.40, fontWeight: 600, letterSpacing: '0.02em',
      fontFamily: 'var(--font-display)',
      textTransform: 'uppercase',
      border: has ? '0' : '1px solid var(--border)',
    }}>{ini}</div>
  );
};

// ════════════════════════════════════════════════════════════════
// Tooltip simples (top-right) on-hover
// ════════════════════════════════════════════════════════════════
const Tooltip = ({ children, text, side = 'top' }) => {
  const [hover, setHover] = React.useState(false);
  return (
    <span
      onMouseEnter={() => setHover(true)}
      onMouseLeave={() => setHover(false)}
      style={{ position: 'relative', display: 'inline-flex' }}
    >
      {children}
      {hover && text && (
        <span style={{
          position: 'absolute',
          [side === 'top' ? 'bottom' : 'top']: 'calc(100% + 6px)',
          left: '50%', transform: 'translateX(-50%)',
          background: 'var(--bg-elev)',
          border: '1px solid var(--border)',
          borderRadius: 6, padding: '6px 10px',
          fontSize: 11, whiteSpace: 'pre-line', maxWidth: 280,
          boxShadow: 'var(--shadow-md)', color: 'var(--text)',
          zIndex: 1500, pointerEvents: 'none', fontFamily: 'var(--font-sans)',
        }}>{text}</span>
      )}
    </span>
  );
};

// ════════════════════════════════════════════════════════════════
// EmpresaTags — uma empresa = nome curto; várias = "3 empresas" + tooltip
// ════════════════════════════════════════════════════════════════
const EmpresaTags = ({ user, mode = 'compact' }) => {
  const list = user?.empresas || [];
  if (!list.length) return <span style={{ color: 'var(--text-dim)' }}>—</span>;
  if (list.length === 1) {
    const e = D.getEmpresa(list[0].id);
    return (
      <span style={{ fontSize: 12, color: 'var(--text)' }}>{e?.nome || list[0].id}</span>
    );
  }
  const primary = list.find(x => x.is_primary) || list[0];
  const otherShorts = list.filter(x => x.id !== primary.id).slice(0, 3).map(x => D.getEmpresa(x.id)?.short || x.id);
  const more = list.length - 1 - otherShorts.length;
  const summaryText = list.map(x => {
    const e = D.getEmpresa(x.id);
    return `${x.is_primary ? '● ' : '  '}${e?.nome || x.id} — ${x.cargo || ''}`;
  }).join('\n');
  return (
    <Tooltip text={summaryText}>
      <span style={{
        display: 'inline-flex', alignItems: 'center', gap: 6,
        fontSize: 12, color: 'var(--text)',
        cursor: 'help', borderBottom: '1px dashed var(--border)',
      }}>
        <strong style={{ fontWeight: 600 }}>{list.length}</strong>
        <span style={{ color: 'var(--text-muted)' }}>empresas ·</span>
        <span style={{ fontFamily: 'var(--font-mono)', fontSize: 10.5, color: 'var(--text-muted)' }}>
          {[D.getEmpresa(primary.id)?.short, ...otherShorts].filter(Boolean).join(', ')}{more > 0 ? `, +${more}` : ''}
        </span>
      </span>
    </Tooltip>
  );
};

// ════════════════════════════════════════════════════════════════
// RelativeTime
// ════════════════════════════════════════════════════════════════
const RelativeTime = ({ iso }) => {
  if (!iso) return <span style={{ color: 'var(--text-dim)' }}>—</span>;
  return (
    <Tooltip text={fmtAbs(iso)}>
      <span style={{ fontSize: 12, color: 'var(--text)', cursor: 'help' }}>{fmtRel(iso)}</span>
    </Tooltip>
  );
};

// ════════════════════════════════════════════════════════════════
// Badges
// ════════════════════════════════════════════════════════════════
const TipoBadge = ({ tipo }) => {
  const t = D.getTipo(tipo);
  if (!t) return <span style={{ color: 'var(--text-dim)' }}>—</span>;
  return (
    <span style={{
      display: 'inline-flex', alignItems: 'center', padding: '2px 8px',
      borderRadius: 999, fontSize: 10.5, fontWeight: 600,
      letterSpacing: '0.04em', textTransform: 'uppercase',
      background: `color-mix(in oklch, ${t.color} 18%, transparent)`,
      border: `1px solid color-mix(in oklch, ${t.color} 35%, transparent)`,
      color: t.color, fontFamily: 'var(--font-display)',
    }}>{t.label}</span>
  );
};

const PortalBadge = ({ activo }) => activo ? (
  <span style={{
    display: 'inline-flex', alignItems: 'center', gap: 4,
    padding: '2px 8px', borderRadius: 999, fontSize: 10.5,
    background: 'color-mix(in oklch, var(--ok) 16%, transparent)',
    border: '1px solid color-mix(in oklch, var(--ok) 35%, transparent)',
    color: 'var(--ok)', fontFamily: 'var(--font-mono)',
  }}>● Activo</span>
) : (
  <span style={{
    display: 'inline-flex', alignItems: 'center', gap: 4,
    padding: '2px 8px', borderRadius: 999, fontSize: 10.5,
    background: 'var(--bg-sunken)', border: '1px solid var(--border)',
    color: 'var(--text-dim)', fontFamily: 'var(--font-mono)',
  }}>○ Sem acesso</span>
);

const SSOBadge = ({ activo }) => (
  <Tooltip text={'Sincronizado com Microsoft 365 SSO.\n2FA gerido pelo Microsoft Authenticator.'}>
    <span style={{
      display: 'inline-flex', alignItems: 'center', justifyContent: 'center',
      width: 18, height: 18, borderRadius: 4,
      fontSize: 11, fontFamily: 'var(--font-mono)',
      cursor: 'help',
      background: activo ? 'color-mix(in oklch, var(--ok) 16%, transparent)' : 'var(--bg-sunken)',
      border: `1px solid ${activo ? 'color-mix(in oklch, var(--ok) 35%, transparent)' : 'var(--border)'}`,
      color: activo ? 'var(--ok)' : 'var(--text-dim)',
    }}>{activo ? '✓' : '✗'}</span>
  </Tooltip>
);

const ApolloBadge = ({ enriched }) => enriched ? (
  <Tooltip text="Enriquecido via Apollo.io">
    <span style={{
      display: 'inline-flex', alignItems: 'center', gap: 4,
      padding: '1px 6px', borderRadius: 4, fontSize: 9.5,
      background: 'color-mix(in oklch, var(--ai-500) 14%, transparent)',
      color: 'var(--ai-500)', fontFamily: 'var(--font-mono)',
      letterSpacing: '0.04em',
    }}>APOLLO ✓</span>
  </Tooltip>
) : (
  <span style={{
    display: 'inline-flex', alignItems: 'center', padding: '1px 6px',
    borderRadius: 4, fontSize: 9.5, background: 'var(--bg-sunken)',
    color: 'var(--text-dim)', fontFamily: 'var(--font-mono)',
  }}>— pendente</span>
);

// ════════════════════════════════════════════════════════════════
// SectionHeader (drawer)
// ════════════════════════════════════════════════════════════════
const SectionHeader = ({ title, subtitle, action }) => (
  <div style={{
    display: 'flex', alignItems: 'flex-end', justifyContent: 'space-between',
    marginBottom: 12, paddingBottom: 8, borderBottom: '1px solid var(--border)',
  }}>
    <div>
      <div className="font-display" style={{
        fontSize: 11, fontWeight: 600, letterSpacing: '0.12em',
        textTransform: 'uppercase', color: 'var(--text-muted)',
      }}>{title}</div>
      {subtitle && <div style={{ fontSize: 11, color: 'var(--text-dim)', marginTop: 2 }}>{subtitle}</div>}
    </div>
    {action}
  </div>
);

// ════════════════════════════════════════════════════════════════
// FieldRow — label esq · value dir · edit inline (lápis on hover)
// ════════════════════════════════════════════════════════════════
const FieldRow = ({ label, value, onChange, editable = true, type = 'text', source, options, multiline, badge }) => {
  const [editing, setEditing] = React.useState(false);
  const [draft, setDraft]     = React.useState(value || '');
  const [hover, setHover]     = React.useState(false);
  React.useEffect(() => setDraft(value || ''), [value]);

  const commit = () => {
    setEditing(false);
    if (draft !== (value || '') && onChange) onChange(draft);
  };
  const cancel = () => { setDraft(value || ''); setEditing(false); };

  return (
    <div
      onMouseEnter={() => setHover(true)}
      onMouseLeave={() => setHover(false)}
      style={{
        display: 'grid', gridTemplateColumns: '180px 1fr', gap: 16,
        padding: '10px 0', borderBottom: '1px dashed var(--border-subtle, var(--border))',
        alignItems: multiline ? 'flex-start' : 'center',
      }}
    >
      <div style={{
        fontSize: 11, color: 'var(--text-muted)',
        fontFamily: 'var(--font-display)', letterSpacing: '0.04em',
        textTransform: 'uppercase', fontWeight: 500,
        display: 'flex', alignItems: 'center', gap: 6,
      }}>
        <span>{label}</span>
        {source && <span style={{
          padding: '0 6px', fontSize: 8.5, borderRadius: 3,
          background: 'var(--bg-sunken)', color: 'var(--text-dim)',
          fontFamily: 'var(--font-mono)', letterSpacing: '0.06em',
        }}>{source}</span>}
      </div>

      {editing ? (
        <div style={{ display: 'flex', gap: 6 }}>
          {type === 'select' ? (
            <select
              autoFocus value={draft}
              onChange={e => setDraft(e.target.value)}
              onBlur={commit}
              onKeyDown={e => { if (e.key === 'Enter') commit(); if (e.key === 'Escape') cancel(); }}
              style={inputStyle(false)}
            >
              {(options || []).map(o => typeof o === 'string'
                ? <option key={o} value={o}>{o}</option>
                : <option key={o.id} value={o.id}>{o.label}</option>)}
            </select>
          ) : multiline ? (
            <textarea
              autoFocus value={draft} rows={4}
              onChange={e => setDraft(e.target.value)}
              onBlur={commit}
              onKeyDown={e => { if (e.key === 'Escape') cancel(); }}
              style={{ ...inputStyle(true), resize: 'vertical', fontFamily: 'var(--font-sans)' }}
            />
          ) : (
            <input
              autoFocus type={type} value={draft}
              onChange={e => setDraft(e.target.value)}
              onBlur={commit}
              onKeyDown={e => { if (e.key === 'Enter') commit(); if (e.key === 'Escape') cancel(); }}
              style={inputStyle(false)}
            />
          )}
        </div>
      ) : (
        <div
          onClick={() => editable && onChange && setEditing(true)}
          style={{
            fontSize: 13, color: value ? 'var(--text)' : 'var(--text-dim)',
            cursor: editable && onChange ? 'text' : 'default',
            display: 'flex', alignItems: multiline ? 'flex-start' : 'center', gap: 8,
            minHeight: 22, whiteSpace: multiline ? 'pre-wrap' : 'normal',
            lineHeight: multiline ? 1.5 : 1.3,
          }}
        >
          <span style={{ flex: 1 }}>{value || <em style={{ color: 'var(--text-dim)', fontStyle: 'normal' }}>—</em>}</span>
          {badge}
          {editable && onChange && hover && (
            <Icon name="more" size={12} style={{ color: 'var(--text-dim)', opacity: 0.6 }} />
          )}
        </div>
      )}
    </div>
  );
};
const inputStyle = (multi) => ({
  flex: 1, padding: multi ? '6px 8px' : '4px 8px',
  background: 'var(--bg-elev)', border: '1px solid var(--ai-500)',
  borderRadius: 4, fontSize: 13, color: 'var(--text)',
  outline: 'none', fontFamily: 'var(--font-sans)',
});

// ════════════════════════════════════════════════════════════════
// EmpresaJunctionTable — tabela editável colaborador_empresa
// ════════════════════════════════════════════════════════════════
const EmpresaJunctionTable = ({ user, onChange, currentUserTipo }) => {
  const list = user?.empresas || [];
  const visible = D.visibleEmpresas(currentUserTipo);
  const setPrimary = (idx) => onChange(list.map((x, i) => ({ ...x, is_primary: i === idx })));
  const update = (idx, patch) => onChange(list.map((x, i) => i === idx ? { ...x, ...patch } : x));
  const remove = (idx) => onChange(list.filter((_, i) => i !== idx));
  const add = () => {
    const taken = new Set(list.map(x => x.id));
    const free = visible.find(e => !taken.has(e.id));
    if (!free) return;
    onChange([...list, { id: free.id, cargo: '', direccao: '', departamento: '', is_primary: list.length === 0 }]);
  };

  return (
    <div style={{ marginTop: 4 }}>
      <div style={{
        display: 'grid',
        gridTemplateColumns: '180px 1fr 1fr 60px 30px',
        gap: 8, padding: '6px 8px',
        fontSize: 10, color: 'var(--text-muted)',
        fontFamily: 'var(--font-display)', letterSpacing: '0.08em',
        textTransform: 'uppercase', fontWeight: 600,
        borderBottom: '1px solid var(--border)',
      }}>
        <div>Empresa</div>
        <div>Cargo</div>
        <div>Direcção · Depto</div>
        <div style={{ textAlign: 'center' }}>Primária</div>
        <div></div>
      </div>
      {list.map((row, idx) => {
        const e = D.getEmpresa(row.id);
        return (
          <div key={idx} style={{
            display: 'grid',
            gridTemplateColumns: '180px 1fr 1fr 60px 30px',
            gap: 8, padding: '8px',
            borderBottom: '1px solid var(--border)',
            alignItems: 'center', fontSize: 12,
          }}>
            <select
              value={row.id}
              onChange={ev => update(idx, { id: ev.target.value })}
              style={cellInput()}
            >
              {visible.map(emp => <option key={emp.id} value={emp.id}>{emp.nome}</option>)}
            </select>
            <input
              type="text" value={row.cargo || ''}
              placeholder="Cargo"
              onChange={ev => update(idx, { cargo: ev.target.value })}
              style={cellInput()}
            />
            <input
              type="text"
              value={[row.direccao, row.departamento].filter(Boolean).join(' · ') || ''}
              placeholder="Direcção · Depto"
              onChange={ev => {
                const parts = ev.target.value.split('·').map(s => s.trim());
                update(idx, { direccao: parts[0] || '', departamento: parts[1] || '' });
              }}
              style={cellInput()}
            />
            <div style={{ display: 'flex', justifyContent: 'center' }}>
              <button
                onClick={() => setPrimary(idx)}
                title={row.is_primary ? 'Empresa primária' : 'Definir como primária'}
                style={{
                  width: 18, height: 18, borderRadius: '50%',
                  border: `2px solid ${row.is_primary ? 'var(--ai-500)' : 'var(--border)'}`,
                  background: row.is_primary ? 'var(--ai-500)' : 'transparent',
                  cursor: 'pointer', padding: 0,
                  display: 'grid', placeItems: 'center',
                }}
              >
                {row.is_primary && <span style={{ width: 6, height: 6, borderRadius: '50%', background: '#fff' }} />}
              </button>
            </div>
            <button
              onClick={() => remove(idx)}
              title="Remover empresa"
              className="btn btn-ghost btn-sm"
              style={{ padding: 4, justifyContent: 'center' }}
            ><Icon name="close" size={12} /></button>
          </div>
        );
      })}
      <div style={{ display: 'flex', alignItems: 'center', gap: 12, padding: '10px 8px' }}>
        <button onClick={add} className="btn btn-sm">
          <Icon name="plus" size={12} />
          Adicionar empresa
        </button>
        <Tooltip text="A empresa primária é a que aparece no header do utilizador. As outras são acessos adicionais." side="top">
          <span style={{ fontSize: 10.5, color: 'var(--text-dim)', display: 'inline-flex', alignItems: 'center', gap: 4 }}>
            <Icon name="circle" size={10} style={{ opacity: 0.4 }} />
            sobre primária
          </span>
        </Tooltip>
      </div>
    </div>
  );
};
const cellInput = () => ({
  padding: '5px 7px', background: 'var(--bg-sunken)',
  border: '1px solid transparent', borderRadius: 4,
  fontSize: 12, color: 'var(--text)', outline: 'none',
  fontFamily: 'var(--font-sans)', width: '100%',
});

// ════════════════════════════════════════════════════════════════
// PermissoesEditor — collapsed por default, com badge "Override"
// ════════════════════════════════════════════════════════════════
const PermissoesEditor = ({ user, onChange, expanded, setExpanded }) => {
  const def = D.TIPOS_DEFAULTS[user.tipo_utilizador] || { dados: [], marcas: [], skills: [], features: [], modos: [] };
  const cur = user.permissoes || def;
  const isOverride = JSON.stringify({...cur, modos:undefined}) !== JSON.stringify({...def, modos: undefined});

  const toggle = (group, key) => {
    const set = new Set(cur[group] || []);
    if (set.has(key)) set.delete(key); else set.add(key);
    onChange({ ...cur, [group]: [...set] });
  };
  const revert = () => onChange({ ...def });

  // Resumos
  const counts = {
    dados:    `${(cur.dados || []).length}/${D.DADOS_KEYS.length}`,
    marcas:   `${(cur.marcas || []).length}/${D.MARCAS_KEYS.length}`,
    skills:   `${(cur.skills || []).length}/${D.SKILLS_KEYS.length}`,
    features: `${(cur.features || []).length}/${D.FEATURES_KEYS.length}`,
  };

  return (
    <div style={{
      border: '1px solid var(--border)', borderRadius: 8,
      background: 'var(--bg-sunken)', overflow: 'hidden',
    }}>
      <div style={{ padding: '12px 14px' }}>
        <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', marginBottom: 8 }}>
          <div className="font-display" style={{ fontSize: 11, fontWeight: 600, letterSpacing: '0.10em', textTransform: 'uppercase', color: 'var(--text-muted)' }}>
            Resumo permissões
          </div>
          {isOverride && (
            <span style={{
              padding: '2px 8px', borderRadius: 999, fontSize: 9.5,
              background: 'color-mix(in oklch, var(--warn) 18%, transparent)',
              border: '1px solid color-mix(in oklch, var(--warn) 35%, transparent)',
              color: 'var(--warn)',
              fontFamily: 'var(--font-mono)', letterSpacing: '0.06em',
            }}>OVERRIDE PONTUAL</span>
          )}
        </div>

        <div style={{ display: 'grid', gridTemplateColumns: 'repeat(2, 1fr)', gap: '6px 18px', fontSize: 12 }}>
          <SummaryRow label="Dados"    count={counts.dados} />
          <SummaryRow label="Marcas"   count={counts.marcas} />
          <SummaryRow label="Skills"   count={counts.skills} />
          <SummaryRow label="Features" count={counts.features} />
        </div>

        <div style={{ display: 'flex', gap: 8, marginTop: 12 }}>
          <button
            onClick={() => setExpanded(!expanded)}
            className="btn btn-sm"
            style={{ flex: 1 }}
          >
            <Icon name={expanded ? 'arrowUp' : 'arrowDown'} size={12} />
            {expanded ? 'Esconder editor' : 'Personalizar permissões'}
          </button>
          {isOverride && (
            <button onClick={revert} className="btn btn-sm btn-ghost">
              <Icon name="refresh" size={12} />
              Reverter para defaults
            </button>
          )}
        </div>
      </div>

      {expanded && (
        <div style={{ padding: '14px', borderTop: '1px solid var(--border)' }}>
          <PermGroup title="Dados"    keys={D.DADOS_KEYS}    selected={cur.dados}    onToggle={(k) => toggle('dados', k)}    cols={2} />
          <PermGroup title="Marcas"   keys={D.MARCAS_KEYS}   selected={cur.marcas}   onToggle={(k) => toggle('marcas', k)}   cols={3} />
          <PermGroup title="Skills"   keys={D.SKILLS_KEYS}   selected={cur.skills}   onToggle={(k) => toggle('skills', k)}   cols={3} />
          <PermGroup title="Features" keys={D.FEATURES_KEYS} selected={cur.features} onToggle={(k) => toggle('features', k)} cols={3} last />
        </div>
      )}
    </div>
  );
};
const SummaryRow = ({ label, count }) => (
  <div style={{ display: 'flex', justifyContent: 'space-between', gap: 8 }}>
    <span style={{ color: 'var(--text-muted)' }}>{label}:</span>
    <span style={{ fontFamily: 'var(--font-mono)', color: 'var(--text)' }}>{count}</span>
  </div>
);
const PermGroup = ({ title, keys, selected, onToggle, cols = 3, last }) => {
  const sel = new Set(selected || []);
  return (
    <div style={{ marginBottom: last ? 0 : 14 }}>
      <div className="font-display" style={{
        fontSize: 10, fontWeight: 600, letterSpacing: '0.12em',
        textTransform: 'uppercase', color: 'var(--text-dim)', marginBottom: 6,
      }}>{title}</div>
      <div style={{ display: 'grid', gridTemplateColumns: `repeat(${cols}, 1fr)`, gap: '4px 10px' }}>
        {keys.map(k => (
          <label key={k} style={{
            display: 'flex', alignItems: 'center', gap: 6,
            fontSize: 11.5, fontFamily: 'var(--font-mono)',
            cursor: 'pointer', padding: '3px 0',
          }}>
            <input
              type="checkbox" checked={sel.has(k)}
              onChange={() => onToggle(k)}
              style={{ accentColor: 'var(--ai-500)' }}
            />
            <span style={{ color: sel.has(k) ? 'var(--text)' : 'var(--text-dim)' }}>{k}</span>
          </label>
        ))}
      </div>
    </div>
  );
};

// ════════════════════════════════════════════════════════════════
// ModosAcessoEditor
// ════════════════════════════════════════════════════════════════
const ModosAcessoEditor = ({ value, onChange }) => {
  const sel = new Set(value || []);
  const toggle = (k) => {
    const next = new Set(sel);
    if (next.has(k)) next.delete(k); else next.add(k);
    onChange([...next]);
  };
  const items = [
    { id: 'dev',      label: 'Dev',      desc: 'developers e admins' },
    { id: 'interno',  label: 'Interno',  desc: 'colaboradores · CRM · KPIs · módulos' },
    { id: 'clientes', label: 'Clientes', desc: 'modo público — sem dados internos' },
    { id: 'board',    label: 'Board',    desc: 'executivos — KPIs estratégicos · Pipeline 3' },
  ];
  return (
    <div style={{ display: 'flex', flexDirection: 'column', gap: 6 }}>
      {items.map(it => (
        <label key={it.id} style={{
          display: 'flex', alignItems: 'center', gap: 10,
          padding: '8px 10px', borderRadius: 6,
          background: sel.has(it.id) ? 'color-mix(in oklch, var(--ai-500) 8%, transparent)' : 'var(--bg-sunken)',
          border: `1px solid ${sel.has(it.id) ? 'color-mix(in oklch, var(--ai-500) 30%, transparent)' : 'var(--border)'}`,
          cursor: 'pointer',
        }}>
          <input
            type="checkbox" checked={sel.has(it.id)}
            onChange={() => toggle(it.id)}
            style={{ accentColor: 'var(--ai-500)' }}
          />
          <div style={{ flex: 1 }}>
            <div style={{ fontSize: 12, fontWeight: 500, color: 'var(--text)' }}>{it.label}</div>
            <div style={{ fontSize: 10.5, color: 'var(--text-dim)' }}>{it.desc}</div>
          </div>
        </label>
      ))}
    </div>
  );
};

// ════════════════════════════════════════════════════════════════
// PortalAccessCard
// ════════════════════════════════════════════════════════════════
const PortalAccessCard = ({ user, onChange }) => {
  const set = (patch) => onChange({ ...user, ...patch });
  const usernameAvailable = !!user.portal_username && /^[a-z0-9._-]+$/.test(user.portal_username);
  return (
    <div style={{
      border: '1px solid var(--border)', borderRadius: 8,
      background: 'var(--bg-sunken)', padding: '14px',
    }}>
      <label style={{ display: 'flex', alignItems: 'center', gap: 10, marginBottom: 14 }}>
        <input
          type="checkbox" checked={user.portal_activo}
          onChange={ev => set({ portal_activo: ev.target.checked })}
          style={{ accentColor: 'var(--ai-500)' }}
        />
        <span style={{ fontSize: 13, fontWeight: 500 }}>Portal activo</span>
        <PortalBadge activo={user.portal_activo} />
      </label>

      <div style={{ display: 'grid', gridTemplateColumns: '120px 1fr', gap: 10, fontSize: 12, alignItems: 'center', marginBottom: 8 }}>
        <span style={{ color: 'var(--text-muted)' }}>Username:</span>
        <div style={{ display: 'flex', gap: 8, alignItems: 'center' }}>
          <input
            type="text" value={user.portal_username || ''}
            onChange={ev => set({ portal_username: ev.target.value.toLowerCase() })}
            disabled={!user.portal_activo}
            placeholder="username.utilizador"
            style={{
              flex: 1, padding: '5px 8px',
              background: 'var(--bg-elev)', border: '1px solid var(--border)',
              borderRadius: 4, fontSize: 12, color: 'var(--text)',
              fontFamily: 'var(--font-mono)', outline: 'none',
            }}
          />
          {user.portal_activo && (
            <span style={{
              fontSize: 10.5, color: usernameAvailable ? 'var(--ok)' : 'var(--warn)',
              fontFamily: 'var(--font-mono)',
            }}>{usernameAvailable ? '✓ Disponível' : '⚠ inválido'}</span>
          )}
        </div>

        <span style={{ color: 'var(--text-muted)' }}>Password:</span>
        <div style={{ display: 'flex', gap: 8, alignItems: 'center' }}>
          <span style={{ flex: 1, fontFamily: 'var(--font-mono)', fontSize: 12, color: 'var(--text-dim)' }}>••••••••••</span>
          <button className="btn btn-sm btn-ghost"><Icon name="refresh" size={11} />Reset password</button>
        </div>

        <span style={{ color: 'var(--text-muted)' }}>SSO MS 365:</span>
        <div style={{ display: 'flex', gap: 8, alignItems: 'center' }}>
          <SSOBadge activo={user.portal_activo} />
          {user.portal_activo && user.ultima_interacao_digi && (
            <span style={{ fontSize: 11, color: 'var(--text-dim)' }}>
              último login {fmtRel(user.ultima_interacao_digi)}
            </span>
          )}
        </div>
      </div>

      <div style={{ display: 'flex', gap: 8, marginTop: 16, paddingTop: 12, borderTop: '1px solid var(--border)' }}>
        <button className="btn btn-sm btn-ghost"><Icon name="refresh" size={11} />Forçar logout de todas as sessões</button>
        <button className="btn btn-sm btn-ghost" style={{ color: 'var(--err)' }}>
          <Icon name="warning" size={11} />Suspender utilizador
        </button>
      </div>
    </div>
  );
};

// ════════════════════════════════════════════════════════════════
// Audit · Sessions · Conversas
// ════════════════════════════════════════════════════════════════
const AuditLogList = ({ entries }) => (
  <div style={{ border: '1px solid var(--border)', borderRadius: 8, overflow: 'hidden' }}>
    {entries.length === 0 ? (
      <div style={{ padding: 16, fontSize: 12, color: 'var(--text-dim)', textAlign: 'center' }}>Sem alterações registadas.</div>
    ) : entries.map((e, i) => (
      <div key={i} style={{
        display: 'grid', gridTemplateColumns: '120px 1fr',
        gap: 12, padding: '10px 12px', fontSize: 12,
        borderBottom: i < entries.length - 1 ? '1px solid var(--border)' : '0',
      }}>
        <div style={{ display: 'flex', flexDirection: 'column' }}>
          <span style={{ fontSize: 11, fontFamily: 'var(--font-mono)', color: 'var(--text-muted)' }}>{fmtRel(e.ts)}</span>
          <span style={{ fontSize: 10, color: 'var(--text-dim)' }}>{e.who}</span>
        </div>
        <div>
          <div style={{ fontFamily: 'var(--font-mono)', fontSize: 11, color: 'var(--text-muted)', marginBottom: 2 }}>{e.field}</div>
          <div style={{ fontSize: 12 }}>
            <span style={{ color: 'var(--text-dim)', textDecoration: 'line-through' }}>{e.from || '∅'}</span>
            <span style={{ color: 'var(--text-dim)', margin: '0 6px' }}>→</span>
            <span style={{ color: 'var(--ok)' }}>{e.to || '∅'}</span>
          </div>
        </div>
      </div>
    ))}
  </div>
);

const SessionsList = ({ sessions }) => (
  <div style={{ border: '1px solid var(--border)', borderRadius: 8, overflow: 'hidden' }}>
    {sessions.length === 0 ? (
      <div style={{ padding: 16, fontSize: 12, color: 'var(--text-dim)', textAlign: 'center' }}>Portal inactivo — sem sessões.</div>
    ) : sessions.map((s, i) => (
      <div key={i} style={{
        display: 'grid', gridTemplateColumns: '120px 110px 1fr 80px',
        gap: 12, padding: '8px 12px', fontSize: 11.5,
        borderBottom: i < sessions.length - 1 ? '1px solid var(--border)' : '0',
        fontFamily: 'var(--font-mono)',
      }}>
        <span style={{ color: 'var(--text-muted)' }}>{fmtRel(s.ts)}</span>
        <span style={{ color: 'var(--text)' }}>{s.ip}</span>
        <span style={{ color: 'var(--text-dim)' }}>{s.ua}</span>
        <span style={{ color: 'var(--text)', textAlign: 'right' }}>{s.duration}</span>
      </div>
    ))}
  </div>
);

const ConversasList = ({ conversas }) => (
  <div style={{ border: '1px solid var(--border)', borderRadius: 8, overflow: 'hidden' }}>
    {conversas.length === 0 ? (
      <div style={{ padding: 16, fontSize: 12, color: 'var(--text-dim)', textAlign: 'center' }}>Sem conversas registadas.</div>
    ) : (
      <>
        {conversas.map((c, i) => (
          <div key={i} style={{
            display: 'flex', alignItems: 'center', justifyContent: 'space-between',
            padding: '10px 12px', fontSize: 12,
            borderBottom: i < conversas.length - 1 ? '1px solid var(--border)' : '0',
          }}>
            <span style={{ color: 'var(--text)' }}>{c.mes}</span>
            <div style={{ display: 'flex', alignItems: 'center', gap: 12 }}>
              <span style={{ fontFamily: 'var(--font-mono)', fontSize: 11, color: 'var(--text-muted)' }}>{c.count} interacções</span>
              <div style={{ width: 80, height: 4, background: 'var(--bg-sunken)', borderRadius: 2, overflow: 'hidden' }}>
                <div style={{
                  height: '100%', width: `${Math.min(100, c.count / 2)}%`,
                  background: 'var(--ai-500)',
                }} />
              </div>
            </div>
          </div>
        ))}
        <div style={{ padding: '10px 12px', borderTop: '1px solid var(--border)', display: 'flex', justifyContent: 'flex-end' }}>
          <button className="btn btn-sm btn-ghost">
            <Icon name="link" size={11} />Abrir Langfuse
          </button>
        </div>
      </>
    )}
  </div>
);

// ════════════════════════════════════════════════════════════════
// Expor
// ════════════════════════════════════════════════════════════════
window.AdminUsers = {
  Avatar, Tooltip,
  EmpresaTags, RelativeTime,
  TipoBadge, PortalBadge, SSOBadge, ApolloBadge,
  SectionHeader, FieldRow,
  EmpresaJunctionTable, PermissoesEditor, ModosAcessoEditor, PortalAccessCard,
  AuditLogList, SessionsList, ConversasList,
  helpers: { initials, fmtRel, fmtAbs },
};
