// PAC Sistema — Shared Components

// ─── SearchableSelect CSS ────────────────────────────────────────────────────
const SS_CSS = `
.ss-trigger {
  display: flex !important;
  align-items: center;
  justify-content: space-between;
  gap: 6px;
  width: 100%;
  cursor: pointer;
  text-align: left;
  -webkit-appearance: none;
  appearance: none;
  background: #fff;
  color: inherit;
  font: inherit;
  box-sizing: border-box;
  padding: 8px 12px;
  border: 1.5px solid #d1d5db;
  border-radius: 6px;
  font-size: 13px;
  line-height: 1.4;
  transition: border-color .15s, box-shadow .15s;
}
.ss-trigger:hover:not(:disabled) { border-color: #9ca3af; }
.ss-trigger:focus-visible {
  outline: none;
  border-color: var(--pac-navy, #0D0D6B);
  box-shadow: 0 0 0 3px rgba(13,13,107,.10);
}
.ss-trigger:disabled { cursor: not-allowed; opacity: .65; background: #f9fafb; }

/* Match .field-w > select styling used in tasks, calendar, reports, upload */
.field-w .ss-trigger {
  font-size: 13px;
  padding: 10px 12px;
  border: 1px solid var(--border, #e8e8f0);
  border-radius: 4px;
  background: #fff;
  color: var(--pac-black, #1a1a2e);
}
.field-w .ss-trigger:focus-visible,
.field-w .ss-trigger:focus {
  border-color: var(--pac-navy, #0D0D6B);
  box-shadow: 0 0 0 3px rgba(13,13,107,.10);
}

/* Option hover */
.ss-opt:hover { background: var(--surface, #f4f4f6) !important; }
`;

if (!document.getElementById('ss-css')) {
  const _s = document.createElement('style');
  _s.id = 'ss-css';
  _s.textContent = SS_CSS;
  document.head.appendChild(_s);
}

// ─── SearchableSelect ────────────────────────────────────────────────────────
// Drop-in replacement for <select> with a sticky search bar at the top of the
// dropdown. Renders the dropdown via a portal on document.body so overflow:hidden
// containers never clip it.
//
// API: same as <select> — value, onChange (receives { target: { value } }),
//      className, style, disabled, children (<option> / <optgroup> elements).
const SearchableSelect = ({ value, onChange, className, style, children, disabled }) => {
  const [open, setOpen] = React.useState(false);
  const [search, setSearch] = React.useState('');
  const [pos, setPos] = React.useState({ top: 0, left: 0, width: 0, maxHeight: 260 });
  const trigRef = React.useRef(null);
  const searchRef = React.useRef(null);

  // Flatten <option> children (handles arrays, <optgroup>, null/false)
  const options = React.useMemo(() => {
    const acc = [];
    const walk = (node) => {
      if (!node) return;
      if (Array.isArray(node)) { node.forEach(walk); return; }
      if (node.type === 'option') {
        const v = node.props.value !== undefined ? String(node.props.value) : String(node.props.children ?? '');
        acc.push({ value: v, label: String(node.props.children ?? '') });
      } else if (node.type === 'optgroup') {
        React.Children.forEach(node.props.children, walk);
      }
    };
    React.Children.forEach(children, walk);
    return acc;
  }, [children]);

  const valStr = value != null ? String(value) : '';
  const selected = options.find(o => o.value === valStr);
  const isPlaceholder = !selected || selected.value === '';

  const filtered = search.trim()
    ? options.filter(o => o.label.toLowerCase().includes(search.toLowerCase()))
    : options;

  // Calculate portal position (flip up if not enough space below)
  const openDrop = () => {
    if (!trigRef.current || disabled) return;
    const r = trigRef.current.getBoundingClientRect();
    const spaceBelow = window.innerHeight - r.bottom - 8;
    const spaceAbove = r.top - 8;
    const maxH = Math.min(280, Math.max(spaceBelow, spaceAbove));
    const flipUp = spaceBelow < 150 && spaceAbove > spaceBelow;
    setPos({
      left: r.left,
      width: r.width,
      top: flipUp ? undefined : r.bottom + 3,
      bottom: flipUp ? (window.innerHeight - r.top + 3) : undefined,
      maxHeight: flipUp ? Math.min(280, spaceAbove) : Math.min(280, spaceBelow),
    });
    setOpen(true);
  };

  // Close on outside click
  React.useEffect(() => {
    if (!open) return;
    const onDown = (e) => {
      const portal = document.getElementById('ss-portal');
      if (trigRef.current?.contains(e.target)) return;
      if (portal?.contains(e.target)) return;
      setOpen(false);
      setSearch('');
    };
    document.addEventListener('mousedown', onDown);
    return () => document.removeEventListener('mousedown', onDown);
  }, [open]);

  // Close on scroll outside the portal (reposition would be stale), but ignore
  // scroll events that originate inside the dropdown list itself.
  React.useEffect(() => {
    if (!open) return;
    const close = (e) => {
      const portal = document.getElementById('ss-portal');
      if (portal?.contains(e.target)) return;
      setOpen(false);
      setSearch('');
    };
    window.addEventListener('scroll', close, true);
    window.addEventListener('resize', close);
    return () => {
      window.removeEventListener('scroll', close, true);
      window.removeEventListener('resize', close);
    };
  }, [open]);

  // Auto-focus search input when dropdown opens
  React.useEffect(() => {
    if (open && searchRef.current) searchRef.current.focus();
  }, [open]);

  const pick = (val) => {
    onChange({ target: { value: val } });
    setOpen(false);
    setSearch('');
  };

  const dropdown = open ? ReactDOM.createPortal(
    <div
      id="ss-portal"
      style={{
        position: 'fixed',
        top: pos.top,
        bottom: pos.bottom,
        left: pos.left,
        width: pos.width,
        zIndex: 99999,
        background: '#fff',
        border: '1.5px solid #d1d5db',
        borderRadius: 8,
        boxShadow: '0 8px 32px rgba(0,0,0,.15)',
        display: 'flex',
        flexDirection: 'column',
        maxHeight: pos.maxHeight,
        overflow: 'hidden',
      }}
    >
      {/* Sticky search bar — always visible at top */}
      <div style={{
        padding: '7px 8px 5px',
        borderBottom: '1px solid #f0f0f5',
        flexShrink: 0,
        background: '#fafafa',
      }}>
        <input
          ref={searchRef}
          type="text"
          value={search}
          onChange={e => setSearch(e.target.value)}
          onKeyDown={e => {
            if (e.key === 'Escape') { setOpen(false); setSearch(''); }
            e.stopPropagation();
          }}
          placeholder="Buscar…"
          style={{
            width: '100%',
            boxSizing: 'border-box',
            padding: '5px 10px',
            border: '1.5px solid #e5e7eb',
            borderRadius: 6,
            fontSize: 12.5,
            outline: 'none',
            fontFamily: 'inherit',
            background: '#fff',
            color: '#1a1a2e',
          }}
        />
      </div>

      {/* Scrollable options list */}
      <div style={{ overflowY: 'auto', flex: 1 }}>
        {filtered.length === 0 ? (
          <div style={{ padding: '10px 12px', color: '#9ca3af', fontSize: 13 }}>
            Nenhum resultado
          </div>
        ) : filtered.map((opt, i) => {
          const isSel = opt.value === valStr;
          return (
            <div
              key={`${opt.value}__${i}`}
              onMouseDown={e => { e.preventDefault(); pick(opt.value); }}
              className="ss-opt"
              style={{
                padding: '8px 12px',
                cursor: 'pointer',
                fontSize: 13,
                color: opt.value === '' ? '#9ca3af' : 'var(--fg, #1a1a2e)',
                background: isSel ? 'rgba(13,13,107,0.07)' : 'transparent',
                fontWeight: isSel ? 600 : 400,
                transition: 'background .1s',
              }}
            >
              {opt.label}
            </div>
          );
        })}
      </div>
    </div>,
    document.body
  ) : null;

  return (
    <div style={{ position: 'relative', display: 'block' }}>
      <button
        ref={trigRef}
        type="button"
        className={`ss-trigger${className ? ` ${className}` : ''}`}
        style={style}
        disabled={disabled}
        onMouseDown={e => {
          if (disabled) return;
          e.preventDefault();
          open ? (setOpen(false), setSearch('')) : openDrop();
        }}
      >
        <span style={{
          flex: 1,
          overflow: 'hidden',
          textOverflow: 'ellipsis',
          whiteSpace: 'nowrap',
          color: isPlaceholder ? '#9ca3af' : 'inherit',
        }}>
          {selected?.label || ' '}
        </span>
        <svg
          width="10" height="10" viewBox="0 0 10 10"
          aria-hidden="true"
          style={{
            flexShrink: 0,
            transform: open ? 'rotate(180deg)' : 'none',
            transition: 'transform .15s',
            opacity: .45,
          }}
        >
          <path
            d="M1.5 3.5L5 7l3.5-3.5"
            stroke="currentColor"
            strokeWidth="1.7"
            fill="none"
            strokeLinecap="round"
            strokeLinejoin="round"
          />
        </svg>
      </button>
      {dropdown}
    </div>
  );
};

// ═══════════════════════════════════════════════════════════════════════════
// E-mail (Gmail) — leitor + transformar em tarefa
// Usados pelo Meu Painel (caixa de entrada) e pelo Kanban (snapshot da tarefa)
// ═══════════════════════════════════════════════════════════════════════════

const EMAIL_ESCAPE = (s) => String(s || '')
  .replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;');

const emailFmtDate = (iso) => {
  if (!iso) return '';
  const d = new Date(iso);
  if (isNaN(d.getTime())) return '';
  return d.toLocaleDateString('pt-BR', { day: '2-digit', month: 'short', year: 'numeric' }) +
    ' às ' + d.toLocaleTimeString('pt-BR', { hour: '2-digit', minute: '2-digit' });
};

// Box grande de leitura do e-mail. Aceita tanto o e-mail vivo do Gmail
// (camelCase) quanto o snapshot salvo na tarefa (snake_case).
// Segurança: o corpo HTML é SEMPRE renderizado em <iframe sandbox> sem
// allow-scripts e sem allow-same-origin — e-mail é vetor clássico de XSS.
const EmailReaderModal = ({ email, onClose, onCreateTask, snapshotNote }) => {
  React.useEffect(() => {
    const h = (e) => { if (e.key === 'Escape') onClose(); };
    document.addEventListener('keydown', h);
    return () => document.removeEventListener('keydown', h);
  }, [onClose]);

  const from = email.from || email.from_address || '';
  const to = email.to || email.to_addresses || '';
  const cc = email.cc || email.cc_addresses || '';
  const subject = email.subject || '(sem assunto)';
  const date = email.date || email.sent_at;
  const bodyHtml = email.bodyHtml || email.body_html;
  const bodyText = email.bodyText || email.body_text;
  const attachments = email.attachments || [];

  const srcDoc = `<!doctype html><html><head><meta charset="utf-8"><base target="_blank">
<style>body{font-family:system-ui,-apple-system,'Segoe UI',sans-serif;font-size:14px;line-height:1.55;color:#1a1a2e;margin:18px;word-break:break-word}img{max-width:100%;height:auto}blockquote{border-left:3px solid #ddd;margin-left:0;padding-left:12px;color:#555}</style>
</head><body>${bodyHtml || `<pre style="white-space:pre-wrap;font-family:inherit;margin:0">${EMAIL_ESCAPE(bodyText)}</pre>`}</body></html>`;

  const fmtSize = (n) => {
    if (!n) return '';
    if (n < 1024) return `${n} B`;
    if (n < 1048576) return `${(n / 1024).toFixed(0)} KB`;
    return `${(n / 1048576).toFixed(1)} MB`;
  };

  return (
    <div className="scrim" onClick={e => { e.stopPropagation(); onClose(); }} style={{ zIndex: 9000 }}>
      <div className="modal" onClick={e => e.stopPropagation()} style={{ maxWidth: 860, width: '94%', display: 'flex', flexDirection: 'column', maxHeight: '88vh' }}>
        <div className="modal-head" style={{ alignItems: 'flex-start' }}>
          <div style={{ width: 32, height: 32, borderRadius: 4, background: 'var(--pac-navy, #0D0D6B)', color: '#fff', display: 'grid', placeItems: 'center', flexShrink: 0 }}>
            <Icon name="mail" size={15} />
          </div>
          <div style={{ minWidth: 0, flex: 1 }}>
            <h2 style={{ fontSize: 15.5, lineHeight: 1.35, wordBreak: 'break-word' }}>{subject}</h2>
            <div style={{ fontSize: 11.5, color: 'var(--fg-muted, #9ca3af)', marginTop: 3, display: 'grid', gap: 1 }}>
              <span><b style={{ color: '#555' }}>De:</b> {from}</span>
              {to && <span><b style={{ color: '#555' }}>Para:</b> {to}</span>}
              {cc && <span><b style={{ color: '#555' }}>Cc:</b> {cc}</span>}
              {date && <span>{emailFmtDate(date)}</span>}
            </div>
          </div>
          <button className="x" onClick={onClose}><Icon name="x" size={16} /></button>
        </div>

        {snapshotNote && (
          <div style={{ margin: '0 20px', padding: '7px 12px', background: 'rgba(13,13,107,.05)', border: '1px solid rgba(13,13,107,.12)', borderRadius: 6, fontSize: 11.5, color: 'var(--pac-navy, #0D0D6B)' }}>
            {snapshotNote}
          </div>
        )}

        {attachments.length > 0 && (
          <div style={{ margin: '8px 20px 0', display: 'flex', gap: 6, flexWrap: 'wrap' }}>
            {attachments.map((a, i) => (
              <span key={i} title={a.mimeType} style={{ display: 'inline-flex', alignItems: 'center', gap: 5, fontSize: 11.5, padding: '4px 10px', background: '#f2f2f8', border: '1px solid #e2e2ee', borderRadius: 14, color: '#444' }}>
                <Icon name="paperclip" size={11} style={{ opacity: .55 }} />
                {a.filename}{a.size ? ` · ${fmtSize(a.size)}` : ''}
              </span>
            ))}
          </div>
        )}

        <div className="modal-body" style={{ flex: 1, minHeight: 320, padding: '12px 20px', overflow: 'hidden', display: 'flex' }}>
          <iframe
            title="Conteúdo do e-mail"
            sandbox="allow-popups allow-popups-to-escape-sandbox"
            srcDoc={srcDoc}
            style={{ width: '100%', border: '1px solid #e8e8f0', borderRadius: 8, background: '#fff', flex: 1 }}
          />
        </div>

        <div className="modal-foot">
          <button className="btn ghost sm" onClick={onClose}>Fechar</button>
          {onCreateTask && (
            <button className="btn sm" onClick={onCreateTask}>
              <Icon name="checkSquare" size={13} /> Criar tarefa
            </button>
          )}
        </div>
      </div>
    </div>
  );
};

// Transformar e-mail em tarefa — mesmo formato do EventToTaskModal do
// calendário; cria o card no Kanban e vincula o snapshot do e-mail
// (o responsável vê o e-mail pelo botão "Ver e-mail" do card).
const EmailToTaskModal = ({ email, users, onClose, onCreated }) => {
  React.useEffect(() => {
    const h = (e) => { if (e.key === 'Escape') onClose(); };
    document.addEventListener('keydown', h);
    return () => document.removeEventListener('keydown', h);
  }, [onClose]);

  const [form, setForm] = React.useState({
    title: email.subject && email.subject !== '(sem assunto)' ? email.subject : '',
    description: '',
    due_date: '',
    client_id: '',
    case_id: '',
    owner_user_id: '',
    priority: 'Média',
  });
  const [clients, setClients] = React.useState([]);
  const [cases, setCases] = React.useState([]);
  const [saving, setSaving] = React.useState(false);
  const [error, setError] = React.useState('');
  const setF = (k, v) => setForm(f => ({ ...f, [k]: v }));

  React.useEffect(() => {
    window.PACApi.clients.list().then(setClients).catch(() => {});
    window.PACApi.cases.list().then(setCases).catch(() => {});
  }, []);

  const filteredCases = cases.filter(c => !form.client_id || c.client_id === form.client_id);

  const onSave = async () => {
    if (!form.title.trim()) { setError('Título é obrigatório.'); return; }
    setSaving(true); setError('');
    try {
      const payload = {
        title: form.title.trim(),
        description: form.description.trim() || undefined,
        due_date: form.due_date || undefined,
        client_id: form.client_id || undefined,
        case_id: form.case_id || undefined,
        owner_user_id: form.owner_user_id || undefined,
        priority: form.priority,
      };
      const { task, emailLinked } = await window.PACApi.gmail.createTask(email.id, payload);
      if (onCreated) onCreated(task, emailLinked);
      onClose();
    } catch (e) {
      setError(e.message || 'Erro ao criar tarefa.');
    } finally {
      setSaving(false);
    }
  };

  return (
    <div className="scrim" onClick={e => { e.stopPropagation(); onClose(); }} style={{ zIndex: 9100 }}>
      <div className="modal" onClick={e => e.stopPropagation()} style={{ maxWidth: 480 }}>
        <div className="modal-head">
          <div style={{ width: 32, height: 32, borderRadius: 4, background: 'var(--pac-navy, #0D0D6B)', color: '#fff', display: 'grid', placeItems: 'center' }}>
            <Icon name="checkSquare" size={15} />
          </div>
          <div style={{ minWidth: 0 }}>
            <h2>Transformar e-mail em tarefa</h2>
            <div style={{ fontSize: 11, color: 'var(--fg-muted)', marginTop: 1, overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>
              {email.from || email.from_address} · {email.subject}
            </div>
          </div>
          <button className="x" onClick={onClose}><Icon name="x" size={16} /></button>
        </div>
        <div className="modal-body" style={{ display: 'grid', gap: 12 }}>
          {error && (
            <div style={{ padding: '8px 12px', background: 'rgba(194,37,62,.08)', border: '1px solid rgba(194,37,62,.2)', borderRadius: 6, color: '#C2253E', fontSize: 12 }}>
              {error}
            </div>
          )}
          <div className="field-w">
            <label>Título *</label>
            <input autoFocus value={form.title} onChange={e => setF('title', e.target.value)} />
          </div>
          <div className="field-w">
            <label>Descrição (o que precisa ser feito)</label>
            <textarea
              rows={3}
              value={form.description}
              onChange={e => setF('description', e.target.value)}
              placeholder="Descreva a tarefa — o e-mail completo ficará anexado ao card automaticamente."
              style={{ resize: 'vertical' }}
            />
          </div>
          <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 10 }}>
            <div className="field-w">
              <label>Prazo</label>
              <input type="date" value={form.due_date} onChange={e => setF('due_date', e.target.value)} />
            </div>
            <div className="field-w">
              <label>Prioridade</label>
              <select value={form.priority} onChange={e => setF('priority', e.target.value)}>
                <option>Alta</option>
                <option>Média</option>
                <option>Baixa</option>
              </select>
            </div>
            <div className="field-w">
              <label>Cliente</label>
              <SearchableSelect value={form.client_id} onChange={e => { setF('client_id', e.target.value); setF('case_id', ''); }}>
                <option value="">— Nenhum —</option>
                {clients.map(c => <option key={c.id} value={c.id}>{c.name}</option>)}
              </SearchableSelect>
            </div>
            <div className="field-w">
              <label>Caso</label>
              <SearchableSelect value={form.case_id} onChange={e => setF('case_id', e.target.value)}>
                <option value="">— Nenhum —</option>
                {filteredCases.map(c => <option key={c.id} value={c.id}>{c.number} · {c.title}</option>)}
              </SearchableSelect>
            </div>
          </div>
          <div className="field-w">
            <label>Responsável</label>
            <select value={form.owner_user_id} onChange={e => setF('owner_user_id', e.target.value)}>
              <option value="">— Eu mesmo —</option>
              {(users || []).map(u => <option key={u.id} value={u.id}>{u.name}</option>)}
            </select>
          </div>
          <div style={{ fontSize: 11.5, color: 'var(--fg-muted, #9ca3af)', lineHeight: 1.5 }}>
            Uma cópia deste e-mail será vinculada ao card — quem receber a tarefa
            poderá ler o e-mail pelo botão "Ver e-mail", sem acesso à sua caixa de entrada.
          </div>
        </div>
        <div className="modal-foot">
          <button className="btn ghost sm" onClick={onClose}>Cancelar</button>
          <button className="btn sm" onClick={onSave} disabled={saving}>
            {saving ? 'Criando…' : 'Criar tarefa'}
          </button>
        </div>
      </div>
    </div>
  );
};

window.EmailReaderModal = EmailReaderModal;
window.EmailToTaskModal = EmailToTaskModal;
