/* global React, API, useApp */
const { useState, useEffect, useCallback, useRef } = React;

const fmtEur  = v => v == null ? '—' : `€${Number(v).toLocaleString('nl-NL',{minimumFractionDigits:2,maximumFractionDigits:2})}`;
const fmtDate = v => v ? new Date(v).toLocaleDateString('nl-NL') : '—';

function LinkModal({ txn, onSave, onClose }) {
  const [invoices, setInvoices] = useState([]);
  const [inbound, setInbound]   = useState([]);
  const [sel, setSel]           = useState({ invoice: txn.matched_invoice_id||'', inbound: txn.matched_inbound_id||'' });
  const [busy, setBusy] = useState(false);
  const { toast } = useApp();

  useEffect(() => {
    API.get('/outbound').then(d => setInvoices(d.filter(i => i.status !== 'draft'))).catch(()=>{});
    API.get('/inbound').then(setInbound).catch(()=>{});
  }, []);

  async function save() {
    setBusy(true);
    try {
      await API.put(`/bank/${txn.id}`, {
        matched_invoice_id: sel.invoice || null,
        matched_inbound_id: sel.inbound || null,
        reconciled: 1,
      });
      toast('Transaction reconciled');
      onSave();
    } catch (e) { toast(e.error || 'Error', 'error'); }
    finally { setBusy(false); }
  }

  return (
    <div className="modal-overlay" onClick={e => e.target === e.currentTarget && onClose()}>
      <div className="modal">
        <div className="modal-head">
          <span className="modal-title">Reconcile · {fmtEur(txn.amount)} on {fmtDate(txn.txn_date)}</span>
          <button className="modal-close" onClick={onClose}>×</button>
        </div>
        <div className="modal-body">
          <p style={{fontSize:12,color:'var(--fg-subtle)',marginBottom:16,fontFamily:'var(--font-mono)'}}>{txn.description}</p>
          <div className="form-grid">
            <div className="field field--full">
              <label className="field-label">Outbound invoice (payment received)</label>
              <select className="field-select" value={sel.invoice} onChange={e => setSel(p => ({...p, invoice: e.target.value}))}>
                <option value="">— none —</option>
                {invoices.map(i => <option key={i.id} value={i.id}>{i.invoice_number} · {i.customer_name} · {fmtEur(i.total)}</option>)}
              </select>
            </div>
            <div className="field field--full">
              <label className="field-label">Inbound invoice / cost (payment made)</label>
              <select className="field-select" value={sel.inbound} onChange={e => setSel(p => ({...p, inbound: e.target.value}))}>
                <option value="">— none —</option>
                {inbound.map(i => <option key={i.id} value={i.id}>{i.invoice_number||i.id.slice(0,8)} · {i.supplier_name||'—'} · {fmtEur(i.total||i.amount_eur)}</option>)}
              </select>
            </div>
          </div>
        </div>
        <div className="modal-foot">
          <button className="btn btn--ghost" onClick={onClose}>Cancel</button>
          <button className="btn btn--primary" onClick={save} disabled={busy || (!sel.invoice && !sel.inbound)}>Reconcile</button>
        </div>
      </div>
    </div>
  );
}

function BankReconcile() {
  const [txns, setTxns]       = useState([]);
  const [filter, setFilter]   = useState('all');
  const [modal, setModal]     = useState(null);
  const [importing, setImporting] = useState(false);
  const fileRef = useRef(null);
  const { toast } = useApp();

  const load = useCallback(() => {
    API.get('/bank').then(setTxns).catch(()=>{});
  }, []);

  useEffect(() => { load(); }, [load]);

  async function importCSV(file) {
    if (!file) return;
    setImporting(true);
    try {
      const fd = new FormData(); fd.append('file', file);
      const res = await fetch('/api/bank', { method:'POST', body:fd });
      const data = await res.json();
      if (!res.ok) throw data;
      toast(`Imported ${data.inserted} transactions (${data.skipped} skipped)`);
      load();
    } catch (e) { toast(e.error || 'Import failed', 'error'); }
    finally { setImporting(false); if(fileRef.current) fileRef.current.value=''; }
  }

  async function unreconcile(txn) {
    await API.put(`/bank/${txn.id}`, { matched_invoice_id: null, matched_inbound_id: null, reconciled: 0 })
      .catch(e => toast(e.error||'Error','error'));
    toast('Unlinked');
    load();
  }

  async function del(txn) {
    if (!confirm('Delete this transaction?')) return;
    await API.del(`/bank/${txn.id}`).catch(()=>{});
    load();
  }

  const visible = txns.filter(t =>
    filter === 'all' ||
    (filter === 'open' && !t.reconciled) ||
    (filter === 'reconciled' && t.reconciled)
  );

  const openCount  = txns.filter(t => !t.reconciled).length;
  const totalIn    = txns.filter(t => t.amount > 0).reduce((s,t) => s+t.amount, 0);
  const totalOut   = txns.filter(t => t.amount < 0).reduce((s,t) => s+t.amount, 0);

  return (
    <div className="page">
      <div className="page-header">
        <div>
          <h1 className="page-title">Bank reconciliation</h1>
          <div className="page-subtitle">Import bank statements · match transactions to invoices</div>
        </div>
        <div className="page-actions">
          <input ref={fileRef} type="file" accept=".csv,.txt" style={{display:'none'}}
            onChange={e => importCSV(e.target.files[0])} />
          <button className="btn btn--primary" disabled={importing}
            onClick={() => fileRef.current?.click()}>
            {importing ? 'Importing…' : '↑ Import CSV'}
          </button>
        </div>
      </div>

      <div style={{display:'flex',gap:1,background:'var(--border)',border:'1px solid var(--border)',marginBottom:24}}>
        {[
          ['Unmatched', openCount, openCount > 0 ? 'danger' : ''],
          ['Total in', fmtEur(totalIn), 'signal'],
          ['Total out', fmtEur(Math.abs(totalOut)), ''],
          ['Transactions', txns.length, ''],
        ].map(([l,v,cls]) => (
          <div key={l} className="stat-cell" style={{flex:1}}>
            <div className="stat-label">{l}</div>
            <div className={`stat-value${cls?' '+cls:''}`}>{v}</div>
          </div>
        ))}
      </div>

      <div className="tabs" style={{marginBottom:16}}>
        {[['all','All'],['open','Unmatched'],['reconciled','Reconciled']].map(([v,l]) => (
          <button key={v} className={`tab ${filter===v?'is-active':''}`} onClick={() => setFilter(v)}>
            {l}{v==='open'&&openCount>0?` (${openCount})`:''}</button>
        ))}
      </div>

      <div className="card" style={{margin:0}}>
        <div className="table-wrap">
          <table className="data-table">
            <thead><tr><th>Date</th><th>Description</th><th>Counterparty</th><th>Amount</th><th>Matched to</th><th></th></tr></thead>
            <tbody>
              {visible.length === 0 && (
                <tr><td colSpan={6}><div className="empty-state">
                  {txns.length === 0 ? 'No transactions yet — import a CSV bank statement to get started' : 'No transactions in this filter'}
                </div></td></tr>
              )}
              {visible.map(txn => (
                <tr key={txn.id} style={{opacity: txn.reconciled ? 0.6 : 1}}>
                  <td className="mono" style={{whiteSpace:'nowrap'}}>{fmtDate(txn.txn_date)}</td>
                  <td style={{maxWidth:260,overflow:'hidden',textOverflow:'ellipsis',whiteSpace:'nowrap',fontSize:12}}>{txn.description}</td>
                  <td style={{fontSize:11,color:'var(--fg-subtle)'}}>{txn.counterparty||'—'}</td>
                  <td className="mono" style={{color: txn.amount >= 0 ? 'var(--signal)' : 'var(--ember)', fontWeight:600}}>
                    {txn.amount >= 0 ? '+' : ''}{fmtEur(txn.amount)}
                  </td>
                  <td style={{fontSize:11}}>
                    {txn.reconciled
                      ? <span style={{color:'var(--signal)'}}>
                          {txn.matched_out_num ? `↑ ${txn.matched_out_num} · ${txn.matched_out_customer||''}` :
                           txn.matched_in_num  ? `↓ ${txn.matched_in_num} · ${txn.matched_in_supplier||''}` : '✓ reconciled'}
                        </span>
                      : <span style={{color:'var(--fg-subtle)'}}>unmatched</span>}
                  </td>
                  <td>
                    <div className="row-actions">
                      {txn.reconciled
                        ? <button className="btn btn--ghost btn--sm" onClick={() => unreconcile(txn)}>Unlink</button>
                        : <button className="btn btn--primary btn--sm" onClick={() => setModal(txn)}>Match</button>}
                      <button className="btn btn--danger btn--sm" onClick={() => del(txn)}>Del</button>
                    </div>
                  </td>
                </tr>
              ))}
            </tbody>
          </table>
        </div>
      </div>

      {modal && (
        <LinkModal txn={modal} onSave={() => { load(); setModal(null); }} onClose={() => setModal(null)} />
      )}
    </div>
  );
}
window.BankReconcile = BankReconcile;
