/* global React, API, useApp */
const { useState, useEffect, useCallback } = 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') : '—';
const today   = () => new Date().toISOString().split('T')[0];
const addDays = (d, n) => { const dt = new Date(d); dt.setDate(dt.getDate()+n); return dt.toISOString().split('T')[0]; };
const newLine = () => ({ _key: Math.random(), description:'', quantity:1, unit_price:0, vat_rate:0.21, subtotal:0 });

function calcLine(l) { return { ...l, subtotal: Number(l.quantity) * Number(l.unit_price) }; }
function calcTotals(lines) {
  const subtotal   = lines.reduce((s, l) => s + l.subtotal, 0);
  const vat_amount = lines.reduce((s, l) => s + l.subtotal * Number(l.vat_rate), 0);
  return { subtotal, vat_amount, total: subtotal + vat_amount };
}

function InvoiceModal({ invoice, companies, onSave, onClose }) {
  const isNew = !invoice?.id;
  const [form, setForm] = useState({
    customer_id: invoice?.customer_id || '',
    invoice_date: invoice?.invoice_date || today(),
    due_date: invoice?.due_date || addDays(today(), 30),
    notes: invoice?.notes || '',
    currency: invoice?.currency || 'EUR',
  });
  const [lines, setLines] = useState(invoice?.lines?.length ? invoice.lines : [newLine()]);
  const [rate, setRate]   = useState(null);
  const [busy, setBusy]   = useState(false);
  const { toast } = useApp();

  useEffect(() => {
    if (form.customer_id) {
      API.get(`/companies/${form.customer_id}/rate`).then(r => {
        setRate(r);
        if (isNew) {
          setLines(l => l.map(line => ({ ...line, vat_rate: r.default_vat_rate || 0.21 })));
        }
      }).catch(() => {});
    }
  }, [form.customer_id]);

  const co = companies.find(c => c.id === form.customer_id);
  const f  = k => e => setForm(p => ({ ...p, [k]: e.target.value }));

  function updateLine(idx, k, v) {
    setLines(ls => ls.map((l, i) => i === idx ? calcLine({ ...l, [k]: v }) : l));
  }
  const { subtotal, vat_amount, total } = calcTotals(lines);

  async function save(status) {
    setBusy(true);
    try {
      const body = { ...form, lines, subtotal, vat_amount, total, status };
      const inv = invoice?.id
        ? await API.put(`/outbound/${invoice.id}`, body)
        : await API.post('/outbound', body);
      toast(isNew ? 'Invoice created' : 'Invoice updated');
      onSave(inv);
    } catch (e) { toast(e.error || 'Error', 'error'); }
    finally { setBusy(false); }
  }

  async function loadTime() {
    if (!form.customer_id) { toast('Select a customer first', 'error'); return; }
    const entries = await API.get(`/time?company_id=${form.customer_id}&uninvoiced=1`).catch(() => []);
    if (!entries.length) { toast('No uninvoiced time entries', 'error'); return; }
    const newLines = entries.map(e => calcLine({ _key: Math.random(), description: e.description || 'Advisory services', quantity: +(e.duration_minutes/60).toFixed(2), unit_price: rate?.hourly_rate || 0, vat_rate: rate?.default_vat_rate || 0.21, subtotal: 0 }));
    setLines(l => [...l.filter(x => x.description || x.unit_price), ...newLines]);
    toast(`${entries.length} time entr${entries.length===1?'y':'ies'} loaded`);
  }

  return (
    <div className="modal-overlay" onClick={e => e.target === e.currentTarget && onClose()}>
      <div className="modal modal--lg">
        <div className="modal-head">
          <span className="modal-title">{isNew ? 'New invoice' : `Edit ${invoice.invoice_number}`}</span>
          <button className="modal-close" onClick={onClose}>×</button>
        </div>
        <div className="modal-body">
          <div className="form-grid" style={{marginBottom:20}}>
            <div className="field field--full">
              <label className="field-label">Customer *</label>
              <select className="field-select" required value={form.customer_id} onChange={f('customer_id')}>
                <option value="">— select —</option>
                {companies.filter(c => c.type !== 'supplier').map(c => <option key={c.id} value={c.id}>{c.name}</option>)}
              </select>
            </div>
            <div className="field">
              <label className="field-label">Invoice date</label>
              <input className="field-input" type="date" value={form.invoice_date} onChange={e => { setForm(p => ({ ...p, invoice_date: e.target.value, due_date: addDays(e.target.value, co?.payment_terms_days || 30) })); }} />
            </div>
            <div className="field">
              <label className="field-label">Due date</label>
              <input className="field-input" type="date" value={form.due_date} onChange={f('due_date')} />
            </div>
          </div>

          <div style={{display:'flex',alignItems:'center',justifyContent:'space-between',marginBottom:8}}>
            <span className="field-label">Line items</span>
            <div style={{display:'flex',gap:8}}>
              <button type="button" className="btn btn--ghost btn--sm" onClick={loadTime}>↓ Load time</button>
              <button type="button" className="btn btn--ghost btn--sm" onClick={() => setLines(l => [...l, newLine()])}>+ Line</button>
            </div>
          </div>

          <div className="line-items">
            <div className="line-item line-item-head">
              <div className="li-cell">Description</div>
              <div className="li-cell">Qty</div>
              <div className="li-cell">Unit price</div>
              <div className="li-cell">VAT</div>
              <div className="li-cell"></div>
            </div>
            {lines.map((l, idx) => (
              <div key={l._key || idx} className="line-item">
                <div className="li-cell"><input className="li-input" placeholder="Description" value={l.description} onChange={e => updateLine(idx, 'description', e.target.value)} /></div>
                <div className="li-cell"><input className="li-input mono" type="number" step="0.01" value={l.quantity} onChange={e => updateLine(idx, 'quantity', e.target.value)} /></div>
                <div className="li-cell"><input className="li-input mono" type="number" step="0.01" value={l.unit_price} onChange={e => updateLine(idx, 'unit_price', e.target.value)} /></div>
                <div className="li-cell">
                  <select className="li-input mono" value={l.vat_rate} onChange={e => updateLine(idx, 'vat_rate', e.target.value)} style={{fontSize:11}}>
                    <option value="0.21">21%</option>
                    <option value="0.09">9%</option>
                    <option value="0.00">0%</option>
                  </select>
                </div>
                <div className="li-cell"><span className="li-del" onClick={() => setLines(ls => ls.filter((_,i) => i!==idx))}>×</span></div>
              </div>
            ))}
            <div className="line-totals">
              <div className="line-total-row"><span className="label">Subtotal</span><span>{fmtEur(subtotal)}</span></div>
              <div className="line-total-row"><span className="label">VAT</span><span>{fmtEur(vat_amount)}</span></div>
              <div className="line-total-row grand"><span className="label">Total</span><span>{fmtEur(total)}</span></div>
            </div>
          </div>

          <div className="field" style={{marginTop:16}}>
            <label className="field-label">Notes (printed on invoice)</label>
            <textarea className="field-textarea" rows={2} value={form.notes} onChange={f('notes')} />
          </div>
        </div>
        <div className="modal-foot">
          <button type="button" className="btn btn--ghost" onClick={onClose}>Cancel</button>
          <button type="button" className="btn btn--ghost" disabled={busy || !form.customer_id} onClick={() => save('draft')}>{busy?'Saving…':'Save draft'}</button>
          <button type="button" className="btn btn--primary" disabled={busy || !form.customer_id} onClick={() => save('draft')}>{isNew ? 'Create invoice' : 'Save'}</button>
        </div>
      </div>
    </div>
  );
}

function OutboundInvoices() {
  const [invoices, setInvoices]   = useState([]);
  const [companies, setCompanies] = useState([]);
  const [filter, setFilter]       = useState('all');
  const [modal, setModal]         = useState(null);
  const [detail, setDetail]       = useState(null);
  const { toast } = useApp();

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

  useEffect(() => {
    load();
    API.get('/companies').then(setCompanies).catch(() => {});
  }, [load]);

  async function send(inv) {
    if (!confirm(`Send invoice ${inv.invoice_number} to the customer?`)) return;
    try {
      await API.post(`/outbound/${inv.id}/send`, {});
      toast(`Invoice ${inv.invoice_number} sent`);
      load();
    } catch (e) { toast(e.error || 'Send failed', 'error'); }
  }

  async function markPaid(inv) {
    await API.put(`/outbound/${inv.id}`, { status: 'paid', paid_at: new Date().toISOString() }).catch(e => toast(e.error || 'Error', 'error'));
    toast('Marked as paid'); load();
  }

  async function del(inv) {
    if (!confirm(`Delete invoice ${inv.invoice_number}?`)) return;
    await API.del(`/outbound/${inv.id}`).catch(e => toast(e.error || 'Error', 'error'));
    toast('Invoice deleted'); load();
  }

  const visible = invoices.filter(i => filter === 'all' || i.status === filter);
  const coMap   = Object.fromEntries(companies.map(c => [c.id, c.name]));

  return (
    <div className="page">
      <div className="page-header">
        <div>
          <h1 className="page-title">Invoices — outbound</h1>
          <div className="page-subtitle">Customer invoices and payment tracking</div>
        </div>
        <div className="page-actions">
          <button className="btn btn--primary" onClick={() => setModal({})}>+ New invoice</button>
        </div>
      </div>

      <div className="tabs">
        {[['all','All'],['draft','Draft'],['sent','Sent'],['paid','Paid'],['overdue','Overdue']].map(([v,l]) => (
          <button key={v} className={`tab ${filter===v?'is-active':''}`} onClick={() => setFilter(v)}>{l}</button>
        ))}
      </div>

      <div className="card" style={{margin:0}}>
        <div className="table-wrap">
          <table className="data-table" style={{padding:'0 20px'}}>
            <thead><tr><th>Invoice #</th><th>Customer</th><th>Date</th><th>Due</th><th>Total</th><th>Status</th><th></th></tr></thead>
            <tbody>
              {visible.length === 0 && <tr><td colSpan={7}><div className="empty-state">No invoices</div></td></tr>}
              {visible.map(inv => (
                <tr key={inv.id} style={{cursor:'pointer'}} onClick={() => setDetail(inv === detail ? null : inv)}>
                  <td className="mono">{inv.invoice_number}</td>
                  <td>{coMap[inv.customer_id] || inv.customer_name || '—'}</td>
                  <td className="mono">{fmtDate(inv.invoice_date)}</td>
                  <td className="mono" style={inv.status==='overdue'?{color:'var(--status-negative)'}:{}}>{fmtDate(inv.due_date)}</td>
                  <td className="mono">{fmtEur(inv.total)}</td>
                  <td><span className={`status status--${inv.status}`}>{inv.status}</span></td>
                  <td>
                    <div className="row-actions" onClick={e => e.stopPropagation()}>
                      <a className="btn btn--ghost btn--sm" href={`/api/outbound/${inv.id}/print`} target="_blank">Print</a>
                      {inv.status === 'draft' && <button className="btn btn--primary btn--sm" onClick={() => send(inv)}>Send</button>}
                      {inv.status === 'sent'  && <button className="btn btn--ghost btn--sm" onClick={() => markPaid(inv)}>Mark paid</button>}
                      {inv.status === 'draft' && <button className="btn btn--ghost btn--sm" onClick={e => { e.stopPropagation(); setModal(inv); }}>Edit</button>}
                      {(inv.status === 'draft') && <button className="btn btn--danger btn--sm" onClick={() => del(inv)}>Del</button>}
                    </div>
                  </td>
                </tr>
              ))}
            </tbody>
          </table>
        </div>
      </div>

      {modal !== null && (
        <InvoiceModal
          invoice={modal.id ? modal : null}
          companies={companies}
          onSave={inv => { load(); setModal(null); }}
          onClose={() => setModal(null)}
        />
      )}
    </div>
  );
}
window.OutboundInvoices = OutboundInvoices;
