<?php
require_once '../includes/auth.php';
require_once '../db.php';

requirePermission('master_sales', 'create', BASE_URL . '/dashboard.php');

require_once '../includes/header.php';
require_once '../includes/sidebar.php';

// Load ALL clients across all companies
$clientRes = $conn->query("SELECT id, name, customer_type FROM clients WHERE status = 1 ORDER BY name");
$clientList = [];
while ($c = $clientRes->fetch_assoc()) $clientList[] = $c;

$master_no = 'MST/' . date('YmdHis');
?>

<div class="page-header">
    <h2><i class="fas fa-layer-group" style="color:var(--primary);margin-right:8px;"></i>Master Sales Invoice</h2>
    <a href="index.php" class="btn btn-secondary"><i class="fas fa-arrow-left"></i> Back</a>
</div>

<form method="post" action="save.php" id="masterForm">
<input type="hidden" name="master_no" value="<?= $master_no ?>">

<!-- Header -->
<div class="panel" style="margin-bottom:12px;">
    <div class="panel-header"><span class="panel-title">Invoice Details</span></div>
    <div class="panel-body" style="padding-bottom:12px;">
        <div class="form-row" style="align-items:flex-end;">

            <div class="form-group" style="flex:2;min-width:220px;">
                <label>Client <span style="color:var(--danger)">*</span></label>
                <input type="hidden" name="client_id" id="clientId">
                <div style="position:relative;">
                    <input type="text" id="clientSearch" placeholder="Type to search client..."
                           autocomplete="off" oninput="filterClients(this.value)" onfocus="filterClients(this.value)" style="width:100%;">
                    <div id="clientDropdown" style="display:none;position:absolute;top:100%;left:0;right:0;background:#fff;border:1px solid var(--border);border-radius:0 0 6px 6px;max-height:200px;overflow-y:auto;z-index:999;box-shadow:0 4px 12px rgba(0,0,0,.12);"></div>
                </div>
                <div id="clientChosen" style="display:none;margin-top:5px;padding:5px 10px;background:var(--bg-light);border-radius:5px;font-size:13px;align-items:center;gap:8px;">
                    <i class="fas fa-user" style="color:var(--primary);"></i>
                    <span id="clientChosenName"></span>
                    <button type="button" onclick="clearClient()" style="margin-left:auto;background:none;border:none;cursor:pointer;color:var(--danger);font-size:13px;"><i class="fas fa-times"></i></button>
                </div>
            </div>

            <div class="form-group">
                <label>Master Ref</label>
                <input type="text" value="<?= htmlspecialchars($master_no) ?>" disabled style="background:#f8fafc;color:var(--text-muted);">
            </div>
            <div class="form-group">
                <label>Invoice Date</label>
                <input type="date" name="invoice_date" value="<?= date('Y-m-d') ?>" required>
            </div>
        </div>
    </div>
</div>

<!-- Line Items -->
<div class="panel" style="margin-bottom:12px;">
    <div class="panel-header">
        <span class="panel-title">Line Items <span style="font-size:11px;font-weight:400;color:var(--text-muted);margin-left:8px;">(search products across all companies)</span></span>
        <div style="display:flex;gap:8px;">
            <button type="button" onclick="openAiModal()" class="btn btn-outline btn-sm" style="border-color:#8b5cf6;color:#7c3aed;"><i class="fas fa-magic" style="margin-right:4px;"></i>AI Extract</button>
            <button type="button" id="addRow" class="btn btn-outline btn-sm"><i class="fas fa-plus"></i> Add Row</button>
        </div>
    </div>
    <!-- Quick Add Bar -->
    <div style="padding:10px 14px;background:#f0f7ff;border-bottom:1px solid #bfdbfe;display:flex;gap:8px;align-items:center;flex-wrap:wrap;">
        <div style="position:relative;flex:1;min-width:200px;">
            <i class="fas fa-search" style="position:absolute;left:9px;top:50%;transform:translateY(-50%);color:#93c5fd;font-size:12px;pointer-events:none;z-index:1;"></i>
            <input type="text" id="quickSearchMaster" class="productInput" placeholder="Search product to add to bill..."
                   autocomplete="off" style="padding:6px 8px 6px 32px;width:100%;font-size:13px;border:1px solid #bfdbfe;border-radius:6px;background:#fff;">
        </div>
        <input type="number" id="quickQtyMaster" min="0.01" step="0.01" value="1" placeholder="Qty"
               style="width:72px;padding:6px 8px;font-size:13px;border:1px solid var(--border);border-radius:6px;">
        <button type="button" id="quickAddBtnMaster" class="btn btn-primary btn-sm">
            <i class="fas fa-plus"></i> Add to Bill
        </button>
        <span id="masterQuickMsg" style="font-size:12px;color:var(--danger);display:none;font-weight:500;"></span>
    </div>
    <div style="overflow-x:auto;">
        <table class="list-table compact-sales-table" id="salesTable" style="width:100%;table-layout:fixed;">
            <colgroup>
                <col style="width:28px;">
                <col style="width:30px;">
                <col style="min-width:200px;width:24%;">
                <col style="width:130px;">
                <col style="width:80px;">
                <col style="width:65px;">
                <col style="width:105px;">
                <col style="width:125px;">
                <col style="width:50px;">
                <col style="width:85px;">
                <col style="width:36px;">
            </colgroup>
            <thead>
                <tr>
                    <th style="text-align:center;">#</th>
                    <th></th>
                    <th>
                        Product
                        <label style="font-size:11px;font-weight:400;margin-left:6px;color:var(--text-muted);cursor:pointer;" title="Show/hide description">
                            <input type="checkbox" id="descToggle" onchange="toggleDescriptions()" style="margin-right:2px;">Desc
                        </label>
                    </th>
                    <th>Batch</th>
                    <th>MRP / Avail</th>
                    <th>Qty</th>
                    <th>Sell Price</th>
                    <th>Discount</th>
                    <th>GST%</th>
                    <th>Total</th>
                    <th></th>
                </tr>
            </thead>
            <tbody id="salesBody">
                <!-- template row (hidden) -->
                <tr class="salesRow template-row" style="display:none;">
                    <td class="rowNum" style="text-align:center;color:var(--text-muted);font-size:12px;">—</td>
                    <td><span class="co-badge" style="font-size:10px;font-weight:700;padding:2px 5px;border-radius:3px;background:#e0f2fe;color:#0369a1;white-space:nowrap;">—</span></td>
                    <td class="product-cell">
                        <div class="prod-name-wrap">
                            <input type="text" class="productInput" placeholder="Search product..." autocomplete="off" style="width:100%;min-width:0;">
                            <input type="hidden" name="product_id[]">
                            <input type="hidden" name="purchase_item_id[]">
                            <input type="hidden" name="item_company_id[]">
                        </div>
                        <div class="prod-desc-wrap">
                            <textarea name="description[]" class="item-desc" placeholder="Note (opt)" rows="1" style="resize:none;font-size:11px;padding:2px 4px;width:100%;"></textarea>
                        </div>
                    </td>
                    <td class="batch-info" style="font-size:11px;color:var(--text-secondary);cursor:default;"></td>
                    <td style="text-align:center;font-size:11px;line-height:1.4;">
                        <span class="mrp" style="color:var(--text-muted);display:block;">0.00</span>
                        <span class="availQty" style="color:var(--success);">0</span>
                    </td>
                    <td><input type="number" step="0.01" class="qty" name="qty[]" min="0" placeholder="0" style="width:100%;"></td>
                    <td><input type="number" step="0.01" class="sellPrice" name="sell_price[]" placeholder="0.00" style="width:100%;"></td>
                    <td>
                        <div style="display:flex;gap:3px;">
                            <select class="discType" name="disc_type[]" style="width:52px;font-size:12px;">
                                <option value="">—</option>
                                <option value="percent">%</option>
                                <option value="amount">&#8377;</option>
                            </select>
                            <input type="number" step="0.01" class="discValue" name="disc_value[]" placeholder="0" style="flex:1;min-width:0;">
                        </div>
                    </td>
                    <td class="gstPercent" style="text-align:center;color:var(--text-muted);font-size:12px;">0</td>
                    <td class="lineTotal" style="text-align:right;font-weight:700;font-size:13px;">0.00</td>
                    <td>
                        <button type="button" class="removeRow action-btn delete" title="Remove">
                            <i class="fas fa-times"></i>
                        </button>
                    </td>
                </tr>
            </tbody>
        </table>
    </div>
</div>

<!-- Totals & Payment -->
<div style="display:grid;grid-template-columns:1fr auto;gap:16px;align-items:start;">
    <div class="panel">
        <div class="panel-header"><span class="panel-title">Payment Details</span></div>
        <div class="panel-body">
            <div class="form-row">
                <div class="form-group">
                    <label>Overall Discount Type</label>
                    <select name="overall_discount_type" id="overallDiscType">
                        <option value="">None</option>
                        <option value="percent">Percent (%)</option>
                        <option value="amount">Amount (&#8377;)</option>
                    </select>
                </div>
                <div class="form-group">
                    <label>Discount Value</label>
                    <input type="number" step="0.01" name="overall_discount_value" id="overallDiscValue" placeholder="0.00">
                </div>
                <div class="form-group">
                    <label>Received Amount</label>
                    <input type="number" step="0.01" name="received_amount" id="receivedAmount" placeholder="0.00">
                </div>
                <div class="form-group">
                    <label>Payment Mode</label>
                    <select name="payment_mode">
                        <option value="Cash">Cash</option>
                        <option value="UPI">UPI</option>
                        <option value="Card">Card</option>
                        <option value="Bank">Bank Transfer</option>
                    </select>
                </div>
            </div>
        </div>
    </div>
    <div class="totals-box" style="min-width:260px;">
        <div class="totals-row"><span>Gross Total</span><span>&#8377; <span id="grossTotal">0.00</span></span></div>
        <div class="totals-row"><span>GST</span><span>&#8377; <span id="gstTotal">0.00</span></span></div>
        <div class="totals-row grand-total"><span>Net Total</span><span>&#8377; <span id="netTotal">0.00</span></span></div>
    </div>
</div>

<div style="display:flex;gap:12px;margin-top:16px;">
    <button type="submit" name="action" value="save" class="btn btn-secondary"><i class="fas fa-save"></i> Save Draft</button>
    <button type="submit" name="action" value="final" class="btn btn-success"
            onclick="return confirm('Finalize invoices and reduce stock for all companies?')">
        <i class="fas fa-check-circle"></i> Complete Sale
    </button>
</div>
</form>

<!-- Global batch dropdown (body-level to avoid overflow clipping) -->
<div id="batchDropdownGlobal" style="display:none;position:fixed;background:#fff;border:1px solid var(--border);border-radius:6px;max-height:280px;overflow-y:auto;z-index:9990;box-shadow:0 4px 18px rgba(0,0,0,.15);min-width:520px;"></div>

<!-- Add Client Modal -->
<div id="clientModal" style="display:none;position:fixed;inset:0;background:rgba(0,0,0,.45);z-index:2000;align-items:center;justify-content:center;">
    <div style="background:#fff;border-radius:10px;padding:28px 28px 20px;width:460px;max-width:95vw;box-shadow:0 8px 40px rgba(0,0,0,.2);">
        <div style="display:flex;align-items:center;justify-content:space-between;margin-bottom:18px;">
            <h3 style="margin:0;font-size:16px;"><i class="fas fa-user-plus" style="color:var(--primary);margin-right:8px;"></i>Add New Client</h3>
            <button type="button" onclick="closeClientModal()" style="background:none;border:none;font-size:18px;cursor:pointer;color:var(--text-muted);">&times;</button>
        </div>
        <div style="display:grid;grid-template-columns:1fr 1fr;gap:12px;">
            <div class="form-group" style="grid-column:1/-1;">
                <label>Client Name <span style="color:var(--danger)">*</span></label>
                <input type="text" id="nc_name" placeholder="Client or company name" style="width:100%;">
            </div>
            <div class="form-group"><label>Phone</label><input type="text" id="nc_phone" placeholder="Phone number"></div>
            <div class="form-group"><label>Email</label><input type="email" id="nc_email" placeholder="Email address"></div>
            <div class="form-group">
                <label>Customer Type</label>
                <select id="nc_type" onchange="toggleModalGST()">
                    <option value="B2C">B2C (Individual)</option>
                    <option value="B2B">B2B (Business)</option>
                </select>
            </div>
            <div class="form-group" id="nc_gstin_wrap" style="display:none;">
                <label>GSTIN</label>
                <input type="text" id="nc_gstin" placeholder="15-digit GSTIN" maxlength="15" style="text-transform:uppercase;" oninput="this.value=this.value.toUpperCase();">
            </div>
        </div>
        <div class="form-group"><label>Address</label><textarea id="nc_address" rows="2" placeholder="Full address" style="width:100%;"></textarea></div>
        <div id="nc_error" style="color:var(--danger);font-size:13px;margin-bottom:8px;display:none;"></div>
        <div style="display:flex;gap:10px;justify-content:flex-end;margin-top:8px;">
            <button type="button" class="btn btn-secondary" onclick="closeClientModal()">Cancel</button>
            <button type="button" class="btn btn-primary" onclick="saveNewClient()"><i class="fas fa-save"></i> Save & Select</button>
        </div>
    </div>
</div>

<script>
/* ---- Company badge colours ---- */
const CO_COLORS = ['#dbeafe:#1d4ed8','#dcfce7:#15803d','#fef9c3:#854d0e','#fce7f3:#9d174d','#ede9fe:#6d28d9'];
const coColorMap = {};

/* ---- Row numbering ---- */
function updateRowNums() {
    document.querySelectorAll('#salesBody .salesRow:not(.template-row)').forEach((row, idx) => {
        const cell = row.querySelector('.rowNum');
        if (cell) cell.textContent = idx + 1;
    });
}

/* ---- Duplicate product check ---- */
function checkDuplicateMaster(pid, excludeRow) {
    const rows = document.querySelectorAll('#salesBody .salesRow:not(.template-row)');
    for (let i = 0; i < rows.length; i++) {
        if (rows[i] === excludeRow) continue;
        const hid = rows[i].querySelector('input[name="product_id[]"]');
        if (hid && hid.value && parseInt(hid.value) === parseInt(pid)) {
            const numCell = rows[i].querySelector('.rowNum');
            return numCell ? numCell.textContent : (i + 1);
        }
    }
    return null;
}

function showMasterQuickMsg(msg) {
    const el = document.getElementById('masterQuickMsg');
    if (!el) return;
    el.textContent = msg;
    el.style.display = 'inline';
    clearTimeout(el._t);
    el._t = setTimeout(() => { el.style.display = 'none'; }, 3500);
}

function toggleDescriptions() {
    const show = document.getElementById('descToggle').checked;
    document.getElementById('salesTable').classList.toggle('show-desc', show);
}

function getCoColor(coId) {
    if (!coColorMap[coId]) {
        const idx = Object.keys(coColorMap).length % CO_COLORS.length;
        coColorMap[coId] = CO_COLORS[idx];
    }
    return coColorMap[coId];
}

/* ---- Client autocomplete ---- */
const CLIENTS = <?= json_encode($clientList) ?>;
function filterClients(q) {
    const dd = document.getElementById('clientDropdown');
    const search = q.trim().toLowerCase();
    const filtered = search ? CLIENTS.filter(c => c.name.toLowerCase().includes(search)) : CLIENTS;
    let html = '';
    filtered.slice(0, 30).forEach(c => {
        const badge = c.customer_type === 'B2B'
            ? '<span style="font-size:10px;background:#e0f2fe;color:#0369a1;padding:1px 5px;border-radius:3px;margin-left:6px;">B2B</span>' : '';
        html += `<div class="cdd-item" onmousedown="selectClient(${c.id},'${c.name.replace(/'/g,"\\'")}')">
            <i class="fas fa-user" style="color:var(--primary);margin-right:7px;font-size:12px;"></i>${c.name}${badge}</div>`;
    });
    html += `<div class="cdd-item cdd-add" onmousedown="openClientModal('${q.replace(/'/g,"\\'")}')">
        <i class="fas fa-plus-circle" style="color:var(--success);margin-right:7px;"></i>Add New Client</div>`;
    dd.innerHTML = html;
    dd.style.display = 'block';
}
document.getElementById('clientSearch').addEventListener('blur', () =>
    setTimeout(() => document.getElementById('clientDropdown').style.display = 'none', 150));
function selectClient(id, name) {
    document.getElementById('clientId').value = id;
    document.getElementById('clientSearch').style.display = 'none';
    document.getElementById('clientDropdown').style.display = 'none';
    const chosen = document.getElementById('clientChosen');
    chosen.style.display = 'flex';
    document.getElementById('clientChosenName').textContent = name;
}
function clearClient() {
    document.getElementById('clientId').value = '';
    document.getElementById('clientSearch').style.display = '';
    document.getElementById('clientSearch').value = '';
    document.getElementById('clientChosen').style.display = 'none';
    document.getElementById('clientSearch').focus();
}
function openClientModal(prefill) {
    document.getElementById('nc_name').value = prefill || '';
    ['nc_phone','nc_email','nc_gstin','nc_address'].forEach(id => document.getElementById(id).value = '');
    document.getElementById('nc_type').value = 'B2C';
    document.getElementById('nc_error').style.display = 'none';
    toggleModalGST();
    document.getElementById('clientModal').style.display = 'flex';
    document.getElementById('nc_name').focus();
}
function closeClientModal() { document.getElementById('clientModal').style.display = 'none'; }
function toggleModalGST() {
    document.getElementById('nc_gstin_wrap').style.display =
        document.getElementById('nc_type').value === 'B2B' ? 'block' : 'none';
}
const GST_STATES = {'01':'J&K','02':'HP','03':'Punjab','04':'Chandigarh','05':'Uttarakhand','06':'Haryana','07':'Delhi','08':'Rajasthan','09':'UP','10':'Bihar','11':'Sikkim','18':'Assam','19':'WB','20':'Jharkhand','21':'Odisha','22':'CG','23':'MP','24':'Gujarat','27':'Maharashtra','29':'Karnataka','30':'Goa','32':'Kerala','33':'TN','36':'Telangana','37':'AP'};
function saveNewClient() {
    const name = document.getElementById('nc_name').value.trim();
    const errEl = document.getElementById('nc_error');
    if (!name) { errEl.textContent = 'Client name is required.'; errEl.style.display='block'; return; }
    errEl.style.display = 'none';
    const gstin = document.getElementById('nc_gstin').value.trim();
    const sc = gstin.length >= 2 && GST_STATES[gstin.substring(0,2)] ? gstin.substring(0,2) : '';
    fetch('ajax_add_client.php', {
        method:'POST', headers:{'Content-Type':'application/x-www-form-urlencoded'},
        body: `name=${encodeURIComponent(name)}&phone=${encodeURIComponent(document.getElementById('nc_phone').value.trim())}`
            + `&email=${encodeURIComponent(document.getElementById('nc_email').value.trim())}`
            + `&customer_type=${encodeURIComponent(document.getElementById('nc_type').value)}`
            + `&gstin=${encodeURIComponent(gstin)}&state_code=${encodeURIComponent(sc)}`
            + `&address=${encodeURIComponent(document.getElementById('nc_address').value.trim())}`
    }).then(r=>r.json()).then(data => {
        if (data.status === 'ok') {
            CLIENTS.push({id:data.id, name:data.name, customer_type:data.customer_type||'B2C'});
            CLIENTS.sort((a,b)=>a.name.localeCompare(b.name));
            closeClientModal();
            selectClient(data.id, data.name);
        } else { errEl.textContent = data.msg||'Error.'; errEl.style.display='block'; }
    }).catch(()=>{ errEl.textContent='Server error.'; errEl.style.display='block'; });
}

/* ---- Product search (cross-company) — body-level dropdown to avoid overflow clipping ---- */
let searchTimer = null;
let activeProductInput = null;
const gdd = document.getElementById('batchDropdownGlobal');

function positionGlobalDD(input) {
    const rect = input.getBoundingClientRect();
    gdd.style.top  = rect.bottom + 'px';
    gdd.style.left = rect.left + 'px';
    gdd.style.width = Math.max(520, rect.width) + 'px';
}

function hideGlobalDD() { gdd.style.display = 'none'; activeProductInput = null; activeBatchCell = null; }

/* ---- Click batch cell to re-pick batch for the same product ---- */
let activeBatchCell = null;

document.addEventListener('click', function(e) {
    const cell = e.target.closest('.batch-info');
    if (!cell || !cell.dataset.pid) return;
    activeBatchCell = cell;
    activeProductInput = null;
    gdd.innerHTML = '<div style="padding:10px;color:var(--text-muted);font-size:13px;">Loading batches…</div>';
    positionGlobalDD(cell);
    gdd.style.display = 'block';
    fetch('ajax_batches.php?pid=' + encodeURIComponent(cell.dataset.pid))
    .then(r => r.json())
    .then(data => {
        if (!activeBatchCell) return;
        if (!data.length) {
            gdd.innerHTML = '<div style="padding:10px;color:var(--text-muted);font-size:13px;">No batches available</div>';
        } else {
            let html = '';
            data.forEach(b => {
                const colors = getCoColor(b.company_id).split(':');
                const badge  = `<span style="font-size:10px;font-weight:700;padding:2px 5px;border-radius:3px;background:${colors[0]};color:${colors[1]};">${b.company_prefix}</span>`;
                html += `<div class="cdd-item batch-item" style="display:flex;align-items:center;gap:8px;"
                    data-pid="${b.product_id}" data-pname="${b.product_name.replace(/"/g,'&quot;')}"
                    data-unit="${b.unit||''}" data-batch="${b.batch_no}"
                    data-piid="${b.purchase_item_id}" data-avail="${b.available_qty}"
                    data-mrp="${b.mrp}" data-price="${b.selling_price_incl}"
                    data-gst="${b.gst_percent}" data-coid="${b.company_id}"
                    data-coname="${b.company_name.replace(/"/g,'&quot;')}" data-copfx="${b.company_prefix}"
                    data-cobg="${getCoColor(b.company_id)}"
                    onmousedown="selectBatchFromCell(this, event)">
                    ${badge}
                    <span style="flex:1;font-size:12px;"><strong>${b.product_name}</strong>${b.unit ? ' <em style="color:#94a3b8;font-size:11px;">'+b.unit+'</em>' : ''}</span>
                    <span style="font-size:11px;color:var(--text-secondary);">${b.batch_no}</span>
                    <span style="font-size:11px;color:var(--success);">Qty:${b.available_qty}</span>
                    <span style="font-size:11px;color:var(--text-muted);">&#8377;${b.selling_price_incl.toFixed(2)}</span>
                </div>`;
            });
            gdd.innerHTML = html;
        }
        positionGlobalDD(cell);
        gdd.style.display = 'block';
    });
});

function selectBatchFromCell(el, e) {
    e.preventDefault();
    if (!activeBatchCell) return;
    const row = activeBatchCell.closest('tr');
    const pid = parseInt(el.dataset.pid);
    const dup = checkDuplicateMaster(pid, row);
    if (dup !== null) {
        showMasterQuickMsg('Already added in row ' + dup + '.');
        hideGlobalDD();
        return;
    }
    const colors = el.dataset.cobg.split(':');

    row.querySelector('.productInput').value                    = el.dataset.pname;
    row.querySelector('input[name="product_id[]"]').value       = el.dataset.pid;
    row.querySelector('input[name="purchase_item_id[]"]').value = el.dataset.piid;
    row.querySelector('input[name="item_company_id[]"]').value  = el.dataset.coid;
    activeBatchCell.innerHTML = `${el.dataset.batch} <i class="fas fa-pen" style="font-size:9px;color:var(--text-muted);margin-left:3px;opacity:.7;"></i>`;
    activeBatchCell.dataset.pid = el.dataset.pid;
    row.querySelector('.mrp').textContent      = parseFloat(el.dataset.mrp).toFixed(2);
    row.querySelector('.availQty').textContent = el.dataset.avail;
    row.querySelector('.gstPercent').textContent = el.dataset.gst;
    row.querySelector('.sellPrice').value      = parseFloat(el.dataset.price).toFixed(2);

    const badge = row.querySelector('.co-badge');
    badge.textContent      = el.dataset.copfx;
    badge.style.background = colors[0];
    badge.style.color      = colors[1];

    hideGlobalDD();
    recalcRow(row);
}

document.addEventListener('input', function(e) {
    if (!e.target.classList.contains('productInput')) return;
    activeProductInput = e.target;
    const q = e.target.value.trim();
    clearTimeout(searchTimer);
    if (q.length < 1) { hideGlobalDD(); return; }
    searchTimer = setTimeout(() => {
        fetch('ajax_batches.php?q=' + encodeURIComponent(q))
        .then(r => r.json())
        .then(data => {
            if (!activeProductInput) return;
            if (!data.length) {
                gdd.innerHTML = '<div style="padding:10px;color:var(--text-muted);font-size:13px;">No results</div>';
            } else {
                let html = '';
                data.forEach(b => {
                    const colors = getCoColor(b.company_id).split(':');
                    const badge  = `<span style="font-size:10px;font-weight:700;padding:2px 5px;border-radius:3px;background:${colors[0]};color:${colors[1]};">${b.company_prefix}</span>`;
                    html += `<div class="cdd-item batch-item" style="display:flex;align-items:center;gap:8px;"
                        data-pid="${b.product_id}" data-pname="${b.product_name.replace(/"/g,'&quot;')}"
                        data-unit="${b.unit||''}" data-batch="${b.batch_no}"
                        data-piid="${b.purchase_item_id}" data-avail="${b.available_qty}"
                        data-mrp="${b.mrp}" data-price="${b.selling_price_incl}"
                        data-gst="${b.gst_percent}" data-coid="${b.company_id}"
                        data-coname="${b.company_name.replace(/"/g,'&quot;')}" data-copfx="${b.company_prefix}"
                        data-cobg="${getCoColor(b.company_id)}"
                        onmousedown="selectBatch(this, event)">
                        ${badge}
                        <span style="flex:1;font-size:12px;"><strong>${b.product_name}</strong>${b.unit ? ' <em style="color:#94a3b8;font-size:11px;">'+b.unit+'</em>' : ''}</span>
                        <span style="font-size:11px;color:var(--text-secondary);">${b.batch_no}</span>
                        <span style="font-size:11px;color:var(--success);">Qty:${b.available_qty}</span>
                        <span style="font-size:11px;color:var(--text-muted);">&#8377;${b.selling_price_incl.toFixed(2)}</span>
                    </div>`;
                });
                gdd.innerHTML = html;
            }
            positionGlobalDD(activeProductInput);
            gdd.style.display = 'block';
        });
    }, 250);
});

document.addEventListener('blur', function(e) {
    if (e.target.classList.contains('productInput')) {
        setTimeout(hideGlobalDD, 200);
    }
}, true);


let _quickBatch = null;

function selectBatch(el, e) {
    e.preventDefault();
    if (!activeProductInput) return;

    // Handle quick-add bar search
    if (activeProductInput.id === 'quickSearchMaster') {
        _quickBatch = Object.assign({}, el.dataset);
        activeProductInput.value = el.dataset.pname;
        hideGlobalDD();
        document.getElementById('quickQtyMaster').focus();
        return;
    }

    const row = activeProductInput.closest('tr');
    const pid = parseInt(el.dataset.pid);
    const dup = checkDuplicateMaster(pid, row);
    if (dup !== null) {
        showMasterQuickMsg('Already added in row ' + dup + '.');
        hideGlobalDD();
        return;
    }
    const colors = el.dataset.cobg.split(':');

    activeProductInput.value = el.dataset.pname;
    row.querySelector('input[name="product_id[]"]').value       = el.dataset.pid;
    row.querySelector('input[name="purchase_item_id[]"]').value = el.dataset.piid;
    row.querySelector('input[name="item_company_id[]"]').value  = el.dataset.coid;
    const batchCell = row.querySelector('.batch-info');
    batchCell.innerHTML = `${el.dataset.batch} <i class="fas fa-pen" style="font-size:9px;color:var(--text-muted);margin-left:3px;opacity:.7;"></i>`;
    batchCell.dataset.pid = el.dataset.pid;
    batchCell.style.cursor = 'pointer';
    batchCell.title = 'Click to change batch';
    row.querySelector('.mrp').textContent                        = parseFloat(el.dataset.mrp).toFixed(2);
    row.querySelector('.availQty').textContent                   = el.dataset.avail;
    row.querySelector('.gstPercent').textContent                 = el.dataset.gst;
    row.querySelector('.sellPrice').value                        = parseFloat(el.dataset.price).toFixed(2);

    const badge = row.querySelector('.co-badge');
    badge.textContent = el.dataset.copfx;
    badge.style.background = colors[0];
    badge.style.color       = colors[1];

    hideGlobalDD();
    recalcRow(row);
}

/* ---- Calculations ---- */
function recalcRow(row) {
    const qty     = parseFloat(row.querySelector('.qty').value || 0);
    const price   = parseFloat(row.querySelector('.sellPrice').value || 0);
    const discType= row.querySelector('.discType').value;
    const discVal = parseFloat(row.querySelector('.discValue').value || 0);
    let finalUnit = price;
    if (discType === 'percent') finalUnit = price - (price * discVal / 100);
    else if (discType === 'amount') finalUnit = price - discVal;
    if (finalUnit < 0) finalUnit = 0;
    row.querySelector('.lineTotal').textContent = (finalUnit * qty).toFixed(2);
    recalcInvoiceTotals();
}

function recalcInvoiceTotals() {
    let gross = 0, gstTotal = 0;
    document.querySelectorAll('#salesBody .salesRow').forEach(row => {
        const qty     = parseFloat(row.querySelector('.qty').value || 0);
        const price   = parseFloat(row.querySelector('.sellPrice').value || 0);
        const discType= row.querySelector('.discType').value;
        const discVal = parseFloat(row.querySelector('.discValue').value || 0);
        const gstp    = parseFloat(row.querySelector('.gstPercent').textContent || 0);
        let finalUnit = price;
        if (discType === 'percent') finalUnit = price - (price * discVal / 100);
        else if (discType === 'amount') finalUnit = price - discVal;
        if (finalUnit < 0) finalUnit = 0;
        const line = finalUnit * qty;
        gross += line;
        if (qty > 0 && gstp > 0) gstTotal += (finalUnit - finalUnit / (1 + gstp / 100)) * qty;
    });
    const overallType = document.getElementById('overallDiscType').value;
    const overallVal  = parseFloat(document.getElementById('overallDiscValue').value || 0);
    let net = gross;
    if (overallType === 'percent') net = gross - (gross * overallVal / 100);
    else if (overallType === 'amount') net = gross - overallVal;
    if (net < 0) net = 0;
    document.getElementById('grossTotal').textContent = gross.toFixed(2);
    document.getElementById('gstTotal').textContent   = gstTotal.toFixed(2);
    document.getElementById('netTotal').textContent   = net.toFixed(2);
}

document.addEventListener('input', function(e) {
    if (['qty','sellPrice','discValue'].some(c => e.target.classList.contains(c)) || e.target.id === 'overallDiscValue') {
        const row = e.target.closest('.salesRow');
        if (row) recalcRow(row); else recalcInvoiceTotals();
    }
});
document.addEventListener('change', function(e) {
    if (e.target.classList.contains('discType') || e.target.id === 'overallDiscType') {
        const row = e.target.closest('.salesRow');
        if (row) recalcRow(row); else recalcInvoiceTotals();
    }
});

// Close global dropdown on outside click
document.addEventListener('click', function(e) {
    const isBatchCell = e.target.closest('.batch-info') && e.target.closest('.batch-info').dataset.pid;
    if (!e.target.classList.contains('productInput') && !isBatchCell && !gdd.contains(e.target)) hideGlobalDD();
});

/* ---- Add / Remove rows ---- */
function addRow() {
    const tmpl   = document.querySelector('.template-row');
    const newRow = tmpl.cloneNode(true);
    newRow.classList.remove('template-row');
    newRow.style.display = '';
    newRow.querySelectorAll('input').forEach(i => i.value = '');
    newRow.querySelectorAll('textarea').forEach(t => t.value = '');
    newRow.querySelectorAll('select').forEach(s => s.selectedIndex = 0);
    newRow.querySelector('.mrp').textContent     = '0.00';
    newRow.querySelector('.availQty').textContent= '0';
    newRow.querySelector('.gstPercent').textContent = '0';
    newRow.querySelector('.lineTotal').textContent  = '0.00';
    const batchInfoClone = newRow.querySelector('.batch-info');
    batchInfoClone.textContent = '';
    batchInfoClone.style.cursor = 'default';
    batchInfoClone.title = '';
    delete batchInfoClone.dataset.pid;
    const badge = newRow.querySelector('.co-badge');
    badge.textContent = '—';
    badge.style.background = '#f1f5f9';
    badge.style.color = '#64748b';
    document.getElementById('salesBody').appendChild(newRow);
    updateRowNums();
}
document.getElementById('addRow').addEventListener('click', addRow);
addRow(); // start with one visible row

document.addEventListener('click', function(e) {
    const btn = e.target.closest('.removeRow');
    if (btn) {
        const rows = document.querySelectorAll('#salesBody .salesRow:not(.template-row)');
        if (rows.length > 1) { btn.closest('tr').remove(); recalcInvoiceTotals(); updateRowNums(); }
    }
});

/* ---- AI Extract ---- */
function openAiModal() {
    document.getElementById('aiModal').style.display = 'flex';
    document.getElementById('aiFile').value = '';
    document.getElementById('aiStatus').innerHTML = '';
    document.getElementById('aiStatus').style.display = 'none';
}
function closeAiModal() { document.getElementById('aiModal').style.display = 'none'; }

async function runAiExtract() {
    const fileInput = document.getElementById('aiFile');
    if (!fileInput.files.length) { alert('Please select an invoice image.'); return; }
    const statusEl = document.getElementById('aiStatus');
    statusEl.style.display = 'block';
    statusEl.innerHTML = '<span style="color:#2563eb;"><i class="fas fa-spinner fa-spin" style="margin-right:6px;"></i>Extracting from invoice...</span>';

    const fd = new FormData();
    fd.append('file', fileInput.files[0]);
    fd.append('type', 'sales');

    let d;
    try {
        const resp = await fetch('../includes/ai_extract.php', { method: 'POST', body: fd });
        d = await resp.json();
    } catch(err) {
        statusEl.innerHTML = '<span style="color:var(--danger);">Network error: ' + err.message + '</span>';
        return;
    }
    if (d.error) { statusEl.innerHTML = '<span style="color:var(--danger);">Error: ' + d.error + '</span>'; return; }

    const extracted = d.data || {};
    const msgs = [];

    // Fill client
    if (extracted.client_name) {
        const q = extracted.client_name.toLowerCase();
        const found = CLIENTS.find(c => c.name.toLowerCase() === q || c.name.toLowerCase().includes(q));
        if (found) { selectClient(found.id, found.name); msgs.push('✓ Client: ' + found.name); }
        else {
            document.getElementById('clientSearch').value = extracted.client_name;
            msgs.push('⚠ Client not matched — please select manually: ' + extracted.client_name);
        }
    }

    // Fill invoice date
    if (extracted.invoice_date) {
        document.querySelector('input[name="invoice_date"]').value = extracted.invoice_date;
        msgs.push('✓ Date: ' + extracted.invoice_date);
    }

    // Fill line items
    const items = extracted.items || [];
    if (items.length > 0) {
        // Clear existing rows
        document.querySelectorAll('#salesBody .salesRow:not(.template-row)').forEach(r => r.remove());

        items.forEach(item => {
            addRow();
            const rows = document.querySelectorAll('#salesBody .salesRow:not(.template-row)');
            const row = rows[rows.length - 1];

            // Fill product name — user must select batch from dropdown
            const prodInput = row.querySelector('.productInput');
            if (prodInput && item.product_name) prodInput.value = item.product_name;

            if (item.qty || item.quantity) row.querySelector('.qty').value = parseFloat(item.qty || item.quantity);
            if (item.sell_price || item.unit_price) {
                row.querySelector('.sellPrice').value = parseFloat(item.sell_price || item.unit_price || 0).toFixed(2);
            }
            if (item.gst_percent) {
                row.querySelector('.gstPercent').textContent = parseFloat(item.gst_percent);
            }
            if (item.description) {
                const ta = row.querySelector('textarea[name="description[]"]');
                if (ta) ta.value = item.description;
            }
            recalcRow(row);
        });
        msgs.push('✓ ' + items.length + ' item(s) filled — please select batch for each row');
    }

    statusEl.innerHTML = msgs.map(m => '<div style="margin-bottom:3px;">' + m + '</div>').join('');
    if (items.length > 0) {
        statusEl.innerHTML += '<div style="margin-top:8px;padding:8px 10px;background:#fffbeb;border:1px solid #fde68a;border-radius:5px;font-size:12px;color:#92400e;">'
            + '<i class="fas fa-info-circle" style="margin-right:5px;"></i>Click each product row\'s Batch cell to pick the correct stock batch before saving.</div>';
    }
    setTimeout(() => closeAiModal(), 500);
}

/* ---- Quick Add to Bill (master) ---- */
document.getElementById('quickAddBtnMaster').addEventListener('click', function() {
    if (!_quickBatch || !_quickBatch.pid) {
        showMasterQuickMsg('Please search and select a product first.');
        return;
    }
    const pid = parseInt(_quickBatch.pid);
    const dup = checkDuplicateMaster(pid, null);
    if (dup !== null) {
        showMasterQuickMsg('Product already added in row ' + dup + '.');
        return;
    }
    const qty = parseFloat(document.getElementById('quickQtyMaster').value) || 1;
    addRow();
    const rows = document.querySelectorAll('#salesBody .salesRow:not(.template-row)');
    const newRow = rows[rows.length - 1];
    const colors = _quickBatch.cobg.split(':');

    newRow.querySelector('.productInput').value                    = _quickBatch.pname;
    newRow.querySelector('input[name="product_id[]"]').value       = _quickBatch.pid;
    newRow.querySelector('input[name="purchase_item_id[]"]').value = _quickBatch.piid;
    newRow.querySelector('input[name="item_company_id[]"]').value  = _quickBatch.coid;

    const batchCell = newRow.querySelector('.batch-info');
    batchCell.innerHTML = _quickBatch.batch + ' <i class="fas fa-pen" style="font-size:9px;color:var(--text-muted);margin-left:3px;opacity:.7;"></i>';
    batchCell.dataset.pid  = _quickBatch.pid;
    batchCell.style.cursor = 'pointer';
    batchCell.title        = 'Click to change batch';

    newRow.querySelector('.mrp').textContent         = parseFloat(_quickBatch.mrp).toFixed(2);
    newRow.querySelector('.availQty').textContent    = _quickBatch.avail;
    newRow.querySelector('.gstPercent').textContent  = _quickBatch.gst;
    newRow.querySelector('.sellPrice').value         = parseFloat(_quickBatch.price).toFixed(2);
    newRow.querySelector('.qty').value               = qty;

    const badge = newRow.querySelector('.co-badge');
    badge.textContent      = _quickBatch.copfx;
    badge.style.background = colors[0];
    badge.style.color      = colors[1];

    recalcRow(newRow);
    updateRowNums();

    _quickBatch = null;
    document.getElementById('quickSearchMaster').value = '';
    document.getElementById('quickQtyMaster').value    = '1';
    document.getElementById('quickSearchMaster').focus();
});

/* ---- Form validation ---- */
document.getElementById('masterForm').addEventListener('submit', function(e) {
    if (!document.getElementById('clientId').value) {
        e.preventDefault();
        alert('Please select a client.');
        document.getElementById('clientSearch').focus();
        return;
    }
    const rows = document.querySelectorAll('#salesBody .salesRow:not(.template-row)');
    let hasItem = false;
    rows.forEach(r => { if (r.querySelector('input[name="purchase_item_id[]"]').value) hasItem = true; });
    if (!hasItem) { e.preventDefault(); alert('Please add at least one product.'); }
});
</script>

<!-- AI Extract Modal -->
<div id="aiModal" style="display:none;position:fixed;inset:0;background:rgba(0,0,0,.45);z-index:3000;align-items:center;justify-content:center;">
    <div style="background:#fff;border-radius:10px;padding:28px;width:480px;max-width:95vw;box-shadow:0 8px 40px rgba(0,0,0,.2);">
        <div style="display:flex;align-items:center;justify-content:space-between;margin-bottom:18px;">
            <h3 style="margin:0;font-size:16px;"><i class="fas fa-magic" style="color:#7c3aed;margin-right:8px;"></i>AI Extract from Invoice</h3>
            <button type="button" onclick="closeAiModal()" style="background:none;border:none;font-size:18px;cursor:pointer;color:var(--text-muted);">&times;</button>
        </div>
        <div class="form-group">
            <label style="font-size:13px;font-weight:500;margin-bottom:6px;display:block;">Upload Invoice Image (JPG/PNG/WebP)</label>
            <input type="file" id="aiFile" accept="image/*,.pdf" style="width:100%;padding:8px;border:1px solid var(--border);border-radius:6px;font-size:13px;">
        </div>
        <div id="aiStatus" style="display:none;margin-top:12px;font-size:13px;line-height:1.7;padding:10px 12px;background:#f0f7ff;border-radius:6px;border:1px solid #bfdbfe;"></div>
        <div style="display:flex;gap:10px;justify-content:flex-end;margin-top:16px;">
            <button type="button" class="btn btn-secondary" onclick="closeAiModal()">Cancel</button>
            <button type="button" class="btn btn-primary" onclick="runAiExtract()" style="background:#7c3aed;border-color:#7c3aed;">
                <i class="fas fa-magic" style="margin-right:6px;"></i>Extract
            </button>
        </div>
    </div>
</div>

<style>
.cdd-item { padding:8px 12px;cursor:pointer;font-size:13px;border-bottom:1px solid #f0f0f0; }
.cdd-item:hover { background:var(--bg-light); }
.cdd-add { color:var(--success);font-weight:500;border-top:2px solid #f0f0f0;border-bottom:none; }
.compact-sales-table td, .compact-sales-table th { padding:5px 6px; }
.compact-sales-table input[type="number"],
.compact-sales-table input[type="text"] { padding:4px 6px;font-size:12px; }
.compact-sales-table select { padding:3px 4px;font-size:12px; }
/* Description toggle */
.prod-desc-wrap { display:none; }
#salesTable.show-desc .prod-desc-wrap { display:block; }
</style>

<?php require_once '../includes/footer.php'; ?>
