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

const STATUS_META = {
  draft:    { label: 'Draft',    color: 'var(--fg-subtle)', bg: 'var(--night-elev-1)' },
  sent:     { label: 'Sent',     color: '#60a5fa', bg: 'rgba(37,99,235,0.12)' },
  accepted: { label: 'Accepted', color: 'var(--ok)', bg: 'rgba(5,150,105,0.12)' },
  rejected: { label: 'Rejected', color: 'var(--danger)', bg: 'rgba(220,38,38,0.10)' },
  expired:  { label: 'Expired',  color: 'var(--fg-subtle)', bg: 'var(--night-elev-1)' },
};

const EMPTY_LINE = { description: '', quantity: 1, unit_price: 0, vat_rate: 0.21, subtotal: 0 };
const VAT_RATE = 0.21;

function fmtEur(v) { return `€ ${Number(v||0).toLocaleString('nl-NL',{minimumFractionDigits:2,maximumFractionDigits:2})}`; }
function fmtDate(d) { return d ? new Date(d).toLocaleDateString('nl-NL',{day:'2-digit',month:'short',year:'numeric'}) : '—'; }
function fmtDateTime(d) { return d ? new Date(d).toLocaleString('nl-NL',{day:'2-digit',month:'short',year:'numeric',hour:'2-digit',minute:'2-digit'}) : '—'; }

function StatusBadge({ status }) {
  const m = STATUS_META[status] || STATUS_META.draft;
  return <span style={{ padding: '2px 8px', borderRadius: 3, fontSize: 11, fontWeight: 600, fontFamily: 'var(--font-mono)', color: m.color, background: m.bg }}>{m.label}</span>;
}

function LineEditor({ lines, onChange }) {
  function update(i, key, val) {
    const next = lines.map((l, idx) => {
      if (idx !== i) return l;
      const updated = { ...l, [key]: val };
      if (key === 'quantity' || key === 'unit_price') {
        updated.subtotal = (Number(updated.quantity) || 0) * (Number(updated.unit_price) || 0);
      }
      return updated;
    });
    onChange(next);
  }
  function addLine() { onChange([...lines, { ...EMPTY_LINE }]); }
  function removeLine(i) { onChange(lines.filter((_, idx) => idx !== i)); }

  const subtotal   = lines.reduce((s,l) => s + (Number(l.subtotal)||0), 0);
  const vat_amount = subtotal * VAT_RATE;
  const total      = subtotal + vat_amount;

  return (
    <div>
      <div style={{ display: 'grid', gridTemplateColumns: '1fr 60px 90px 32px', gap: '2px 8px', marginBottom: 6 }}>
        <span style={{ fontSize: 10, fontFamily: 'var(--font-mono)', color: 'var(--fg-subtle)', letterSpacing: '0.1em', textTransform: 'uppercase' }}>Description</span>
        <span style={{ fontSize: 10, fontFamily: 'var(--font-mono)', color: 'var(--fg-subtle)', letterSpacing: '0.1em', textTransform: 'uppercase' }}>Qty</span>
        <span style={{ fontSize: 10, fontFamily: 'var(--font-mono)', color: 'var(--fg-subtle)', letterSpacing: '0.1em', textTransform: 'uppercase' }}>Unit price</span>
        <span></span>
      </div>
      {lines.map((l, i) => (
        <div key={i} style={{ display: 'grid', gridTemplateColumns: '1fr 60px 90px 32px', gap: '4px 8px', marginBottom: 4 }}>
          <input className="field-input" value={l.description} onChange={e => update(i,'description',e.target.value)} placeholder="Description" />
          <input className="field-input" type="number" min="0" step="0.5" value={l.quantity} onChange={e => update(i,'quantity',e.target.value)} style={{ fontFamily: 'var(--font-mono)', textAlign: 'right' }} />
          <input className="field-input" type="number" min="0" step="0.01" value={l.unit_price} onChange={e => update(i,'unit_price',e.target.value)} style={{ fontFamily: 'var(--font-mono)', textAlign: 'right' }} />
          <button style={{ background: 'none', border: 'none', color: 'var(--fg-subtle)', cursor: 'pointer', fontSize: 14, paddingTop: 2 }} onClick={() => removeLine(i)}>×</button>
        </div>
      ))}
      <button className="btn btn--ghost btn--sm" onClick={addLine} style={{ marginTop: 4, marginBottom: 16 }}>+ Add line</button>
      <div style={{ borderTop: '1px solid var(--border)', paddingTop: 10, display: 'flex', flexDirection: 'column', alignItems: 'flex-end', gap: 4 }}>
        <div style={{ fontSize: 12, color: 'var(--fg-subtle)' }}>Subtotaal <span style={{ fontFamily: 'var(--font-mono)', marginLeft: 16, color: 'var(--fg-muted)' }}>{fmtEur(subtotal)}</span></div>
        <div style={{ fontSize: 12, color: 'var(--fg-subtle)' }}>BTW 21% <span style={{ fontFamily: 'var(--font-mono)', marginLeft: 16, color: 'var(--fg-muted)' }}>{fmtEur(vat_amount)}</span></div>
        <div style={{ fontSize: 14, fontWeight: 700, color: 'var(--signal)', fontFamily: 'var(--font-mono)' }}>{fmtEur(total)}</div>
      </div>
    </div>
  );
}

function ProposalModal({ companies, avSet, initial, onSave, onClose }) {
  const isEdit = !!initial?.id;
  const [form, setForm] = useState({
    company_id: initial?.company_id || '',
    title: initial?.title || '',
    intro: initial?.intro || '',
    valid_until: initial?.valid_until || '',
    notes: initial?.notes || '',
    lines: initial?.lines ? JSON.parse(initial.lines) : [{ ...EMPTY_LINE }],
  });
  const [busy, setBusy] = useState(false);
  const [error, setError] = useState('');

  const f = k => e => setForm(p => ({ ...p, [k]: e.target.value }));
  const noAV = form.company_id && !avSet.has(form.company_id);

  async function submit() {
    if (!form.company_id || !form.title.trim()) return setError('Company and title are required');
    setBusy(true); setError('');
    const lines = form.lines.map(l => ({ ...l, subtotal: (Number(l.quantity)||0) * (Number(l.unit_price)||0) }));
    const subtotal   = lines.reduce((s,l) => s + l.subtotal, 0);
    const vat_amount = subtotal * VAT_RATE;
    const total      = subtotal + vat_amount;
    try {
      const payload = { ...form, lines, subtotal, vat_amount, total, vat_rate: VAT_RATE };
      await onSave(payload, isEdit ? initial.id : null);
      onClose();
    } catch(ex) {
      setError(ex?.error || 'Something went wrong');
    } finally { setBusy(false); }
  }

  return (
    <div style={{ position: 'fixed', inset: 0, background: 'rgba(0,0,0,0.6)', zIndex: 100, display: 'flex', alignItems: 'center', justifyContent: 'center', padding: 20 }}>
      <div style={{ background: 'var(--canvas)', border: '1px solid var(--border)', borderRadius: 8, width: '100%', maxWidth: 680, maxHeight: '92vh', overflowY: 'auto' }}>
        <div style={{ padding: '16px 20px', borderBottom: '1px solid var(--border)', display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
          <span style={{ fontWeight: 600, fontSize: 15 }}>{isEdit ? 'Edit proposal' : 'New proposal'}</span>
          <button style={{ background: 'none', border: 'none', color: 'var(--fg-subtle)', cursor: 'pointer', fontSize: 20, lineHeight: 1 }} onClick={onClose}>×</button>
        </div>
        <div style={{ padding: '16px 20px' }}>
          {noAV && (
            <div style={{ padding: '10px 14px', background: 'rgba(245,158,11,0.08)', border: '1px solid rgba(245,158,11,0.3)', borderRadius: 4, fontSize: 12, color: 'rgb(245,158,11)', marginBottom: 14 }}>
              ⚠ This client has not yet accepted the Algemene Voorwaarden. Consider sending the portal link to complete legal onboarding first.
            </div>
          )}
          <div className="field">
            <label className="field-label">Company *</label>
            <select className="field-input" value={form.company_id} onChange={f('company_id')}>
              <option value="">— Select company —</option>
              {companies.map(c => <option key={c.id} value={c.id}>{c.name}</option>)}
            </select>
          </div>
          <div className="field">
            <label className="field-label">Proposal title *</label>
            <input className="field-input" value={form.title} onChange={f('title')} placeholder="e.g. Website redesign — Acme BV" />
          </div>
          <div className="field">
            <label className="field-label">Intro / context (optional)</label>
            <textarea className="field-input" rows={3} value={form.intro} onChange={f('intro')} placeholder="Brief context or personal message to include in the proposal" style={{ resize: 'vertical' }} />
          </div>
          <div className="field">
            <label className="field-label">Valid until</label>
            <input className="field-input" type="date" value={form.valid_until} onChange={f('valid_until')} style={{ maxWidth: 180 }} />
          </div>
          <div className="field">
            <label className="field-label">Line items</label>
            <LineEditor lines={form.lines} onChange={lines => setForm(p => ({...p, lines}))} />
          </div>
          <div className="field">
            <label className="field-label">Internal notes (not sent to client)</label>
            <textarea className="field-input" rows={2} value={form.notes} onChange={f('notes')} style={{ resize: 'vertical' }} />
          </div>
          {error && <div style={{ padding: '8px 12px', background: 'rgba(220,38,38,0.08)', border: '1px solid rgba(220,38,38,0.3)', borderRadius: 3, fontSize: 12, color: 'var(--danger)', marginTop: 8 }}>{error}</div>}
        </div>
        <div style={{ padding: '12px 20px', borderTop: '1px solid var(--border)', display: 'flex', justifyContent: 'flex-end', gap: 8 }}>
          <button className="btn btn--ghost" onClick={onClose}>Cancel</button>
          <button className="btn btn--primary" disabled={busy} onClick={submit}>{busy ? 'Saving…' : isEdit ? 'Save changes' : 'Create proposal'}</button>
        </div>
      </div>
    </div>
  );
}

function Proposals() {
  const { toast } = useApp();
  const [proposals, setProposals] = useState([]);
  const [companies, setCompanies] = useState([]);
  const [avSet, setAvSet]         = useState(new Set());
  const [loading, setLoading]     = useState(true);
  const [filter, setFilter]       = useState('all');
  const [modal, setModal]         = useState(null); // null | { mode: 'create'|'edit', initial }
  const [confirm, setConfirm]     = useState(null); // null | { type, proposal }
  const [busy, setBusy]           = useState(false);

  const load = useCallback(async () => {
    setLoading(true);
    const [ps, cs, avs] = await Promise.all([
      API.get('/proposals').catch(() => []),
      API.get('/companies').catch(() => []),
      API.get('/av').catch(() => []),
    ]);
    setProposals(ps || []);
    setCompanies(cs || []);
    setAvSet(new Set((avs || []).map(a => a.company_id)));
    setLoading(false);
  }, []);

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

  // Mark expired
  const now = new Date().toISOString().slice(0,10);
  const visible = (proposals || []).filter(p => {
    if (p.valid_until && p.valid_until < now && p.status === 'sent') p.status = 'expired';
    return filter === 'all' ? true : p.status === filter;
  });

  const counts = (proposals||[]).reduce((acc,p) => {
    const s = (p.valid_until && p.valid_until < now && p.status==='sent') ? 'expired' : p.status;
    acc[s] = (acc[s]||0) + 1;
    return acc;
  }, {});

  async function handleSave(payload, editId) {
    if (editId) {
      const updated = await API.put(`/proposals/${editId}`, payload);
      setProposals(prev => prev.map(p => p.id === editId ? { ...p, ...updated } : p));
      toast('Proposal updated');
    } else {
      const created = await API.post('/proposals', payload);
      setProposals(prev => [created, ...prev]);
      toast('Proposal created');
    }
  }

  async function handleSend(p) {
    setBusy(true);
    try {
      await API.post(`/proposals/${p.id}/send`, {});
      setProposals(prev => prev.map(x => x.id === p.id ? { ...x, status: 'sent', sent_at: new Date().toISOString() } : x));
      toast(`Sent to ${p.company_name}`);
    } catch(ex) {
      toast(ex?.error || 'Send failed', 'error');
    } finally { setBusy(false); setConfirm(null); }
  }

  async function handleDelete(p) {
    setBusy(true);
    try {
      await API.delete(`/proposals/${p.id}`);
      setProposals(prev => prev.filter(x => x.id !== p.id));
      toast('Proposal deleted');
    } catch(ex) {
      toast(ex?.error || 'Delete failed', 'error');
    } finally { setBusy(false); setConfirm(null); }
  }

  function downloadPDF(p) {
    window.open(`/api/proposals/${p.id}/pdf`, '_blank');
  }

  const FILTERS = ['all','draft','sent','accepted','rejected','expired'];

  return (
    <div className="page">
      <div className="page-header">
        <div>
          <h1 className="page-title">Proposals</h1>
          <div className="page-subtitle">Offertes · AV + BTW NL001170142B85 van toepassing</div>
        </div>
        <button className="btn btn--primary" onClick={() => setModal({ mode: 'create', initial: null })}>+ New proposal</button>
      </div>

      {/* Filters */}
      <div style={{ display: 'flex', gap: 2, marginBottom: 20, borderBottom: '1px solid var(--border)', paddingBottom: 0 }}>
        {FILTERS.map(f => (
          <button key={f} onClick={() => setFilter(f)} style={{
            background: 'none', border: 'none', cursor: 'pointer', padding: '8px 14px', fontSize: 12,
            fontFamily: 'var(--font-mono)', letterSpacing: '0.05em',
            color: filter === f ? 'var(--signal)' : 'var(--fg-subtle)',
            borderBottom: filter === f ? '2px solid var(--signal)' : '2px solid transparent',
            marginBottom: -1,
          }}>
            {f.charAt(0).toUpperCase() + f.slice(1)} {counts[f] ? `(${counts[f]})` : ''}
          </button>
        ))}
      </div>

      {loading ? (
        <div style={{ color: 'var(--fg-subtle)', padding: 24, fontSize: 13 }}>Loading…</div>
      ) : visible.length === 0 ? (
        <div className="card">
          <div style={{ padding: 32, textAlign: 'center' }}>
            <div style={{ fontSize: 14, fontWeight: 500, color: 'var(--fg)', marginBottom: 8 }}>
              {filter === 'all' ? 'No proposals yet' : `No ${filter} proposals`}
            </div>
            {filter === 'all' && (
              <div style={{ fontSize: 12, color: 'var(--fg-muted)' }}>Create a proposal and send it to a client via the portal.</div>
            )}
          </div>
        </div>
      ) : (
        <div className="card" style={{ margin: 0 }}>
          <div className="table-wrap">
            <table className="data-table">
              <thead>
                <tr>
                  <th>Number</th>
                  <th>Company</th>
                  <th>Title</th>
                  <th>Total</th>
                  <th>Valid until</th>
                  <th>Status</th>
                  <th>Sent / Accepted</th>
                  <th></th>
                </tr>
              </thead>
              <tbody>
                {visible.map(p => (
                  <tr key={p.id}>
                    <td className="mono" style={{ fontSize: 11, fontWeight: 600, color: 'var(--signal)' }}>{p.proposal_number}</td>
                    <td style={{ fontWeight: 500 }}>
                      {p.company_name}
                      {!avSet.has(p.company_id) && <span title="No AV accepted" style={{ marginLeft: 5, fontSize: 10, color: 'rgb(245,158,11)' }}>⚠</span>}
                    </td>
                    <td style={{ fontSize: 13, maxWidth: 220, overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>{p.title}</td>
                    <td className="mono" style={{ fontSize: 12, color: 'var(--signal)', fontWeight: 600 }}>{fmtEur(p.total)}</td>
                    <td className="mono" style={{ fontSize: 11, color: p.valid_until && p.valid_until < now ? 'var(--danger)' : 'var(--fg-muted)' }}>{p.valid_until || '—'}</td>
                    <td><StatusBadge status={p.status === 'sent' && p.valid_until && p.valid_until < now ? 'expired' : p.status} /></td>
                    <td className="mono" style={{ fontSize: 11, color: 'var(--fg-subtle)' }}>
                      {p.accepted_at ? fmtDate(p.accepted_at) : p.sent_at ? fmtDate(p.sent_at) : '—'}
                    </td>
                    <td>
                      <div style={{ display: 'flex', gap: 4 }}>
                        {(p.status === 'draft' || p.status === 'sent') && (
                          <button className="btn btn--ghost btn--sm" onClick={() => setModal({ mode: 'edit', initial: p })}>Edit</button>
                        )}
                        {(p.status === 'draft' || p.status === 'sent') && (
                          <button className="btn btn--primary btn--sm" onClick={() => setConfirm({ type: 'send', proposal: p })}>Send</button>
                        )}
                        <button className="btn btn--ghost btn--sm" onClick={() => downloadPDF(p)}>PDF</button>
                        {p.status === 'draft' && (
                          <button className="btn btn--ghost btn--sm" onClick={() => setConfirm({ type: 'delete', proposal: p })} style={{ color: 'var(--danger)' }}>Del</button>
                        )}
                      </div>
                    </td>
                  </tr>
                ))}
              </tbody>
            </table>
          </div>
          <div style={{ padding: '10px 20px', borderTop: '1px solid var(--border)', fontSize: 11, color: 'var(--fg-subtle)', fontFamily: 'var(--font-mono)', display: 'flex', gap: 16 }}>
            <span>{proposals.length} proposal{proposals.length===1?'':'s'} total</span>
            <span>⚠ = no AV on file</span>
          </div>
        </div>
      )}

      {modal && (
        <ProposalModal
          companies={companies}
          avSet={avSet}
          initial={modal.initial}
          onSave={handleSave}
          onClose={() => setModal(null)}
        />
      )}

      {confirm && (
        <div style={{ position: 'fixed', inset: 0, background: 'rgba(0,0,0,0.5)', zIndex: 100, display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
          <div style={{ background: 'var(--canvas)', border: '1px solid var(--border)', borderRadius: 8, padding: 24, maxWidth: 400, width: '100%', margin: 20 }}>
            {confirm.type === 'send' ? (
              <>
                <div style={{ fontWeight: 600, marginBottom: 8 }}>Send proposal?</div>
                <div style={{ fontSize: 13, color: 'var(--fg-muted)', marginBottom: 16, lineHeight: 1.6 }}>
                  This will email <strong>{confirm.proposal.proposal_number}</strong> to the primary contact at <strong>{confirm.proposal.company_name}</strong> with a PDF attachment and a portal link.
                </div>
                <div style={{ display: 'flex', gap: 8, justifyContent: 'flex-end' }}>
                  <button className="btn btn--ghost" onClick={() => setConfirm(null)}>Cancel</button>
                  <button className="btn btn--primary" disabled={busy} onClick={() => handleSend(confirm.proposal)}>{busy ? 'Sending…' : 'Send now'}</button>
                </div>
              </>
            ) : (
              <>
                <div style={{ fontWeight: 600, marginBottom: 8 }}>Delete draft?</div>
                <div style={{ fontSize: 13, color: 'var(--fg-muted)', marginBottom: 16 }}>This cannot be undone.</div>
                <div style={{ display: 'flex', gap: 8, justifyContent: 'flex-end' }}>
                  <button className="btn btn--ghost" onClick={() => setConfirm(null)}>Cancel</button>
                  <button className="btn btn--sm" disabled={busy} onClick={() => handleDelete(confirm.proposal)} style={{ background: 'var(--danger)', color: '#fff', border: 'none', borderRadius: 4, padding: '6px 14px', cursor: 'pointer' }}>{busy ? '…' : 'Delete'}</button>
                </div>
              </>
            )}
          </div>
        </div>
      )}
    </div>
  );
}
window.Proposals = Proposals;
