/* FINANCEIRO — Reconciliação de Faturas
   Upload extrato Revolut (PDF) → pesquisa faturas nas caixas de email configuradas
*/

(function () {
  // ── Helpers ────────────────────────────────────────────────────────────────
  const fmtAmount = (amount, currency) => {
    const sign = amount < 0 ? '-' : '+';
    return `${sign}${Math.abs(amount).toFixed(2)} ${currency}`;
  };

  const scoreColor = (score) => {
    if (score >= 60) return 'var(--green, #22c55e)';
    if (score >= 30) return 'var(--amber, #f59e0b)';
    return 'var(--text-dim)';
  };

  // ── Config Drawer ──────────────────────────────────────────────────────────
  const MailboxConfig = ({ onClose }) => {
    const [mailboxes, setMailboxes] = React.useState([]);
    const [newEmail, setNewEmail] = React.useState('');
    const [newLabel, setNewLabel] = React.useState('');
    const [loading, setLoading] = React.useState(true);

    React.useEffect(() => {
      fetch('/api/finance/reconciliation/mailboxes')
        .then(r => r.json())
        .then(d => { setMailboxes(d.mailboxes || []); setLoading(false); })
        .catch(() => setLoading(false));
    }, []);

    const addMailbox = async () => {
      if (!newEmail.trim()) return;
      try {
        const r = await fetch('/api/finance/reconciliation/mailboxes', {
          method: 'POST',
          headers: { 'Content-Type': 'application/json' },
          body: JSON.stringify({ email: newEmail.trim(), label: newLabel.trim() || newEmail.trim() }),
        });
        const d = await r.json();
        if (d.mailbox) {
          setMailboxes(prev => [...prev.filter(m => m.id !== d.mailbox.id), d.mailbox]);
          setNewEmail(''); setNewLabel('');
        }
      } catch (e) {
        console.error('Failed to add mailbox:', e);
      }
    };

    const removeMailbox = async (id) => {
      try {
        await fetch(`/api/finance/reconciliation/mailboxes/${id}`, { method: 'DELETE' });
        setMailboxes(prev => prev.filter(m => m.id !== id));
      } catch (e) {
        console.error('Failed to remove mailbox:', e);
      }
    };

    return (
      <div style={{ position: 'fixed', inset: 0, background: 'rgba(0,0,0,0.4)', zIndex: 1000, display: 'flex', alignItems: 'flex-end', justifyContent: 'flex-end' }}>
        <div className="card" style={{ width: 420, height: '100vh', borderRadius: '12px 0 0 12px', display: 'flex', flexDirection: 'column', overflow: 'hidden' }}>
          <div style={{ padding: '18px 20px', borderBottom: '1px solid var(--border)', display: 'flex', alignItems: 'center', justifyContent: 'space-between' }}>
            <div className="font-display" style={{ fontWeight: 600, fontSize: 15 }}>Caixas de Email</div>
            <button className="btn btn-sm" onClick={onClose}>Fechar</button>
          </div>
          <div style={{ flex: 1, overflowY: 'auto', padding: '16px 20px' }}>
            <div style={{ fontSize: 12, color: 'var(--text-muted)', marginBottom: 14, lineHeight: 1.5 }}>
              Caixas onde o sistema vai pesquisar faturas para cada transação.
            </div>
            {loading ? (
              <div style={{ color: 'var(--text-dim)', fontSize: 13 }}>A carregar...</div>
            ) : mailboxes.map(mb => (
              <div key={mb.id} style={{ display: 'flex', alignItems: 'center', gap: 10, padding: '8px 0', borderBottom: '1px solid var(--border)' }}>
                <Icon name="mail" size={14} />
                <div style={{ flex: 1, minWidth: 0 }}>
                  <div style={{ fontSize: 13, fontWeight: 500 }}>{mb.label}</div>
                  <div style={{ fontSize: 11, color: 'var(--text-muted)', fontFamily: 'var(--font-mono)' }}>{mb.email}</div>
                </div>
                <button className="btn btn-sm" style={{ color: 'var(--red, #ef4444)', border: '1px solid var(--border)' }} onClick={() => removeMailbox(mb.id)}>
                  <Icon name="trash" size={12} />
                </button>
              </div>
            ))}
            <div style={{ marginTop: 20 }}>
              <div style={{ fontSize: 12, color: 'var(--text-muted)', marginBottom: 8, fontWeight: 600 }}>ADICIONAR CAIXA</div>
              <input
                className="input"
                placeholder="email@digidelta.pt"
                value={newEmail}
                onChange={e => setNewEmail(e.target.value)}
                style={{ width: '100%', marginBottom: 8 }}
              />
              <input
                className="input"
                placeholder="Etiqueta (ex: Financeiro)"
                value={newLabel}
                onChange={e => setNewLabel(e.target.value)}
                style={{ width: '100%', marginBottom: 8 }}
              />
              <button className="btn btn-primary btn-sm" onClick={addMailbox} style={{ width: '100%' }}>
                Adicionar
              </button>
            </div>
          </div>
        </div>
      </div>
    );
  };

  // ── Match Row ──────────────────────────────────────────────────────────────
  const MatchRow = ({ match }) => {
    const [attachments, setAttachments] = React.useState(null);
    const [loadingAtts, setLoadingAtts] = React.useState(false);
    const [urls, setUrls] = React.useState(null);
    const [loadingUrls, setLoadingUrls] = React.useState(false);

    const fetchAttachments = async (e) => {
      e.stopPropagation();
      if (attachments !== null) return;
      setLoadingAtts(true);
      try {
        const r = await fetch(`/api/finance/reconciliation/attachments?mailbox=${encodeURIComponent(match.mailbox)}&messageId=${encodeURIComponent(match.messageId)}`);
        const d = await r.json();
        setAttachments(d.attachments || []);
      } catch {
        setAttachments([]);
      } finally {
        setLoadingAtts(false);
      }
    };

    const fetchUrls = async (e) => {
      e.stopPropagation();
      if (urls !== null) { setUrls(null); return; }
      setLoadingUrls(true);
      try {
        const r = await fetch(`/api/finance/reconciliation/urls?mailbox=${encodeURIComponent(match.mailbox)}&messageId=${encodeURIComponent(match.messageId)}`);
        const d = await r.json();
        setUrls(d.urls || []);
      } catch {
        setUrls([]);
      } finally {
        setLoadingUrls(false);
      }
    };

    const attUrl = (a) =>
      `/api/finance/reconciliation/attachment?mailbox=${encodeURIComponent(match.mailbox)}&messageId=${encodeURIComponent(match.messageId)}&attachmentId=${encodeURIComponent(a.id)}`;

    return (
      <div style={{ background: 'var(--bg-sunken)', borderRadius: 6, marginBottom: 6, overflow: 'hidden' }}>
        <div style={{ padding: '8px 12px', display: 'flex', alignItems: 'flex-start', gap: 10 }}>
          <div style={{ width: 32, height: 32, borderRadius: 6, background: 'var(--bg)', border: '1px solid var(--border)', display: 'grid', placeItems: 'center', flexShrink: 0 }}>
            <Icon name={match.hasAttachments ? 'paperclip' : 'mail'} size={13} />
          </div>
          <div style={{ flex: 1, minWidth: 0 }}>
            <div style={{ fontSize: 12.5, fontWeight: 500, whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' }}>{match.subject}</div>
            <div style={{ fontSize: 11, color: 'var(--text-muted)', marginTop: 2 }}>
              {match.fromName || match.from} · {match.receivedDateTime?.slice(0, 10)} · {match.mailbox}
            </div>
          </div>
          <div style={{ flexShrink: 0, textAlign: 'right', display: 'flex', flexDirection: 'column', alignItems: 'flex-end', gap: 4 }}>
            <div style={{ fontSize: 11, fontFamily: 'var(--font-mono)', fontWeight: 700, color: scoreColor(match.score) }}>
              {match.score}%
            </div>
            <button
              className="btn btn-sm"
              onClick={fetchUrls}
              disabled={loadingUrls}
              style={{ fontSize: 10, padding: '2px 7px', display: 'flex', alignItems: 'center', gap: 4 }}
            >
              <Icon name="link" size={10} />
              {loadingUrls ? '...' : urls !== null ? 'Fechar' : 'Ver URLs'}
            </button>
            {match.hasAttachments && (
              <button
                className="btn btn-sm"
                onClick={fetchAttachments}
                disabled={loadingAtts}
                style={{ fontSize: 10, padding: '2px 7px', display: 'flex', alignItems: 'center', gap: 4 }}
              >
                <Icon name="download" size={10} />
                {loadingAtts ? '...' : 'Anexos'}
              </button>
            )}
          </div>
        </div>
        {attachments && attachments.length > 0 && (
          <div style={{ padding: '0 12px 10px 54px', display: 'flex', flexWrap: 'wrap', gap: 6 }}>
            {attachments.map(a => (
              <a
                key={a.id}
                href={attUrl(a)}
                download={a.name}
                style={{ fontSize: 11, color: 'var(--accent-500, #3b82f6)', textDecoration: 'none', display: 'flex', alignItems: 'center', gap: 4, padding: '3px 8px', background: 'var(--bg)', border: '1px solid var(--border)', borderRadius: 4 }}
              >
                <Icon name="file" size={10} />
                {a.name}
              </a>
            ))}
          </div>
        )}
        {attachments && attachments.length === 0 && (
          <div style={{ padding: '0 12px 8px 54px', fontSize: 11, color: 'var(--text-dim)' }}>Sem anexos acessíveis.</div>
        )}
        {urls !== null && (
          <div style={{ padding: '0 12px 10px 54px', borderTop: '1px solid var(--border)' }}>
            {urls.length === 0
              ? <div style={{ fontSize: 11, color: 'var(--text-dim)', paddingTop: 8 }}>Sem URLs encontrados.</div>
              : <div style={{ display: 'flex', flexDirection: 'column', gap: 4, paddingTop: 8 }}>
                  {urls.map((u, i) => (
                    <a key={i} href={u} target="_blank" rel="noopener noreferrer"
                      style={{ fontSize: 11, color: 'var(--accent-500, #3b82f6)', textDecoration: 'none', display: 'flex', alignItems: 'center', gap: 4, wordBreak: 'break-all' }}
                    >
                      <Icon name="external-link" size={10} style={{ flexShrink: 0 }} />
                      {u}
                    </a>
                  ))}
                </div>
            }
          </div>
        )}
      </div>
    );
  };

  // ── Transaction Row ────────────────────────────────────────────────────────
  const TransactionRow = ({ result }) => {
    const { transaction: tx, matches, keyword } = result;
    const [expanded, setExpanded] = React.useState(matches.length > 0 && matches[0].score >= 30);
    const isExpense = tx.amount < 0;
    const bestScore = matches[0]?.score || 0;

    return (
      <div className="card" style={{ marginBottom: 8, overflow: 'hidden' }}>
        <div
          onClick={() => setExpanded(e => !e)}
          style={{ padding: '12px 16px', display: 'flex', alignItems: 'center', gap: 14, cursor: 'pointer', userSelect: 'none' }}
        >
          {/* Status indicator */}
          <div style={{ width: 8, height: 8, borderRadius: '50%', flexShrink: 0, background: bestScore >= 60 ? 'var(--green, #22c55e)' : bestScore >= 30 ? 'var(--amber, #f59e0b)' : 'var(--text-dim)' }} />

          {/* Date */}
          <div style={{ fontFamily: 'var(--font-mono)', fontSize: 11, color: 'var(--text-muted)', flexShrink: 0, width: 80 }}>{tx.date}</div>

          {/* Description */}
          <div style={{ flex: 1, minWidth: 0 }}>
            <div style={{ fontSize: 13, fontWeight: 500, whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' }}>{tx.description}</div>
            {keyword && <div style={{ fontSize: 11, color: 'var(--text-dim)', fontFamily: 'var(--font-mono)', marginTop: 1 }}>keyword: {keyword}</div>}
          </div>

          {/* Amount */}
          <div style={{ fontFamily: 'var(--font-mono)', fontSize: 13, fontWeight: 600, flexShrink: 0, color: isExpense ? 'var(--red, #ef4444)' : 'var(--green, #22c55e)' }}>
            {fmtAmount(tx.amount, tx.currency)}
          </div>

          {/* Match count */}
          <div style={{ flexShrink: 0, textAlign: 'right', minWidth: 60 }}>
            {matches.length > 0 ? (
              <span style={{ fontSize: 11, fontFamily: 'var(--font-mono)', fontWeight: 600, color: scoreColor(bestScore) }}>
                {matches.length} match{matches.length > 1 ? 'es' : ''}
              </span>
            ) : (
              <span style={{ fontSize: 11, color: 'var(--text-dim)' }}>sem match</span>
            )}
          </div>

          <Icon name={expanded ? 'chevron-up' : 'chevron-down'} size={14} />
        </div>

        {expanded && (
          <div style={{ padding: '0 16px 12px', borderTop: '1px solid var(--border)' }}>
            {matches.length === 0 ? (
              <div style={{ padding: '12px 0', fontSize: 12, color: 'var(--text-muted)' }}>
                Nenhum email encontrado nas caixas configuradas para esta transação.
              </div>
            ) : (
              <div style={{ paddingTop: 10 }}>
                {matches.map((m, i) => <MatchRow key={i} match={m} />)}
              </div>
            )}
          </div>
        )}
      </div>
    );
  };

  // ── Main Screen ────────────────────────────────────────────────────────────
  const FinanceReconciliacaoScreen = () => {
    const [file, setFile] = React.useState(null);
    const [transactions, setTransactions] = React.useState([]);
    const [results, setResults] = React.useState([]);
    const [loading, setLoading] = React.useState(false);
    const [error, setError] = React.useState(null);
    const [showConfig, setShowConfig] = React.useState(false);
    const [stats, setStats] = React.useState(null);
    const fileRef = React.useRef();
    const [invoiceQuery, setInvoiceQuery] = React.useState('');
    const [invoiceResults, setInvoiceResults] = React.useState(null);
    const [invoiceLoading, setInvoiceLoading] = React.useState(false);
    const [invoiceError, setInvoiceError] = React.useState(null);

    const handleFile = async (e) => {
      const f = e.target.files?.[0];
      if (!f) return;
      setFile(f);
      setResults([]);
      setError(null);
      setTransactions([]);
      setLoading(true);
      try {
        const formData = new FormData();
        formData.append('statement', f);
        const r = await fetch('/api/finance/reconciliation/parse-statement', { method: 'POST', body: formData });
        const d = await r.json();
        if (!r.ok) throw new Error(d.error || 'Erro ao processar PDF');
        setTransactions(d.transactions || []);
      } catch (err) {
        setError(err.message);
      } finally {
        setLoading(false);
      }
    };

    const runSearch = async () => {
      if (transactions.length === 0) return;
      setLoading(true);
      setError(null);
      try {
        const r = await fetch('/api/finance/reconciliation/search', {
          method: 'POST',
          headers: { 'Content-Type': 'application/json' },
          body: JSON.stringify({ transactions }),
        });
        const d = await r.json();
        if (!r.ok) throw new Error(d.error || 'Erro no servidor');
        setResults(d.results || []);
        const matched = (d.results || []).filter(r => r.matches.length > 0 && r.matches[0].score >= 30).length;
        setStats({ total: d.results.length, matched, pct: d.results.length > 0 ? Math.round(matched / d.results.length * 100) : 0 });
      } catch (e) {
        setError(e.message);
      } finally {
        setLoading(false);
      }
    };

    const searchInvoice = async () => {
      if (!invoiceQuery.trim()) return;
      setInvoiceLoading(true);
      setInvoiceError(null);
      setInvoiceResults(null);
      try {
        const r = await fetch('/api/finance/reconciliation/search-invoice', {
          method: 'POST',
          headers: { 'Content-Type': 'application/json' },
          body: JSON.stringify({ query: invoiceQuery.trim() }),
        });
        const d = await r.json();
        if (!r.ok) throw new Error(d.error || 'Erro no servidor');
        setInvoiceResults(d.matches || []);
      } catch (e) {
        setInvoiceError(e.message);
      } finally {
        setInvoiceLoading(false);
      }
    };

    const expenseCount = transactions.filter(t => t.amount < 0).length;

    return (
      <div className="scrollbar" style={{ height: '100%', overflowY: 'auto', padding: '28px 32px 80px' }}>
        {showConfig && <MailboxConfig onClose={() => setShowConfig(false)} />}

        {/* Header */}
        <div style={{ display: 'flex', alignItems: 'flex-start', justifyContent: 'space-between', marginBottom: 24 }}>
          <div>
            <div className="font-mono" style={{ fontSize: 11, color: 'var(--text-dim)', letterSpacing: '0.08em', textTransform: 'uppercase' }}>
              FINANCEIRO · RECONCILIAÇÃO
            </div>
            <h2 className="font-display" style={{ margin: '4px 0 0', fontSize: 24, fontWeight: 500, letterSpacing: '-0.01em' }}>
              Reconciliação de Faturas
            </h2>
            <div style={{ fontSize: 13, color: 'var(--text-muted)', marginTop: 4 }}>
              Upload do extrato Revolut (PDF) → pesquisa automática de faturas nas caixas de email
            </div>
          </div>
          <button className="btn btn-sm" onClick={() => setShowConfig(true)} style={{ display: 'flex', alignItems: 'center', gap: 6 }}>
            <Icon name="settings" size={13} />
            Caixas de email
          </button>
        </div>

        {/* Upload zone */}
        <div
          className="card"
          onClick={() => fileRef.current?.click()}
          style={{ padding: '32px 24px', textAlign: 'center', cursor: 'pointer', border: '2px dashed var(--border)', background: file ? 'color-mix(in oklch, var(--accent-500) 4%, var(--bg))' : 'var(--bg-sunken)', marginBottom: 20 }}
        >
          <input ref={fileRef} type="file" accept=".pdf" style={{ display: 'none' }} onChange={handleFile} />
          <Icon name="upload" size={24} />
          {file ? (
            <div style={{ marginTop: 10 }}>
              <div style={{ fontWeight: 600, fontSize: 14 }}>{file.name}</div>
              <div style={{ fontSize: 12, color: 'var(--text-muted)', marginTop: 4 }}>
                {loading ? 'A processar PDF...' : transactions.length > 0 ? `${transactions.length} transações · ${expenseCount} despesas` : 'Nenhuma transação encontrada'}
              </div>
            </div>
          ) : (
            <div style={{ marginTop: 10 }}>
              <div style={{ fontWeight: 500, fontSize: 14 }}>Arrasta o extrato Revolut aqui</div>
              <div style={{ fontSize: 12, color: 'var(--text-muted)', marginTop: 4 }}>ou clica para seleccionar o ficheiro PDF</div>
            </div>
          )}
        </div>

        {/* Action bar */}
        {transactions.length > 0 && (
          <div style={{ display: 'flex', alignItems: 'center', gap: 12, marginBottom: 20 }}>
            <button className="btn btn-primary" onClick={runSearch} disabled={loading} style={{ display: 'flex', alignItems: 'center', gap: 8 }}>
              {loading ? <><Icon name="loader" size={14} /> A pesquisar...</> : <><Icon name="search" size={14} /> Pesquisar faturas</>}
            </button>
            {stats && (
              <div style={{ fontSize: 13, color: 'var(--text-muted)' }}>
                <span style={{ fontWeight: 600, color: 'var(--text)' }}>{stats.matched}</span> de {stats.total} transações com match ({stats.pct}%)
              </div>
            )}
          </div>
        )}

        {/* Invoice number search */}
        <div className="card" style={{ padding: '12px 16px', marginBottom: 20, display: 'flex', flexDirection: 'column', gap: 10 }}>
          <div style={{ fontSize: 12, fontWeight: 600, color: 'var(--text-muted)', textTransform: 'uppercase', letterSpacing: '0.06em' }}>Pesquisa por fornecedor / destinatário</div>
          <div style={{ display: 'flex', gap: 8 }}>
            <input
              className="input"
              placeholder="ex: Apollo, LinkedIn, Amazon, Revolut..."
              value={invoiceQuery}
              onChange={e => setInvoiceQuery(e.target.value)}
              onKeyDown={e => e.key === 'Enter' && searchInvoice()}
              style={{ flex: 1 }}
            />
            <button className="btn btn-primary btn-sm" onClick={searchInvoice} disabled={invoiceLoading} style={{ display: 'flex', alignItems: 'center', gap: 6, whiteSpace: 'nowrap' }}>
              <Icon name={invoiceLoading ? 'loader' : 'search'} size={13} />
              {invoiceLoading ? 'A pesquisar...' : 'Pesquisar fatura'}
            </button>
          </div>
          {invoiceError && (
            <div style={{ fontSize: 12, color: 'var(--red, #ef4444)' }}>{invoiceError}</div>
          )}
          {invoiceResults !== null && invoiceResults.length === 0 && (
            <div style={{ fontSize: 12, color: 'var(--text-muted)' }}>Nenhum email encontrado com esse número nas caixas configuradas.</div>
          )}
          {invoiceResults && invoiceResults.length > 0 && (
            <div style={{ display: 'flex', flexDirection: 'column', gap: 0 }}>
              <div style={{ fontSize: 11, color: 'var(--text-muted)', marginBottom: 6 }}>{invoiceResults.length} resultado{invoiceResults.length > 1 ? 's' : ''}</div>
              {invoiceResults.map((m, i) => <MatchRow key={i} match={m} />)}
            </div>
          )}
        </div>

        {error && (
          <div className="card" style={{ padding: '12px 16px', marginBottom: 16, background: 'color-mix(in oklch, var(--red, #ef4444) 8%, var(--bg))', border: '1px solid color-mix(in oklch, var(--red, #ef4444) 30%, transparent)', color: 'var(--red, #ef4444)', fontSize: 13 }}>
            {error}
          </div>
        )}

        {/* Results */}
        {results.length > 0 && [...results].sort((a, b) => (b.matches[0]?.score || 0) - (a.matches[0]?.score || 0)).map((result, i) => (
          <TransactionRow key={i} result={result} />
        ))}

        {/* Empty state before search */}
        {transactions.length > 0 && results.length === 0 && !loading && (
          <div style={{ textAlign: 'center', padding: '40px 0', color: 'var(--text-muted)', fontSize: 13 }}>
            Clica em "Pesquisar faturas" para iniciar a reconciliação.
          </div>
        )}
      </div>
    );
  };

  window.FinanceReconciliacaoScreen = FinanceReconciliacaoScreen;
})();
