/* ============================================================
   ELECTROMED — Rental Management + Rental Workflow
   ============================================================ */

// Map DB field names to the old field names that helper functions expect
function normalizeRental(r) {
  return {
    ...r,
    no:          r.rental_number  || r.no,
    cust:        r.customer_name  || r.cust,
    from:        r.from_date      || r.from,
    to:          r.to_date        || r.to,
    due:         r.due_date       || r.due,
    periodStart: r.period_start   || r.periodStart,
    gst:         !!r.gst,
    lines:       r.lines          || [],
  };
}

function Rentals({ branch }) {
  const { PKR } = window.DATA;
  const [view, setView] = useState('Contracts');
  const [tab,  setTab]  = useState('All');
  const [q,    setQ]    = useState('');
  const [sel,  setSel]  = useState(null);
  const [wf,   setWf]   = useState(false);

  const bf = branch !== 'All' ? { branch_id: branch } : {};
  const { data: rawRentals, loading, error, refetch } = useRentals(bf);
  const rentals = rawRentals.map(normalizeRental);

  const list = rentals.filter((r) =>
    (tab === 'All' || r.status === tab) &&
    ((r.no   || '').toLowerCase().includes(q.toLowerCase()) ||
     (r.cust || '').toLowerCase().includes(q.toLowerCase()))
  );

  const active   = rentals.filter(r => r.status !== 'Closed');
  const deposits = active.reduce((s, r) => {
    const D = window.DATA;
    return s + (D.rentDeposit ? D.rentDeposit(r) : parseFloat(r.deposit || 0));
  }, 0);

  if (loading) return <div className="view-enter"><div className="card card-pad" style={{ textAlign: 'center', padding: 40 }}>Loading rentals…</div></div>;
  if (error)   return <div className="view-enter"><div className="card card-pad" style={{ color: 'var(--bad)' }}>Error: {error}</div></div>;

  return (
    <div className="view-enter">
      <PageHead eyebrow="03 · Rental Management" title="Rentals & Contracts"
        sub="Contracts, rate plans, deposits, payment reminders, returns and rent-fleet availability."
        actions={<>
          <div className="tabs">
            <button className={cls('tab', view === 'Contracts' && 'active')} onClick={() => setView('Contracts')}>Contracts</button>
            <button className={cls('tab', view === 'Fleet'     && 'active')} onClick={() => setView('Fleet')}>Rent Inventory</button>
          </div>
          {window.can('rentals','create') && <Btn variant="primary" icon={<Icons.plus size={16} stroke={2.6} />} onClick={() => setWf(true)}>New Rental</Btn>}
        </>} />

      {view === 'Fleet' ? <RentFleet branch={branch} /> : <>
        <div className="grid" style={{ gridTemplateColumns: 'repeat(4,1fr)', marginBottom: 20 }}>
          <StatCard icon={<Icons.rental size={18} />} label="Active Contracts"  value={active.length} sub={`${rentals.filter(r => r.status === 'Active').length} active`} />
          <StatCard icon={<Icons.clock  size={18} />} label="Due This Week"     value={rentals.filter(r => r.status === 'Due Soon' || r.status === 'Overdue').length} sub="needs action" />
          <StatCard icon={<Icons.bell   size={18} />} label="Overdue Returns"   value={rentals.filter(r => r.status === 'Overdue').length} accent />
          <StatCard icon={<Icons.shield size={18} />} label="Deposits Held"     value={PKR(deposits)} sub="refundable" />
        </div>

        <div className="card">
          <div className="card-pad row" style={{ justifyContent: 'space-between', gap: 14, flexWrap: 'wrap', paddingBottom: 14 }}>
            <Tabs tabs={['All', 'Active', 'Due Soon', 'Overdue', 'Closed']} value={tab} onChange={setTab} />
            <SearchBox value={q} onChange={setQ} placeholder="Contract or customer…" w={240} />
          </div>
          <div style={{ overflowX: 'auto' }}>
            <table className="tbl">
              <thead><tr>
                <th>Contract</th><th>Customer</th><th>Device</th><th>Plan / Rate</th><th>Period</th><th>Delivered by</th><th>Status</th>
              </tr></thead>
              <tbody>
                {list.map((r) => {
                  const D = window.DATA;
                  const machines = D.rentMachines ? D.rentMachines(r) : [];
                  const multi    = machines.length > 1;
                  const recurring = D.rentRecurring ? D.rentRecurring(r) : parseFloat(r.rate || 0);
                  return (
                    <tr key={r.id} style={{ cursor: 'pointer' }} onClick={() => setSel(r)}>
                      <td className="mono" style={{ fontWeight: 700 }}>{r.no}</td>
                      <td style={{ fontWeight: 600 }}>{r.cust}</td>
                      <td>
                        {multi
                          ? <><div style={{ fontWeight: 600 }}>{machines.length} machines</div><div className="tiny muted">{machines.slice(0, 2).map(m => m.cat).join(' · ')}{machines.length > 2 ? ' +' + (machines.length - 2) : ''}</div></>
                          : <><div style={{ fontWeight: 600 }}>{r.device}</div><div className="tiny muted mono">{r.serial}</div></>
                        }
                      </td>
                      <td><span style={{ fontWeight: 700 }} className="mono">{PKR(multi ? recurring : r.rate)}</span><div className="tiny muted">{r.plan}{multi ? ' · consolidated' : ''}</div></td>
                      <td className="tiny muted">{r.from}<br />→ {r.to}</td>
                      <td className="tiny"><div className="row" style={{ gap: 5 }}><Icons.truck size={13} style={{ color: 'var(--ink-3)' }} />{r.delivered}</div></td>
                      <td><Badge kind={window.statusKind(r.status)}>{r.status}</Badge></td>
                    </tr>
                  );
                })}
              </tbody>
            </table>
          </div>
          {!list.length && <div className="ph-img" style={{ height: 120, margin: 18 }}>no rentals match</div>}
        </div>

        {sel && <RentalDetail r={sel} onClose={() => { setSel(null); refetch(); }} onRefetch={refetch} />}
        {wf  && <RentalWorkflow onClose={() => { setWf(false); refetch(); }} />}
      </>}
      {wf && view === 'Fleet' && <RentalWorkflow onClose={() => { setWf(false); refetch(); }} />}
    </div>
  );
}

function RentFleet({ branch }) {
  const { PKR } = window.DATA;
  const { data: inventory, refetch: refetchInventory } = useInventory();
  const [addToFleet, setAddToFleet] = useState(false);

  const rentable = inventory.filter(i => i.rent_stock > 0 || i.rent_sys > 0);
  const totalUnits = rentable.reduce((s, i) => s + (parseInt(i.rent_sys) || 0), 0);
  const onField    = rentable.reduce((s, i) => s + Math.max(0, (parseInt(i.rent_sys) || 0) - (parseInt(i.rent_stock) || 0)), 0);
  const util = totalUnits > 0 ? Math.round(onField / totalUnits * 100) : 0;

  const StockMoveModal = window.StockMove;

  return (
    <div>
      <div className="grid" style={{ gridTemplateColumns: 'repeat(4,1fr)', marginBottom: 20 }}>
        <StatCard icon={<Icons.rental size={18} />} label="Fleet Units"     value={totalUnits} sub="rentable machines" />
        <StatCard icon={<Icons.truck  size={18} />} label="On Field"        value={onField}    sub="out with patients" />
        <StatCard icon={<Icons.box    size={18} />} label="Available Now"   value={totalUnits - onField} sub="ready to deploy" />
        <StatCard icon={<Icons.chart  size={18} />} label="Utilisation"     value={util + '%'} accent />
      </div>
      <div className="card">
        <div className="card-pad row" style={{ justifyContent: 'space-between', alignItems: 'center', paddingBottom: 6 }}>
          <div>
            <div style={{ fontWeight: 800, fontSize: 15 }}>Rental Fleet by Model</div>
            <div className="tiny muted" style={{ marginTop: 3 }}>Availability across all branches</div>
          </div>
          <Btn variant="ghost" sm icon={<Icons.swap size={15} />} onClick={() => setAddToFleet(true)}>Add to Fleet</Btn>
        </div>
        <div style={{ overflowX: 'auto' }}>
          <table className="tbl">
            <thead><tr><th>Device</th><th>Category</th><th>Monthly Rate</th><th>On Field</th><th>Available</th><th style={{ width: 200 }}>Utilisation</th></tr></thead>
            <tbody>
              {rentable.map((f) => {
                const total  = parseInt(f.rent_sys)   || 0;
                const avail  = parseInt(f.rent_stock) || 0;
                const onRent = Math.max(0, total - avail);
                const pct    = total > 0 ? Math.round(onRent / total * 100) : 0;
                return (
                  <tr key={f.id}>
                    <td style={{ fontWeight: 700 }}>{f.name}</td>
                    <td className="muted tiny">{f.category}</td>
                    <td className="mono" style={{ fontWeight: 700 }}>{PKR(f.rent_rate_monthly || f.rent_rate || 0)}<span className="tiny muted">/mo</span></td>
                    <td className="mono">{onRent} / {total}</td>
                    <td><Badge kind={avail === 0 ? 'bad' : avail <= 1 ? 'warn' : 'ok'}>{avail === 0 ? 'None free' : `${avail} free`}</Badge></td>
                    <td><div className="track" style={{ height: 7 }}><i style={{ width: pct + '%', background: pct >= 80 ? 'var(--warn)' : 'var(--grad-lime)' }} /></div><div className="tiny muted" style={{ marginTop: 4 }}>{pct}% on rent</div></td>
                  </tr>
                );
              })}
              {!rentable.length && <tr><td colSpan={6} className="muted tiny" style={{ textAlign: 'center', padding: 20 }}>No devices in the rental fleet yet. Use "Add to Fleet" to reclassify sale units.</td></tr>}
            </tbody>
          </table>
        </div>
      </div>
      {addToFleet && StockMoveModal && (
        <StockMoveModal initType="Reclassification" branch={branch} onClose={() => { setAddToFleet(false); refetchInventory(); }} />
      )}
    </div>
  );
}

// ── Rental payment period calculator ────────────────────────────
function calcExpectedPeriods(rental) {
  const start = new Date(rental.from_date || rental.from);
  if (!rental.from_date && !rental.from) return [];
  const today = new Date();
  const cycle = rental.plan || 'Monthly';
  const rate  = parseFloat(rental.rate) || 0;
  const periods = [];
  let ps = new Date(start);
  let n  = 1;
  while (ps <= today && n <= 120) {
    const pe = new Date(ps);
    if      (cycle === 'Daily')  pe.setDate(pe.getDate() + 1);
    else if (cycle === 'Weekly') pe.setDate(pe.getDate() + 7);
    else                         pe.setMonth(pe.getMonth() + 1);
    const fmt = (d) => d.toISOString().slice(0, 10);
    let label;
    if      (cycle === 'Daily')   label = `Day ${n} · ${fmt(ps)}`;
    else if (cycle === 'Weekly')  label = `Week ${n} · ${fmt(ps)}`;
    else { const mo = ps.toLocaleString('en-PK', { month: 'long', year: 'numeric' }); label = mo; }
    periods.push({ num: n, label, period_start: fmt(ps), period_end: fmt(pe), amount: rate });
    ps = new Date(pe);
    n++;
  }
  return periods;
}

function RentalDetail({ r, onClose, onRefetch }) {
  const D = window.DATA; const { PKR } = D;
  const lines     = D.rentLines     ? D.rentLines(r)     : (r.lines || []);
  const machines  = D.rentMachines  ? D.rentMachines(r)  : lines.filter(l => l.type === 'Machine');
  const multi     = machines.length > 1;
  const pooledDep = D.rentDeposit   ? D.rentDeposit(r)   : parseFloat(r.deposit  || 0);
  const recurring = D.rentRecurring ? D.rentRecurring(r)  : parseFloat(r.rate     || 0);
  const onRent    = machines.filter((m) => !m.returned).length;
  const per       = r.plan === 'Daily' ? 'day' : r.plan === 'Weekly' ? 'wk' : 'mo';

  const { data: pmts, refetch: refetchPmts } = useRentalPayments(r.id);
  const [collectFor,  setCollectFor]  = useState(null);
  const [detailTab,   setDetailTab]   = useState('ledger');
  const [showInv,     setShowInv]     = useState(false);
  const [confirmDel,  setConfirmDel]  = useState(false);

  const canDelete = ['Closed', 'Cancelled'].includes(r.status);

  // Merge expected periods with actual payments
  const expected  = calcExpectedPeriods(r);
  const rentPmts  = pmts.filter(p => p.type === 'Rent');
  const depPmt    = pmts.find(p   => p.type === 'Deposit');

  const ledger = expected.map(ep => {
    const pmt = rentPmts.find(p => p.period_num === ep.num);
    return {
      ...ep,
      status:     pmt ? pmt.status : (new Date(ep.period_end) < new Date() ? 'Overdue' : 'Pending'),
      paid:       pmt ? parseFloat(pmt.amount_paid) || 0 : 0,
      paid_on:    pmt ? pmt.payment_date : null,
      mode:       pmt ? pmt.mode : null,
      pmt_id:     pmt ? pmt.id   : null,
    };
  });

  const totalDue       = ledger.reduce((s, p) => s + p.amount, 0);
  const totalPaid      = ledger.reduce((s, p) => s + p.paid,   0);
  const outstanding    = totalDue - totalPaid;
  const overdueCount   = ledger.filter(p => p.status === 'Overdue').length;
  const depCollected   = !!depPmt || !!r.deposit_collected;

  const statusBadge = (s) => {
    if (s === 'Paid')    return <Badge kind="ok">Paid</Badge>;
    if (s === 'Partial') return <Badge kind="warn">Partial</Badge>;
    if (s === 'Overdue') return <Badge kind="bad">Overdue</Badge>;
    if (s === 'Waived')  return <Badge kind="idle">Waived</Badge>;
    return <Badge kind="idle">Pending</Badge>;
  };

  if (confirmDel) return (
    <ConfirmDeleteModal
      title="Delete Rental Agreement?"
      body={<>Permanently remove <strong>{r.no}</strong> for {r.cust}? This cannot be undone.</>}
      onCancel={() => setConfirmDel(false)}
      onConfirm={async () => {
        await api.deleteRental(r.id);
        window.toast('Rental deleted', 'ok');
        onRefetch?.();
        onClose();
      }}
    />
  );

  return (
    <Modal wide title={`Agreement ${r.no}`}
      sub={`${r.cust} · ${multi ? machines.length + ' machines' : r.device} · ${r.plan} billing`}
      onClose={onClose}
      foot={<>
        {canDelete && window.can('rentals','delete') && (
          <Btn variant="danger" icon={<Icons.trash size={15} />} onClick={() => setConfirmDel(true)}>Delete</Btn>
        )}
        <Btn variant="ghost" icon={<Icons.print size={16} />}
          onClick={() => window.printDocument && window.printDocument(document.getElementById('rental-doc-' + r.id))}>
          Print
        </Btn>
        <WaSendBtn docType="Sale Order" docId={r.id} />
        {r.status !== 'Closed' && (
          <Btn variant="primary" icon={<Icons.receipt size={16} />} onClick={() => setShowInv(true)}>
            Generate Invoice
          </Btn>
        )}
      </>}>

      {/* ── Summary stats ── */}
      <div className="grid" style={{ gridTemplateColumns: 'repeat(4,1fr)', gap: 10, marginBottom: 16 }}>
        {[
          ['Billing Cycle', r.plan || '—'],
          ['Recurring', PKR(recurring) + '/' + per],
          ['Total Collected', PKR(totalPaid)],
          ['Outstanding', PKR(outstanding)],
        ].map(([k, v]) => (
          <div key={k} style={{ background: 'var(--surface-2)', borderRadius: 12, padding: '11px 13px' }}>
            <div className="tiny muted" style={{ fontWeight: 700 }}>{k}</div>
            <div style={{ fontWeight: 800, marginTop: 3, fontSize: 15 }} className="mono">{v}</div>
          </div>
        ))}
      </div>

      {/* ── Overdue alert ── */}
      {overdueCount > 0 && (
        <div className="row" style={{ gap: 10, padding: '11px 14px', borderRadius: 11, background: 'var(--bad-bg)', marginBottom: 14 }}>
          <Icons.clock size={18} style={{ color: 'var(--bad)', flexShrink: 0 }} />
          <span style={{ fontWeight: 700, color: 'var(--bad)', fontSize: 13 }}>{overdueCount} payment{overdueCount > 1 ? 's' : ''} overdue — collect now to avoid penalty</span>
        </div>
      )}

      {/* ── Deposit row ── */}
      <div style={{ border: '1px solid var(--line)', borderRadius: 11, overflow: 'hidden', marginBottom: 14 }}>
        <div className="row" style={{ justifyContent: 'space-between', padding: '10px 16px', background: 'var(--surface-2)' }}>
          <div>
            <span style={{ fontWeight: 700, fontSize: 13 }}>Security Deposit</span>
            <span className="mono" style={{ marginLeft: 10, fontWeight: 800 }}>{PKR(pooledDep)}</span>
            <span className="tiny muted" style={{ marginLeft: 8 }}>refundable on return</span>
          </div>
          <div className="row" style={{ gap: 8 }}>
            {depCollected
              ? <><Badge kind="ok">Collected</Badge>{depPmt && <span className="tiny muted">{depPmt.payment_date} · {depPmt.mode}</span>}</>
              : <><Badge kind="warn">Pending</Badge>
                  <Btn variant="primary" sm icon={<Icons.check size={13} />}
                    onClick={() => setCollectFor({ type: 'Deposit', label: 'Security Deposit', amount_due: pooledDep })}>
                    Collect Deposit
                  </Btn>
                </>
            }
          </div>
        </div>
      </div>

      {/* ── Tabs ── */}
      <div className="tabs" style={{ marginBottom: 14, display: 'flex', gap: 4 }}>
        <button className={cls('tab', detailTab === 'ledger' && 'active')} onClick={() => setDetailTab('ledger')}>Payment Ledger</button>
        <button className={cls('tab', detailTab === 'items'  && 'active')} onClick={() => setDetailTab('items')}>Rented Items</button>
      </div>

      {/* ── Payment Ledger tab ── */}
      {detailTab === 'ledger' && (
        <div style={{ border: '1px solid var(--line)', borderRadius: 13, overflow: 'hidden' }}>
          <table className="tbl" style={{ fontSize: 13 }}>
            <thead>
              <tr>
                <th>#</th>
                <th>Period</th>
                <th style={{ textAlign: 'right' }}>Due</th>
                <th style={{ textAlign: 'right' }}>Paid</th>
                <th>Mode</th>
                <th>Date</th>
                <th>Status</th>
                <th></th>
              </tr>
            </thead>
            <tbody>
              {ledger.length === 0 && (
                <tr><td colSpan={8} className="tiny muted" style={{ textAlign: 'center', padding: 20 }}>
                  No billing periods yet — rental just started.
                </td></tr>
              )}
              {ledger.map((p) => (
                <tr key={p.num} style={{ background: p.status === 'Overdue' ? 'var(--bad-bg)' : undefined }}>
                  <td className="mono muted tiny">{p.num}</td>
                  <td style={{ fontWeight: 600 }}>{p.label}</td>
                  <td className="mono" style={{ textAlign: 'right' }}>{PKR(p.amount)}</td>
                  <td className="mono" style={{ textAlign: 'right', color: p.paid > 0 ? 'var(--ok)' : undefined }}>
                    {p.paid > 0 ? PKR(p.paid) : '—'}
                  </td>
                  <td className="tiny muted">{p.mode || '—'}</td>
                  <td className="tiny muted mono">{p.paid_on || '—'}</td>
                  <td>{statusBadge(p.status)}</td>
                  <td style={{ textAlign: 'right' }}>
                    {p.status !== 'Paid' && p.status !== 'Waived' && (
                      <Btn variant="primary" sm
                        onClick={() => setCollectFor({ type: 'Rent', period_num: p.num, label: p.label, amount_due: p.amount, pmt_id: p.pmt_id })}>
                        Collect
                      </Btn>
                    )}
                  </td>
                </tr>
              ))}
            </tbody>
          </table>
          {/* Ledger summary footer */}
          <div className="row" style={{ justifyContent: 'flex-end', padding: '10px 16px', background: 'var(--surface-2)', borderTop: '1px solid var(--line)', gap: 28 }}>
            <div className="tiny muted">Total due <span className="mono" style={{ fontWeight: 700, color: 'var(--ink)' }}>{PKR(totalDue)}</span></div>
            <div className="tiny muted">Collected <span className="mono" style={{ fontWeight: 700, color: 'var(--ok)' }}>{PKR(totalPaid)}</span></div>
            <div className="tiny muted">Outstanding <span className="mono" style={{ fontWeight: 700, color: outstanding > 0 ? 'var(--bad)' : 'var(--ok)' }}>{PKR(outstanding)}</span></div>
          </div>
        </div>
      )}

      {/* ── Rented Items tab ── */}
      {detailTab === 'items' && (
        <div id={'rental-doc-' + r.id} style={{ border: '1px solid var(--line)', borderRadius: 13, overflow: 'hidden' }}>
          <table className="tbl" style={{ fontSize: 13 }}>
            <thead><tr><th>Machine / Item</th><th>Serial</th><th style={{ textAlign: 'right' }}>Rate</th><th style={{ textAlign: 'right' }}>Deposit</th><th>Status</th></tr></thead>
            <tbody>
              {(lines.length ? lines : [{ device: r.device, cat: '', rate: r.rate, deposit: r.deposit }]).map((l, i) => (
                <tr key={i}>
                  <td style={{ fontWeight: 600 }}>{l.device}<div className="tiny muted">{l.cat}</div></td>
                  <td className="mono tiny muted">{l.serial || '—'}</td>
                  <td className="mono" style={{ textAlign: 'right', fontWeight: 700 }}>{PKR(l.rate)}<span className="tiny muted">/{per}</span></td>
                  <td className="mono tiny" style={{ textAlign: 'right' }}>{l.deposit ? PKR(l.deposit) : '—'}</td>
                  <td><Badge kind="info">On rent</Badge></td>
                </tr>
              ))}
            </tbody>
          </table>
        </div>
      )}

      {/* ── Collect Payment modal ── */}
      {collectFor && (
        <CollectPaymentModal
          rental={r}
          collectFor={collectFor}
          onClose={() => setCollectFor(null)}
          onSaved={() => { setCollectFor(null); refetchPmts(); if (onRefetch) onRefetch(); }}
        />
      )}

      {showInv && <RentalInvoice r={r} onClose={() => setShowInv(false)} />}
    </Modal>
  );
}

/* ── Collect Payment Modal ──────────────────────────────────── */
function CollectPaymentModal({ rental, collectFor, onClose, onSaved }) {
  const { PKR } = window.DATA;
  const today = new Date().toISOString().slice(0, 10);
  const [amount, setAmount]   = useState(String(collectFor.amount_due || ''));
  const [mode,   setMode]     = useState('Cash');
  const [ref,    setRef]      = useState('');
  const [date,   setDate]     = useState(today);
  const [notes,  setNotes]    = useState('');
  const [busy,   setBusy]     = useState(false);

  const num = (v) => parseFloat(String(v).replace(/[^0-9.]/g, '')) || 0;

  const save = async () => {
    if (!num(amount)) { window.toast && window.toast('Enter amount', 'warn'); return; }
    setBusy(true);
    try {
      const due  = parseFloat(collectFor.amount_due) || 0;
      const paid = num(amount);
      const status = paid >= due ? 'Paid' : paid > 0 ? 'Partial' : 'Pending';

      if (collectFor.pmt_id) {
        // Update existing partial payment
        await api.updateRentalPayment(collectFor.pmt_id, {
          amount_paid: paid, amount_due: due, mode, ref, payment_date: date, notes, status,
        });
      } else {
        await api.createRentalPayment({
          rental_id:    rental.id,
          type:         collectFor.type,
          period_num:   collectFor.period_num || null,
          period_label: collectFor.label,
          amount_due:   due,
          amount_paid:  paid,
          status,
          payment_date: date,
          mode,
          ref,
          notes,
        });
      }
      window.toast && window.toast(`${collectFor.type === 'Deposit' ? 'Deposit' : collectFor.label} — ${PKR(paid)} collected`, 'ok');
      onSaved();
    } catch (err) {
      window.toast && window.toast(err.message || 'Failed to save', 'error');
      setBusy(false);
    }
  };

  return (
    <Modal title="Collect Payment" sub={`${rental.no} · ${collectFor.label}`} onClose={onClose}
      foot={<>
        <Btn variant="ghost" onClick={onClose} disabled={busy}>Cancel</Btn>
        <Btn variant="primary" icon={<Icons.check size={16} />} onClick={save} disabled={busy}>
          {busy ? 'Saving…' : 'Record Payment'}
        </Btn>
      </>}>
      <div style={{ display: 'grid', gap: 14 }}>
        {/* Amount due banner */}
        <div className="row" style={{ justifyContent: 'space-between', padding: '10px 14px', background: 'var(--surface-2)', borderRadius: 11 }}>
          <span className="tiny" style={{ fontWeight: 700 }}>Amount Due</span>
          <span className="mono" style={{ fontWeight: 800, fontSize: 16 }}>{PKR(parseFloat(collectFor.amount_due) || 0)}</span>
        </div>

        <div className="grid" style={{ gridTemplateColumns: '1fr 1fr', gap: 12 }}>
          <label className="fld"><span>Amount Collected (Rs)</span>
            <input className="input-block mono" value={amount}
              onChange={e => setAmount(e.target.value.replace(/[^0-9.]/g, ''))}
              placeholder={String(collectFor.amount_due || 0)} />
          </label>
          <label className="fld"><span>Payment Date</span>
            <input type="date" className="input-block" value={date} onChange={e => setDate(e.target.value)} />
          </label>
        </div>

        <label className="fld"><span>Payment Mode</span>
          <div className="tabs" style={{ display: 'flex' }}>
            {['Cash', 'Bank Transfer', 'Cheque', 'Online'].map(m => (
              <button key={m} className={cls('tab', mode === m && 'active')} style={{ flex: 1 }} onClick={() => setMode(m)}>{m}</button>
            ))}
          </div>
        </label>

        <div className="grid" style={{ gridTemplateColumns: '1fr 1fr', gap: 12 }}>
          <label className="fld"><span>Reference / Receipt #</span>
            <input className="input-block mono" value={ref} onChange={e => setRef(e.target.value)} placeholder="Optional" />
          </label>
          <label className="fld"><span>Notes</span>
            <input className="input-block" value={notes} onChange={e => setNotes(e.target.value)} placeholder="Optional" />
          </label>
        </div>

        {/* Partial payment warning */}
        {num(amount) > 0 && num(amount) < (parseFloat(collectFor.amount_due) || 0) && (
          <div className="row" style={{ gap: 8, padding: '9px 13px', background: 'var(--warn-bg)', borderRadius: 10 }}>
            <Icons.clock size={15} style={{ color: 'var(--warn)', flexShrink: 0 }} />
            <span className="tiny" style={{ fontWeight: 600, color: 'var(--warn)' }}>
              Partial — {PKR((parseFloat(collectFor.amount_due) || 0) - num(amount))} will remain outstanding
            </span>
          </div>
        )}
      </div>
    </Modal>
  );
}

function RentalInvoice({ r, onClose }) {
  const D = window.DATA; const { PKR } = D;
  const { data: companies } = useCompanies();
  const defaultCo = { name: 'Electromed Corporation', color: 'var(--forest-2)', gstRate: 17, ntn: '—', strn: '—', letterhead: 'Respiratory & Sleep Care', addr: 'Karachi', phone: '', email: '', bank: '—' };
  const co    = companies.find((c) => c.id === (r.company || r.company_id || '')) || defaultCo;
  const inv   = D.rentInvoice ? D.rentInvoice(r) : { lines: [], subtotal: parseFloat(r.rate), tax: 0, total: parseFloat(r.rate), gstRate: 17, periodStart: r.periodStart, cycle: r.plan };
  const docRef = useRef(null);
  const invNo  = 'RINV-' + (r.no || '').replace('RNT-', '') + '-' + new Date().getMonth().toString().padStart(2, '0');
  const per    = (inv.cycle || r.plan) === 'Daily' ? 'day' : (inv.cycle || r.plan) === 'Weekly' ? 'wk' : 'mo';

  return (
    <Modal wide title={`Rental Invoice · ${r.no}`} sub={`${r.cust} · ${(inv.cycle || r.plan)} billing`} onClose={onClose}
      foot={<>
        <Btn variant="ghost" icon={<Icons.download size={16} />} onClick={() => window.printDocument && window.printDocument(docRef.current)}>Download PDF</Btn>
        <Btn variant="ghost" icon={<Icons.print   size={16} />} onClick={() => window.printDocument && window.printDocument(docRef.current)}>Print</Btn>
        <Btn variant="primary" icon={<Icons.bell size={16} />}>Send to Customer</Btn>
      </>}>
      <div ref={docRef} style={{ border: '1px solid var(--line)', borderRadius: 14, overflow: 'hidden' }}>
        <div style={{ padding: '18px 22px', background: co.color, color: '#fff', display: 'flex', justifyContent: 'space-between', alignItems: 'flex-start' }}>
          <div className="row" style={{ gap: 12 }}>
            <div style={{ width: 40, height: 40, borderRadius: 11, background: 'rgba(255,255,255,.12)', display: 'grid', placeItems: 'center', flexShrink: 0 }}>
              <svg width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="var(--lime)" strokeWidth="2.2" strokeLinecap="round" strokeLinejoin="round"><path d="M2 12h4l2-6 4 13 3-9 2 2h5" /></svg>
            </div>
            <div>
              <div style={{ fontWeight: 800, fontSize: 16 }}>{co.name}</div>
              <div className="tiny" style={{ color: 'rgba(255,255,255,.7)', marginTop: 2 }}>{co.letterhead}</div>
              <div className="tiny" style={{ color: 'rgba(255,255,255,.55)', marginTop: 6, lineHeight: 1.5 }}>{co.addr}<br />{co.phone} · {co.email}</div>
            </div>
          </div>
          <div style={{ textAlign: 'right' }}>
            <div style={{ fontWeight: 800, fontSize: 18, letterSpacing: '.04em' }}>{r.gst ? 'RENTAL TAX INVOICE' : 'RENTAL INVOICE'}</div>
            <div className="tiny mono" style={{ color: 'rgba(255,255,255,.8)', marginTop: 4 }}>{invNo}</div>
            <div className="tiny" style={{ color: 'rgba(255,255,255,.55)', marginTop: 6 }}>Agreement {r.no} · {inv.cycle || r.plan}</div>
          </div>
        </div>

        <div style={{ padding: '16px 22px', display: 'flex', justifyContent: 'space-between', gap: 18, flexWrap: 'wrap', borderBottom: '1px solid var(--line)' }}>
          <div>
            <div className="tiny muted" style={{ fontWeight: 700, marginBottom: 4 }}>BILL TO</div>
            <div style={{ fontWeight: 700 }}>{r.cust}</div>
            <div className="tiny muted">Delivered by · {r.delivered}</div>
            <div className="tiny muted">Billing period from {inv.periodStart}</div>
          </div>
          {r.gst && (
            <div style={{ textAlign: 'right' }}>
              <div className="tiny muted" style={{ fontWeight: 700, marginBottom: 4 }}>SELLER TAX</div>
              <div className="tiny mono">NTN · {co.ntn}</div>
              {co.strn && <div className="tiny mono">STRN · {co.strn}</div>}
            </div>
          )}
        </div>

        <table className="tbl" style={{ fontSize: 13 }}>
          <thead><tr><th>Machine / Item</th><th>Serial</th><th>Basis</th><th style={{ textAlign: 'right' }}>Amount</th></tr></thead>
          <tbody>
            {(inv.lines || []).map((l, i) => (
              <tr key={i}>
                <td style={{ fontWeight: 600 }}>{l.qty ? `${l.qty}× ` : ''}{l.device}<div className="tiny muted">{l.cat}</div></td>
                <td className="mono tiny">{l.serial}</td>
                <td className={cls('tiny', l.prorated ? '' : 'muted')} style={l.prorated ? { color: 'var(--warn)', fontWeight: 700 } : {}}>{l.note}</td>
                <td className="mono" style={{ textAlign: 'right', fontWeight: 700 }}>{PKR(l.amount)}</td>
              </tr>
            ))}
          </tbody>
        </table>

        <div style={{ padding: '14px 22px', display: 'flex', justifyContent: 'flex-end' }}>
          <div style={{ width: 280 }}>
            <div className="row" style={{ justifyContent: 'space-between', padding: '6px 0' }}><span className="muted tiny">Subtotal</span><span className="mono" style={{ fontWeight: 600 }}>{PKR(inv.subtotal)}</span></div>
            {inv.tax > 0 && <div className="row" style={{ justifyContent: 'space-between', padding: '6px 0', borderBottom: '1px solid var(--line)' }}><span className="muted tiny">GST @ {inv.gstRate}%</span><span className="mono" style={{ fontWeight: 600 }}>{PKR(inv.tax)}</span></div>}
            <div className="row" style={{ justifyContent: 'space-between', padding: '10px 0 4px' }}><span style={{ fontWeight: 800 }}>Invoice Total</span><span className="mono" style={{ fontWeight: 800, fontSize: 16 }}>{PKR(inv.total)}</span></div>
            <div className="row" style={{ justifyContent: 'space-between', padding: '4px 0' }}><span className="muted tiny">Security deposit held</span><span className="mono tiny">{PKR(D.rentDeposit ? D.rentDeposit(r) : parseFloat(r.deposit || 0))}</span></div>
          </div>
        </div>

        <div className="tiny muted" style={{ padding: '12px 22px', borderTop: '1px solid var(--line)' }}>
          Recurring {(inv.cycle || r.plan).toLowerCase()} rental — one consolidated invoice covers all machines.
          {r.gst ? ' Tax invoice issued under the Sales Tax Act.' : ' Non-GST invoice.'}
          {co.bank ? ` Bank · ${co.bank}` : ''}
        </div>
      </div>
    </Modal>
  );
}

const RENT_STEPS = [
  { t: 'Rental Request',         d: 'Customer & machines needed' },
  { t: 'Cycle & Rates',          d: 'One billing cycle · per-machine rate & deposit' },
  { t: 'Machines Delivered',     d: 'Delivered-by & serials logged' },
  { t: 'Scheduler Tracking',     d: 'Renewal & return reminders' },
  { t: 'Agreement Activated',    d: 'One contract · consolidated invoice' },
];

function RentalWorkflow({ onClose }) {
  const D = window.DATA; const { PKR } = D;
  const { data: customers } = useCustomers();
  const { data: inventory } = useInventory();
  const [step,     setStep]     = useState(0);
  const [custId,   setCustId]   = useState('');
  const [cycle,    setCycle]    = useState('Monthly');
  const [fromDate, setFromDate] = useState(new Date().toISOString().slice(0, 10));
  const [toDate,   setToDate]   = useState('');
  const [busy,     setBusy]     = useState(false);

  // Catalog: inventory items that are in the rental fleet or are machine-category
  const allRentable = inventory.filter(i =>
    (i.rent_sys || 0) > 0 ||
    (i.rent_stock || 0) > 0 ||
    (i.category || '').toLowerCase() === 'machine'
  );
  // Deduplicate by name (same machine may appear across branches)
  const seenNames = new Set();
  const catalog = allRentable.filter(i => {
    const k = i.name || i.sku;
    if (seenNames.has(k)) return false;
    seenNames.add(k);
    return true;
  });

  const getRateForCycle = (p, c) => {
    if (c === 'Daily')  return parseFloat(p.rent_rate_daily  || (p.rent_rate * 0.08) || 500);
    if (c === 'Weekly') return parseFloat(p.rent_rate_weekly || (p.rent_rate * 0.33) || 3500);
    return parseFloat(p.rent_rate_monthly || p.rent_rate || 15000);
  };
  const mkItem = (p, c) => ({
    device:  p.name || p.model,
    cat:     p.category || p.cat,
    rate:    getRateForCycle(p, c || cycle),
    deposit: parseFloat(p.rent_deposit || 50000),
    serial:  '',
  });
  const [lines, setLines] = useState([]);
  React.useEffect(() => { if (catalog.length && !lines.length) setLines([mkItem(catalog[0])]); }, [catalog.length]);

  const last   = step === RENT_STEPS.length - 1;

  const submit = async () => {
    setBusy(true);
    try {
      const cust = customers.find(c => c.id === custId);
      const today = new Date().toISOString().slice(0, 10);
      const rentNum = 'RNT-' + Date.now().toString().slice(-6);
      await api.createRental({
        rental_number: rentNum,
        customer_id:   custId || null,
        customer_name: cust ? cust.name : '',
        device:        (lines[0] && lines[0].device) || '—',
        plan:          cycle,
        rate:          recurring,
        deposit:       deposits,
        from_date:     fromDate || today,
        to_date:       toDate   || null,
        due_date:      toDate   || null,
        status:        'Active',
        lines:         lines,
        gst:           0,
      });
      window.toast(`Rental ${rentNum} activated`, 'ok');
      onClose();
    } catch (err) {
      window.toast(err.message || 'Failed to activate rental', 'error');
      setBusy(false);
    }
  };

  const patch  = (ix, p) => setLines(a => a.map((l, i) => i === ix ? { ...l, ...p } : l));
  const setDevice = (ix, name) => {
    const p = catalog.find(c => (c.name || c.model) === name);
    if (p) patch(ix, mkItem(p));
  };
  const remove = (ix) => setLines(a => a.filter((_, i) => i !== ix));
  const add    = ()   => { if (catalog.length) setLines(a => [...a, mkItem(catalog[0])]); };
  const recurring = lines.reduce((s, l) => s + (l.rate || 0), 0);
  const deposits  = lines.reduce((s, l) => s + (l.deposit || 0), 0);
  const per = cycle === 'Daily' ? 'day' : cycle === 'Weekly' ? 'wk' : 'mo';

  return (
    <Modal wide title="New Rental" sub="One agreement can hold several machines on the same billing cycle" onClose={onClose}
      foot={<>
        <Btn variant="ghost" onClick={step ? () => setStep(step - 1) : onClose}>{step ? 'Back' : 'Cancel'}</Btn>
        <Btn variant="primary" icon={last ? <Icons.check size={16} /> : <Icons.chevR size={16} />}
          onClick={last ? submit : () => setStep(step + 1)}
          disabled={!lines.length || busy}>{busy ? 'Saving…' : last ? 'Activate Agreement' : 'Continue'}</Btn>
      </>}>

      <div className="row" style={{ marginBottom: 22 }}>
        {RENT_STEPS.map((s, ix) => (
          <React.Fragment key={ix}>
            <div style={{ width: 30, height: 30, borderRadius: 50, display: 'grid', placeItems: 'center', fontWeight: 800, fontSize: 13, flexShrink: 0,
              background: ix < step ? 'var(--lime)' : ix === step ? 'var(--ink)' : 'var(--surface-3)',
              color: ix <= step ? (ix < step ? 'var(--forest-2)' : '#fff') : 'var(--ink-3)' }}>
              {ix < step ? <Icons.check size={16} stroke={3} /> : ix + 1}
            </div>
            {ix < RENT_STEPS.length - 1 && <div style={{ flex: 1, height: 2, background: ix < step ? 'var(--lime)' : 'var(--line-2)', margin: '0 4px' }} />}
          </React.Fragment>
        ))}
      </div>
      <div style={{ textAlign: 'center', marginBottom: 18 }}>
        <div style={{ fontWeight: 800, fontSize: 17 }}>{RENT_STEPS[step].t}</div>
        <div className="tiny muted" style={{ marginTop: 3 }}>{RENT_STEPS[step].d}</div>
      </div>

      {step === 0 && <div style={{ display: 'grid', gap: 14 }}>
        <label className="fld"><span>Customer</span>
          <select className="input-block" value={custId} onChange={e => setCustId(e.target.value)}>
            <option value="">— Select customer —</option>
            {customers.map(c => <option key={c.id} value={c.id}>{c.name}</option>)}
          </select>
        </label>
        <label className="fld"><span>Purpose</span>
          <div className="tabs" style={{ width: '100%', display: 'flex' }}>
            {['Post-surgery', 'Sleep trial', 'Home O₂', 'Emergency'].map(t => <button key={t} className="tab" style={{ flex: 1, fontSize: 12.5 }}>{t}</button>)}
          </div>
        </label>
        <div className="row" style={{ justifyContent: 'space-between' }}>
          <span style={{ fontWeight: 800, fontSize: 14 }}>Machines Required</span>
          <span className="tiny muted">{lines.length} machine{lines.length > 1 ? 's' : ''}</span>
        </div>
        <div style={{ display: 'grid', gap: 8 }}>
          {lines.map((l, ix) => (
            <div key={ix} className="row" style={{ gap: 8 }}>
              <select className="input-block" style={{ flex: 1 }} value={l.device} onChange={e => setDevice(ix, e.target.value)}>
                {catalog.map(p => <option key={p.id || p.name || p.model}>{p.name || p.model}</option>)}
              </select>
              <button className="btn-icon" style={{ color: 'var(--ink-3)', flexShrink: 0 }} disabled={lines.length === 1} onClick={() => remove(ix)}><Icons.x size={17} /></button>
            </div>
          ))}
        </div>
        <button className="btn btn-ghost btn-sm" style={{ border: '1px dashed var(--line-2)', width: '100%', justifyContent: 'center', padding: '10px' }} onClick={add}><Icons.plus size={15} stroke={2.5} />Add machine</button>
      </div>}

      {step === 1 && <div style={{ display: 'grid', gap: 14 }}>
        <label className="fld"><span>Billing Cycle</span>
          <div className="tabs" style={{ width: '100%', display: 'flex' }}>
            {['Daily', 'Weekly', 'Monthly'].map(t => <button key={t} className={cls('tab', cycle === t && 'active')} style={{ flex: 1 }} onClick={() => {
              setCycle(t);
              setLines(prev => prev.map(l => {
                const prod = catalog.find(c => (c.name || c.model) === l.device);
                return prod ? { ...l, rate: getRateForCycle(prod, t), deposit: parseFloat(prod.rent_deposit || 50000) } : l;
              }));
            }}>{t}</button>)}
          </div>
        </label>
        <div className="grid" style={{ gridTemplateColumns: '1fr 1fr', gap: 12 }}>
          <label className="fld"><span>From Date</span><input type="date" className="input-block" value={fromDate} onChange={e => setFromDate(e.target.value)} /></label>
          <label className="fld"><span>Next Due</span><input type="date" className="input-block" value={toDate} onChange={e => setToDate(e.target.value)} /></label>
        </div>
        <div style={{ border: '1px solid var(--line)', borderRadius: 13, overflow: 'hidden' }}>
          <table className="tbl" style={{ fontSize: 13 }}>
            <thead><tr><th>Machine</th><th style={{ textAlign: 'right' }}>Rate / {per}</th><th style={{ textAlign: 'right' }}>Deposit</th></tr></thead>
            <tbody>
              {lines.map((l, ix) => (
                <tr key={ix}>
                  <td style={{ fontWeight: 600 }}>{l.device}<div className="tiny muted">{l.cat}</div></td>
                  <td style={{ textAlign: 'right' }}><input className="input-block mono" style={{ width: 110, padding: '6px 9px', textAlign: 'right', display: 'inline-block' }} value={l.rate} onChange={e => patch(ix, { rate: Math.max(0, parseInt(e.target.value.replace(/\D/g, '')) || 0) })} /></td>
                  <td style={{ textAlign: 'right' }}><input className="input-block mono" style={{ width: 110, padding: '6px 9px', textAlign: 'right', display: 'inline-block' }} value={l.deposit} onChange={e => patch(ix, { deposit: Math.max(0, parseInt(e.target.value.replace(/\D/g, '')) || 0) })} /></td>
                </tr>
              ))}
            </tbody>
          </table>
          <div className="row" style={{ justifyContent: 'space-between', padding: '11px 16px', background: 'var(--surface-2)', borderTop: '1px solid var(--line)' }}>
            <span style={{ fontWeight: 700 }}>Consolidated {cycle.toLowerCase()} invoice</span>
            <span className="mono" style={{ fontWeight: 800, fontSize: 15 }}>{PKR(recurring)}<span className="tiny muted">/{per}</span></span>
          </div>
        </div>
        <div className="row" style={{ gap: 8, padding: '10px 14px', background: 'var(--lime-soft)', borderRadius: 11 }}>
          <Icons.shield size={16} style={{ color: 'var(--lime-700)', flexShrink: 0 }} />
          <span className="tiny" style={{ fontWeight: 600 }}>Pooled refundable deposit: <b>{PKR(deposits)}</b></span>
        </div>
      </div>}

      {step === 2 && <div style={{ display: 'grid', gap: 14 }}>
        <label className="fld"><span>Delivered By</span>
          <select className="input-block"><option>Kamran Ali (KHI)</option><option>Ali Raza (LHR)</option><option>Self pickup</option><option>Courier</option></select>
        </label>
        <div className="tiny muted" style={{ fontWeight: 700 }}>SERIAL ASSIGNMENT · {lines.length} machine{lines.length > 1 ? 's' : ''}</div>
        <div style={{ display: 'grid', gap: 8 }}>
          {lines.map((l, ix) => (
            <div key={ix} className="row" style={{ gap: 10, justifyContent: 'space-between', padding: '9px 12px', border: '1px solid var(--line)', borderRadius: 11 }}>
              <span style={{ fontWeight: 600, fontSize: 13.5 }}>{l.device}</span>
              <input className="input-block mono" style={{ width: 150, padding: '7px 9px' }} placeholder="Assign serial…" defaultValue={`${(l.cat || 'XX').slice(0, 2).toUpperCase()}-${90040 + ix}`} />
            </div>
          ))}
        </div>
      </div>}

      {step === 3 && <div style={{ background: 'var(--surface-2)', borderRadius: 14, padding: 18, textAlign: 'center' }}>
        <Icons.cal size={30} style={{ color: 'var(--lime-700)', margin: '0 auto 8px' }} />
        <div style={{ fontWeight: 700, marginBottom: 4 }}>Scheduler is now tracking this agreement</div>
        <div className="tiny muted">One {cycle.toLowerCase()} invoice covers all {lines.length} machine{lines.length > 1 ? 's' : ''}.</div>
      </div>}

      {step === 4 && <div style={{ textAlign: 'center', padding: '6px 0' }}>
        <div style={{ width: 64, height: 64, borderRadius: 50, background: 'var(--lime-soft)', display: 'grid', placeItems: 'center', margin: '0 auto 14px' }}><Icons.check size={34} stroke={2.6} style={{ color: 'var(--lime-700)' }} /></div>
        <div style={{ fontWeight: 800, fontSize: 18 }}>Agreement Activated</div>
        <div className="tiny muted" style={{ marginTop: 4, marginBottom: 14 }}>{lines.length} machine{lines.length > 1 ? 's' : ''} · {cycle} · {PKR(recurring)}/{per} consolidated · deposit {PKR(deposits)} ledgered</div>
        <div className="row" style={{ gap: 8, justifyContent: 'center', flexWrap: 'wrap' }}>
          <Badge kind="ok"><Icons.bell size={12} />SMS sent</Badge><Badge kind="info">Email agreement</Badge><Badge kind="warn">WhatsApp</Badge>
        </div>
      </div>}
    </Modal>
  );
}
window.Rentals = Rentals;
