// Shared quote/invoice building blocks — both QuotesView and InvoicesView
// render the same line-item editor and totals math, so it lives once here.

// Stable row keys for the editor — an index key makes React re-identify every
// row below a deletion, which can strand focus/edit state on the wrong money
// field. `_k` is client-only; DocFormModal strips it before the API call.
let lineItemSeq = 0;

const LineItemsEditor = ({ items, setItems, products }) => {
    // list_price = optional "reg. price" — shown crossed out on the PDF when
    // higher than unit price (discount look). Display-only; totals ignore it.
    const addItem = () => setItems(p => [...p, { _k: ++lineItemSeq, description: '', quantity: 1, unit_price: 0, list_price: '', product_id: null, total: 0 }]);
    const removeItem = (i) => setItems(p => p.filter((_, idx) => idx !== i));
    const updateItem = (i, key, val) => setItems(p => p.map((row, idx) => {
        if (idx !== i) return row;
        const updated = { ...row, [key]: val };
        if (key === 'product_id' && val) {
            const prod = products.find(p => p.id === parseInt(val));
            if (prod) { updated.description = prod.name; updated.unit_price = parseFloat(prod.unit_price); updated.list_price = ''; }
        }
        // Auto reg. price: pricing a product line below its catalog price IS a
        // discount — fill list_price from the catalog so the strike-through
        // shows itself (server derives the same on save; this is the live echo).
        if (key === 'unit_price' && updated.product_id && (row.list_price === '' || row.list_price == null)) {
            const prod = products.find(p => p.id === parseInt(updated.product_id));
            if (prod && parseFloat(prod.unit_price) > parseFloat(val || 0)) updated.list_price = parseFloat(prod.unit_price);
        }
        // parseFloat wherever money math happens — the displayed total must
        // match the server's NUMERIC math exactly (quantity is decimal-capable
        // on the backend even though this input steps in whole units).
        updated.total = parseFloat(updated.quantity || 0) * parseFloat(updated.unit_price || 0);
        return updated;
    }));

    return (
        <div>
            <table className="line-items-table">
                <thead><tr><th style={{ width: '31%' }}>Description</th><th style={{ width: '16%' }}>Product</th><th style={{ width: '9%' }}>Qty</th><th style={{ width: '13%' }} title="Optional — prints crossed out when higher than unit price">Reg. Price</th><th style={{ width: '13%' }}>Unit Price</th><th style={{ width: '12%' }}>Total</th><th style={{ width: '6%' }}></th></tr></thead>
                <tbody>
                    {items.map((row, i) => {
                        // Live echo of the picked product's billing term — the
                        // server snapshots is_subscription/billing_interval on
                        // save; this just shows it while the form is open.
                        const prod = row.product_id ? products.find(p => p.id === parseInt(row.product_id)) : null;
                        const per = prod && prod.is_subscription ? (prod.billing_interval === 'year' ? ' /yr' : ' /mo') : '';
                        return (
                        <tr key={row._k ?? i}>
                            <td><input value={row.description} onChange={e => updateItem(i, 'description', e.target.value)} placeholder="Item description" /></td>
                            <td>
                                <select value={row.product_id || ''} onChange={e => updateItem(i, 'product_id', e.target.value || null)}>
                                    <option value="">Custom</option>
                                    {products.map(p => <option key={p.id} value={p.id}>{p.name}</option>)}
                                </select>
                            </td>
                            <td><input type="number" min="1" step="1" value={row.quantity} onChange={e => updateItem(i, 'quantity', e.target.value)} /></td>
                            <td><input type="number" min="0" step="0.01" value={row.list_price ?? ''} placeholder="—" onChange={e => updateItem(i, 'list_price', e.target.value)} /></td>
                            <td><input type="number" min="0" step="0.01" value={row.unit_price} onChange={e => updateItem(i, 'unit_price', e.target.value)} /></td>
                            <td style={{ fontWeight: 500 }}>${(parseFloat(row.quantity || 0) * parseFloat(row.unit_price || 0)).toFixed(2)}{per}</td>
                            <td><button type="button" className="btn-icon-sm danger" onClick={() => removeItem(i)}><i className="fas fa-times"></i></button></td>
                        </tr>
                        );
                    })}
                </tbody>
            </table>
            <button type="button" className="btn btn-secondary btn-small" onClick={addItem}><i className="fas fa-plus"></i> Add Line Item</button>
        </div>
    );
};

const TotalsBlock = ({ items, taxRate, onTaxChange, products = [] }) => {
    const subtotal  = items.reduce((s, i) => s + parseFloat(i.quantity || 0) * parseFloat(i.unit_price || 0), 0);
    const taxAmount = subtotal * (parseFloat(taxRate || 0) / 100);
    const total     = subtotal + taxAmount;
    // Grand Total wears the term when EVERY line is a subscription on one
    // cadence — same uniformInterval rule as the server/PDF. In the form,
    // interval comes from the picked product (server snapshots it on save).
    let totalPer = '';
    if (items.length && products.length) {
        const perLine = items.map(row => {
            const prod = row.product_id ? products.find(p => p.id === parseInt(row.product_id)) : null;
            return prod && prod.is_subscription ? (prod.billing_interval === 'year' ? ' /yr' : ' /mo') : '';
        });
        if (perLine.every(p => p) && new Set(perLine).size === 1) totalPer = perLine[0];
    }
    return (
        <div className="totals-block">
            <div className="totals-row"><span>Subtotal</span><span>${subtotal.toFixed(2)}</span></div>
            <div className="totals-row">
                <span>Tax <input type="number" min="0" max="100" step="0.1" value={taxRate} onChange={e => onTaxChange(e.target.value)} style={{ width: '4rem', padding: '0.2rem 0.4rem', border: '1px solid #d1d5db', borderRadius: '0.25rem', fontSize: '0.8125rem', marginLeft: '0.5rem' }} />%</span>
                <span>${taxAmount.toFixed(2)}</span>
            </div>
            <div className="totals-row total-final"><span>Total</span><span>${total.toFixed(2)}{totalPer}</span></div>
        </div>
    );
};
