<?php
// files/invoiceUnPaid_reports.php

$image = 'images/company/logo.jpg';
$src = '';

    $path = '../' . TENANT_URL . '/images/company/logo.jpg';
    if (is_file($path)) {
        $imageData = base64_encode(file_get_contents($path));
        $src = 'data:image/jpeg;base64,' . $imageData;
    }


function h($s)
{
    return htmlspecialchars((string)$s, ENT_QUOTES, 'UTF-8');
}
function gbp2($v)
{
    return number_format((float)$v, 2);
}

// Filter lists from active rows
$clients = [];
$agents  = [];
$brokers = [];

$qC = $GLOBALS['con']->query("SELECT clientnumber, clientname FROM clientdetails WHERE statuslive=1 ORDER BY clientname ASC");
while ($r = $qC->fetch_assoc()) {
    $clients[(int)$r['clientnumber']] = $r['clientname'];
}

$qA = $GLOBALS['con']->query("SELECT agent_number, agent_name FROM agents WHERE statuslive=1 ORDER BY agent_name ASC");
while ($r = $qA->fetch_assoc()) {
    $agents[(int)$r['agent_number']] = $r['agent_name'];
}

$qB = $GLOBALS['con']->query("SELECT broker_number, broker_name FROM brokers WHERE statuslive=1 ORDER BY broker_name ASC");
while ($r = $qB->fetch_assoc()) {
    $brokers[(int)$r['broker_number']] = $r['broker_name'];
}

// Unpaid invoices (status = 0)
$stmt = $GLOBALS['con']->prepare("
    SELECT invNo, client, agent, broker, totals, commission, date, date_due
    FROM invoices
    WHERE status = 1
    ORDER BY ABS(invNo) ASC
");
$stmt->execute();
$rs = $stmt->get_result();
$stmt->close();

// Name helpers
function getClientNameLocal(int $id): string
{
    $stmt = $GLOBALS['con']->prepare("SELECT clientname FROM clientdetails WHERE clientnumber=?");
    $stmt->bind_param('i', $id);
    $stmt->execute();
    $res = $stmt->get_result();
    $stmt->close();
    $row = $res->fetch_assoc();
    return $row['clientname'] ?? '';
}
function getAgentNameLocal(?int $id): string
{
    if (!$id) return '';
    $stmt = $GLOBALS['con']->prepare("SELECT agent_name FROM agents WHERE agent_number=?");
    $stmt->bind_param('i', $id);
    $stmt->execute();
    $res = $stmt->get_result();
    $stmt->close();
    $row = $res->fetch_assoc();
    return $row['agent_name'] ?? '';
}
function getBrokerNameLocal(?int $id): string
{
    if (!$id) return '';
    $stmt = $GLOBALS['con']->prepare("SELECT broker_name FROM brokers WHERE broker_number=?");
    $stmt->bind_param('i', $id);
    $stmt->execute();
    $res = $stmt->get_result();
    $stmt->close();
    $row = $res->fetch_assoc();
    return $row['broker_name'] ?? '';
}

// Build rows
$rows = [];
while ($r = $rs->fetch_assoc()) {
    $t = explode('|', (string)$r['totals']); // [net|vat]
    $net = (float)str_replace(',', '', $t[0] ?? '0');
    $vat = (float)str_replace(',', '', $t[1] ?? '0');
    $com = (float)str_replace(',', '', (string)$r['commission']);

    $clientId = (int)$r['client'];
    $agentId  = (int)($r['agent'] ?? 0);
    $brokerId = (int)($r['broker'] ?? 0);

    $rows[] = [
        'invoice'    => sprintf("%06d", (int)$r['invNo']),
        'client'     => getClientNameLocal($clientId),
        'agent'      => getAgentNameLocal($agentId),
        'broker'     => getBrokerNameLocal($brokerId),
        'net_disp'   => gbp2($net),
        'vat_disp'   => gbp2($vat),
        'com_disp'   => gbp2($com),
        'net_num'    => $net,
        'vat_num'    => $vat,
        'com_num'    => $com,
        'clientId'   => $clientId,
        'agentId'    => $agentId,
        'brokerId'   => $brokerId,
        'link'       => "index.php?t=includes/master&p=invoice_view.php&inv=" . (int)$r['invNo'] . "&tenant=" . rawurlencode(TENANT_URL),
    ];
}
?>
<div class="container-fluid">
    <div class="d-flex flex-column flex-md-row justify-content-between align-items-start mb-3 px-3">
        <div class="mb-2 mb-md-0">

            <div class="note note-light mb-3"> <strong>View, print, download or email outstanding invoices. Filter results by client, agent or broker.</div>

        </div>

    </div>

    <div class="row g-3 align-items-end">
        <div class="col-12 col-md-3">
            <label for="fltClient" class="form-label">Client</label>
            <select id="fltClient" class="form-select" data-mdb-select-init>
                <option value="">All clients</option>
                <?php foreach ($clients as $id => $name): ?>
                <option value="<?= (int)$id ?>"><?= h($name) ?></option>
                <?php endforeach; ?>
            </select>
        </div>
        <div class="col-12 col-md-3">
            <label for="fltAgent" class="form-label">Agent</label>
            <select id="fltAgent" class="form-select" data-mdb-select-init>
                <option value="">All agents</option>
                <?php foreach ($agents as $id => $name): ?>
                <option value="<?= (int)$id ?>"><?= h($name) ?></option>
                <?php endforeach; ?>
            </select>
        </div>
        <div class="col-12 col-md-3">
            <label for="fltBroker" class="form-label">Broker</label>
            <select id="fltBroker" class="form-select" data-mdb-select-init>
                <option value="">All brokers</option>
                <?php foreach ($brokers as $id => $name): ?>
                <option value="<?= (int)$id ?>"><?= h($name) ?></option>
                <?php endforeach; ?>
            </select>
        </div>
        <div class="col-12 col-md-3">
            <button id="clearFilters" class="btn btn-info w-100" data-mdb-tooltip-init data-mdb-placement="top"
                    data-mdb-trigger="hover" title="Clear filters">
                <i class="fad fa-broom"></i> Clear filters
            </button>
        </div>
    </div>



    <!-- MDB previously rendered a DIV; we will inject a TABLE at runtime into this container -->
    <div id="exportTitle">Outstanding invoices</div>
    <div id="unpaidTableContainer"></div>
    <div id="tableWrapper" class="d-none"></div>
</div>

<script>
function cellText(html) {
    const d = document.createElement('div');
    d.innerHTML = html == null ? '' : String(html);
    return d.textContent || d.innerText || '';
}

// Email PDF from current DataTable view (no links)
async function emailUnpaidPdf(dt, buttonEl) {
    const title = document.getElementById('exportTitle')?.textContent || 'Outstanding invoices';

    // use all filtered rows; change page:'all' -> 'current' if needed
    const idx = dt.rows({
        search: 'applied',
        page: 'all'
    }).indexes().toArray();

    // headers
    const header = ['Invoice', 'Client', 'Agent', 'Broker', 'Net', 'VAT', 'Commission'];
    const body = [header.map(h => ({
        text: h,
        bold: true
    }))];

    // sums from hidden numeric columns
    const sum = name => dt.column(name + ':name', {
            search: 'applied'
        }).data()
        .reduce((a, b) => a + (parseFloat(b) || 0), 0);
    const fmt = n => Number(n).toLocaleString('en-GB', {
        minimumFractionDigits: 2,
        maximumFractionDigits: 2
    });

    // build rows from visible columns 0..6, stripping tags
    idx.forEach(r => {
        const row = [];
        for (let c = 0; c <= 6; c++) {
            const val = dt.cell(r, c).render('display'); // whatever is shown
            row.push(cellText(val)); // strip any HTML (links)
        }
        // right-align numeric columns (last 3) by wrapping with style later
        body.push([
            row[0], row[1], row[2], row[3],
            {
                text: row[4],
                alignment: 'right'
            },
            {
                text: row[5],
                alignment: 'right'
            },
            {
                text: row[6],
                alignment: 'right'
            }
        ]);
    });

    // totals row
    body.push([{
            text: 'Totals',
            colSpan: 4,
            alignment: 'right',
            bold: true
        }, '', '', '',
        {
            text: fmt(sum('net_n')),
            alignment: 'right',
            bold: true
        },
        {
            text: fmt(sum('vat_n')),
            alignment: 'right',
            bold: true
        },
        {
            text: fmt(sum('com_n')),
            alignment: 'right',
            bold: true
        }
    ]);

    // pdfMake doc
    const headerCells = ['Invoice', 'Client', 'Agent', 'Broker', 'Net', 'VAT', 'Commission']
        .map(t => ({
            text: t,
            style: 'th'
        }));

    const doc = {
        pageSize: 'A4',
        pageOrientation: 'landscape',
        pageMargins: [20, 70, 20, 30], // bigger top/bottom to fit header/footer
        header: () => ({
            margin: [20, 10, 20, 0],
            columns: [
                // Left: logo (fixed width)
                <?php if (!empty($src)) { ?> {
                    image: <?= json_encode($src) ?>,
                    width: 100,
                    alignment: 'left'
                },
                <?php } else { ?> {
                    text: '',
                    width: 100
                }, // reserve space even if no logo
                <?php } ?>
                // Center: title (flexible)
                {
                    text: (document.getElementById('exportTitle')?.textContent || 'Outstanding invoices'),
                    alignment: 'center',
                    fontSize: 16,
                    bold: true,
                    margin: [0, 20, 0, 0],
                    width: '*'
                },
                // Right: empty spacer matching logo width
                {
                    text: '',
                    width: 100
                }
            ],
            columnGap: 10
        }),
        footer: () => ({
            margin: [20, 0, 20, 10],
            columns: [{
                alignment: 'center',
                text: 'Generated by EnRep Reporting System: <?= date('d-m-Y') ?>'
            }]
        }),
        styles: {
            th: {
                bold: true,
                fillColor: '#eeeeee',
                fontSize: 9,
                margin: [4, 4, 4, 4]
            },
            td: {
                fontSize: 8.5,
                margin: [4, 3, 4, 3]
            }
        },
        content: [{
            margin: [0, 8, 0, 0], // small gap under header
            table: {
                headerRows: 1,
                widths: ['*', '*', '*', '*', 90, 90, 100],
                body: [
                    headerCells,
                    ...body.slice(1).map(r => [ // reuse your built rows
                        {
                            text: r[0],
                            style: 'td'
                        },
                        {
                            text: r[1],
                            style: 'td'
                        },
                        {
                            text: r[2],
                            style: 'td'
                        },
                        {
                            text: r[3],
                            style: 'td'
                        },
                        {
                            text: r[4].text || r[4],
                            style: 'td',
                            alignment: 'right'
                        },
                        {
                            text: r[5].text || r[5],
                            style: 'td',
                            alignment: 'right'
                        },
                        {
                            text: r[6].text || r[6],
                            style: 'td',
                            alignment: 'right'
                        }
                    ])
                ]
            },
            layout: {
                fillColor: (rowIndex) => (rowIndex && rowIndex % 2 === 0) ? '#f9f9f9' : null,
                hLineWidth: () => 0.5,
                vLineWidth: () => 0.5,
                hLineColor: () => '#cccccc',
                vLineColor: () => '#cccccc'
            }
        }]
    };

    // 4) make Blob
    const blob = await new Promise(res => pdfMake.createPdf(doc).getBlob(res));

    // 5) upload PDF
    const stamp = new Date().toISOString().replace(/[-:T.]/g, '').slice(0, 14);
    const filename = `${title.replace(/\s+/g,'_')}_${stamp}.pdf`;

    const fd = new FormData();
    fd.append('pdf', blob, filename); // common server key
    fd.append('file', blob, filename); // fallback key
    fd.append('tenant', TENANT_URL); // required in all processing scripts

    const upRes = await fetch(`${ROOT_URL}/functions/upload_pdf.php`, {
        method: 'POST',
        body: fd
    });

    let up;
    try {
        up = await upRes.json();
    } catch {
        up = {};
    }

    if (!upRes.ok) {
        showResponse('danger', `Upload failed (${upRes.status})`);
        return;
    }

    // normalise server response keys
    const filePath = up.filePath || up.filepath || up.path || up.url || '';
    const fileName = up.fileName || up.filename || up.name || filename;

    if (!filePath) {
        showResponse('danger', 'Upload returned no path');
        return;
    }

    // 6) open mailer
    const el = buttonEl;
    const payload = {
        clientNumber: el.dataset.clientNumber || '',
        clientName: el.dataset.clientName || '',
        primaryEmail: el.dataset.primaryEmail || '',
        secondaryEmail: el.dataset.secondaryEmail || '',
        subject: el.dataset.subject || title,
        message: el.dataset.message || title,
        filePath,
        fileName,
        invoiceNumber: el.dataset.invoiceNumber || '',
        addressMode: 'billing',
        mode: el.dataset.mode || 'emailUnpaid'
    };

    const encoded = encodeURIComponent(JSON.stringify(payload));
    const dest = `${ROOT_URL}/includes/master/financeMailer.php?mode=popup&data=${encoded}&tenant=${TENANT_URL}`;
    loadModalContent(dest, "mailerBox", "modal-xl", 1060, "true", "Email Invoice", "", '');

}

document.getElementById('navBox').innerHTML =
    '<li class="breadcrumb-item"><a href="index.php?t=includes/finance&p=finance_invoices.php">Finance - Invoices</a> <i class="fad fa-angle-double-right mx-2 mt-1"></i></li><li class="breadcrumb-item"><a href="index.php?t=includes/finance&p=finance_unpaid.php">Outstanding</a> <i class="fad fa-angle-double-right mx-2 mt-1"></i></li><li class="breadcrumb-item active">Outstanding Report</li>';

const UNPAID_ROWS = <?php echo json_encode($rows, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES); ?>;

document.addEventListener('DOMContentLoaded', () => {
    // build table markup at runtime
    const wrap = document.getElementById('unpaidTableContainer');
    const tbl = document.createElement('table');
    tbl.id = 'unpaidTable';
    tbl.className = 'table table-striped table-hover mb-0 align-middle table-sm';
    tbl.innerHTML = `
    <thead class="table-light">
      <tr>
        <th style="width:100px">Invoice</th><th>Client</th><th>Agent</th><th>Broker</th>
        <th class="text-end">Net</th><th class="text-end">VAT</th><th class="text-end">Commission</th>
      </tr>
    </thead>
    <tfoot class="bg-dark text-light">
      <tr>
        <th class="text-end text-light" colspan="4">Totals</th>
        <th class="text-end text-light" id="totNet">0.00</th>
        <th class="text-end text-light" id="totVAT">0.00</th>
        <th class="text-end text-light" id="totCom">0.00</th>
      </tr>
    </tfoot>
    <tbody></tbody>`;
    wrap.appendChild(tbl);

    const rows = UNPAID_ROWS.map(r => ({
        invoice: r.invoice,
        client: r.client || '',
        agent: r.agent || '',
        broker: r.broker || '',
        net_disp: Number(r.net_num).toLocaleString('en-GB', {
            minimumFractionDigits: 2,
            maximumFractionDigits: 2
        }),
        vat_disp: Number(r.vat_num).toLocaleString('en-GB', {
            minimumFractionDigits: 2,
            maximumFractionDigits: 2
        }),
        com_disp: Number(r.com_num).toLocaleString('en-GB', {
            minimumFractionDigits: 2,
            maximumFractionDigits: 2
        }),
        net_num: r.net_num,
        vat_num: r.vat_num,
        com_num: r.com_num,
        clientId: r.clientId,
        agentId: r.agentId,
        brokerId: r.brokerId,
        link: r.link
    }));

    const dt = new DataTable('#unpaidTable', {
        data: rows,
        columns: [{
                title: 'Invoice',
                data: 'invoice',
                name: 'invoice',
                render: (d, t, row) => `<a href="${row.link}" class="text-decoration-none">${d}</a>`
            },
            {
                title: 'Client',
                data: 'client',
                name: 'client'
            },
            {
                title: 'Agent',
                data: 'agent',
                name: 'agent'
            },
            {
                title: 'Broker',
                data: 'broker',
                name: 'broker'
            },
            {
                title: 'Net',
                data: 'net_disp',
                name: 'net_disp',
                className: 'text-end'
            },
            {
                title: 'VAT',
                data: 'vat_disp',
                name: 'vat_disp',
                className: 'text-end'
            },
            {
                title: 'Commission',
                data: 'com_disp',
                name: 'com_disp',
                className: 'text-end'
            },
            {
                data: 'net_num',
                name: 'net_n',
                visible: false
            },
            {
                data: 'vat_num',
                name: 'vat_n',
                visible: false
            },
            {
                data: 'com_num',
                name: 'com_n',
                visible: false
            },
            {
                data: 'clientId',
                name: 'client_id',
                visible: false
            },
            {
                data: 'agentId',
                name: 'agent_id',
                visible: false
            },
            {
                data: 'brokerId',
                name: 'broker_id',
                visible: false
            }
        ],
        select: {
            style: 'multi'
        },
        layout: {
            topStart: {
                buttons: [{
                        text: '<i class="fad fa-print duoBlue"></i> Print Report',
                        className: 'me-2',
                        action: (e, api) => {
                            const content = generatePrintContent(api);
                            insertContentIntoWrapper(content);
                            printContainer('tableWrapper', {
                                orientation: 'landscape',
                                header: '<p>' + document.getElementById('exportTitle')
                                    .textContent + '</p>',
                                footer: '<p>Generated by EnRep Reporting System: <?= date('d-m-Y') ?>',
                                styles: [ROOT_URL + '/src/css/print.css'],
                                logoUrl: '<?= $image ?>'

                            });
                        }
                    },

                    {
                        extend: 'pdfHtml5',
                        footer: true,
                        title: $('#exportTitle').text(),
                        filename: $('#exportTitle').text().replace(/ /g, ""),
                        text: '<i class="fad fa-file-pdf duoRed"></i> Download Report',
                        orientation: 'landscape',
                        pageSize: 'A4',
                        className: 'me-2',
                        exportOptions: {
                            columns: "thead th:not(.noExport)",
                            modifier: {
                                page: 'current',
                                orthogonal: 'export'
                            }
                        },
                        customize: function(doc) {
                            doc.pageMargins = [20, 20, 40, 20];
                            doc.styles.tableHeader.alignment = 'left';

                            const logoData = <?= json_encode($src) ?>;
                            doc.header = () => ({
                                columns: [{
                                    image: logoData,
                                    width: 100
                                }],
                                margin: 10
                            });
                            doc.footer = (page, pages) => ({
                                columns: [{
                                    alignment: 'center',
                                    text: 'Generated by EnRep Reporting System: <?= date('d-m-Y') ?>'
                                }],
                                margin: [10, 0]
                            });

                            // Stretch table to full width
                            const tbl = doc.content.find(c => c.table);
                            if (tbl) {
                                const cols = tbl.table.body[0].length;
                                tbl.table.widths = Array(cols).fill('*'); // full-width distribution

                                // right-align numeric columns (last 3)
                                const rightCols = [cols - 3, cols - 2, cols - 1];
                                tbl.table.body.forEach((row, i) => {
                                    row.forEach((cell, j) => {
                                        if (rightCols.includes(j)) {
                                            if (typeof cell === 'string') row[j] = {
                                                text: cell,
                                                alignment: 'right'
                                            };
                                            else cell.alignment = 'right';
                                        }
                                    });
                                });
                            }
                        }

                    },
                    {
                        text: '<i class="fad fa-paperclip me-1"></i> Email Report',
                        className: 'me-2',
                        action: (e, dt, node) => emailUnpaidPdf(dt, node[0] || node)
                    }


                ]
            }
        },
        responsive: true,
        autoWidth: false,
        order: [
            [0, 'asc']
        ]
    });

    // footer totals
    const fmt = n => Number(n).toLocaleString('en-GB', {
        minimumFractionDigits: 2,
        maximumFractionDigits: 2
    });

    function recalc() {
        const sum = name => dt.column(name + ':name', {
                search: 'applied'
            }).data()
            .reduce((a, b) => a + (parseFloat(b) || 0), 0);
        document.getElementById('totNet').textContent = fmt(sum('net_n'));
        document.getElementById('totVAT').textContent = fmt(sum('vat_n'));
        document.getElementById('totCom').textContent = fmt(sum('com_n'));
    }
    dt.on('draw', recalc);
    recalc();

    // filters
    const fltClient = document.getElementById('fltClient');
    const fltAgent = document.getElementById('fltAgent');
    const fltBroker = document.getElementById('fltBroker');
    const clearBtn = document.getElementById('clearFilters');

    function applyFilters() {
        dt.column('client_id:name').search(fltClient.value ? '^' + fltClient.value + '$' : '', true, false)
            .column('agent_id:name').search(fltAgent.value ? '^' + fltAgent.value + '$' : '', true, false)
            .column('broker_id:name').search(fltBroker.value ? '^' + fltBroker.value + '$' : '', true, false)
            .draw();
    }
    fltClient.addEventListener('change', applyFilters);
    fltAgent.addEventListener('change', applyFilters);
    fltBroker.addEventListener('change', applyFilters);
    clearBtn.addEventListener('click', () => {
        fltClient.value = '';
        fltAgent.value = '';
        fltBroker.value = '';
        applyFilters();
    });
});


function generatePrintContent(dt) {
    // columns 0..6 visible; last 3 are money
    const headers = Array.from(document.querySelectorAll('#unpaidTable thead th'))
        .filter(th => !th.classList.contains('noExport'))
        .map(th => th.textContent.trim());

    const rowIdx = dt.rows({
        search: 'applied',
        page: 'current'
    }).indexes().toArray();

    const cellText = (html) => {
        const d = document.createElement('div');
        d.innerHTML = html == null ? '' : String(html);
        return d.textContent || d.innerText || '';
    };

    const fmt = n => Number(n).toLocaleString('en-GB', {
        minimumFractionDigits: 2,
        maximumFractionDigits: 2
    });
    const sum = name => dt.column(name + ':name', {
            search: 'applied'
        }).data()
        .reduce((a, b) => a + (parseFloat(b) || 0), 0);

    let html = '<table class="table table-striped table-sm table-bordered table-hover" style="width:100%"><thead><tr>';
    headers.forEach(h => {
        html += `<th>${h}</th>`;
    });
    html += '</tr></thead><tbody>';

    rowIdx.forEach(r => {
        html += '<tr>';
        for (let c = 0; c <= 6; c++) {
            const val = cellText(dt.cell(r, c).render('display'));
            const align = (c >= 4) ? ' style="text-align:right"' : '';
            html += `<td${align}>${val}</td>`;
        }
        html += '</tr>';
    });

    html += '</tbody>';

    // tfoot totals: colspan 4 + 3 numeric cells
    const totNet = fmt(sum('net_n'));
    const totVAT = fmt(sum('vat_n'));
    const totCom = fmt(sum('com_n'));

    html += `<tfoot><tr>
    <th colspan="4" style="text-align:right">Totals</th>
    <th style="text-align:right">${totNet}</th>
    <th style="text-align:right">${totVAT}</th>
    <th style="text-align:right">${totCom}</th>
  </tr></tfoot>`;

    html += '</table>';
    return html;
}



function insertContentIntoWrapper(content) {
    const wrapper = document.getElementById('tableWrapper');
    if (wrapper) {
        wrapper.innerHTML = content;
    }
}
</script>