<?php
defined('BASEPATH') or exit('No direct script access allowed');

if (!function_exists('report_pdf_total_rows')) {
    /**
     * Total row count for PDF "Total Records" when exporting in Dompdf chunks.
     * Prefer $pdf_total_rows (full set); fall back to count($report) for small/single PDFs.
     *
     * @param mixed $report
     * @param mixed $pdf_total_rows
     * @return int
     */
    function report_pdf_total_rows($report, $pdf_total_rows = null)
    {
        if ($pdf_total_rows !== null && $pdf_total_rows !== '') {
            return (int) $pdf_total_rows;
        }
        return is_array($report) ? count($report) : 0;
    }
}

if (!function_exists('report_cell')) {
    /**
     * Read a value from object/array row by property name (supports Acc_No.).
     */
    function report_cell($row, $key)
    {
        if (is_array($row)) {
            return isset($row[$key]) ? $row[$key] : '';
        }
        if (is_object($row)) {
            if (property_exists($row, $key) || isset($row->$key)) {
                return $row->$key;
            }
            // checkout / circulation report uses Acc_No. with trailing dot
            if ($key === 'Acc_No' && isset($row->{'Acc_No.'})) {
                return $row->{'Acc_No.'};
            }
            // keys with dots e.g. S.No.
            if (isset($row->{$key})) {
                return $row->{$key};
            }
        }
        return '';
    }
}

if (!function_exists('report_rows_to_array')) {
    function report_rows_to_array($rows)
    {
        if (empty($rows)) {
            return array();
        }
        $out = array();
        foreach ($rows as $row) {
            $out[] = is_array($row) ? $row : (array) $row;
        }
        return $out;
    }
}

if (!function_exists('report_export_logo_file')) {
    /**
     * Resolve logo relative path to absolute file + mime + binary data.
     * @return array{path:string,mime:string,data:string}|null
     */
    function report_export_logo_file($relative_path, $fallback_relative = '')
    {
        $candidates = array();
        $relative_path = trim((string) $relative_path);
        if ($relative_path !== '') {
            $candidates[] = $relative_path;
            // Session sometimes stores full URL or absolute path
            if (preg_match('#https?://#i', $relative_path)) {
                $path = parse_url($relative_path, PHP_URL_PATH);
                if ($path) {
                    $candidates[] = ltrim($path, '/');
                }
            }
        }
        if ($fallback_relative !== '') {
            $candidates[] = $fallback_relative;
        }

        foreach ($candidates as $rel) {
            $rel = str_replace('\\', '/', $rel);
            $rel = ltrim($rel, '/');
            // Strip leading app folder if present in URL path
            if (stripos($rel, 'kohareport/') === 0) {
                $rel = substr($rel, strlen('kohareport/'));
            }

            $try_rels = array($rel);
            if (preg_match('#(?:^|/)(uploads/.+)$#i', $rel, $um)) {
                $try_rels[] = $um[1];
            }

            foreach ($try_rels as $try) {
                $full = rtrim(FCPATH, '/\\') . DIRECTORY_SEPARATOR . str_replace('/', DIRECTORY_SEPARATOR, $try);
                if (!is_file($full) || !is_readable($full)) {
                    continue;
                }
                $ext = strtolower(pathinfo($full, PATHINFO_EXTENSION));
                $mime = 'image/png';
                if ($ext === 'jpg' || $ext === 'jpeg') {
                    $mime = 'image/jpeg';
                } elseif ($ext === 'gif') {
                    $mime = 'image/gif';
                } elseif ($ext === 'webp') {
                    // Word/Excel may not support webp — prefer png sibling if exists
                    $png = preg_replace('/\.webp$/i', '.png', $full);
                    if ($png && is_file($png)) {
                        $full = $png;
                        $mime = 'image/png';
                    } else {
                        $mime = 'image/webp';
                    }
                }
                $data = @file_get_contents($full);
                if ($data === false || $data === '') {
                    continue;
                }
                return array(
                    'path' => $full,
                    'mime' => $mime,
                    'data' => $data,
                );
            }
        }
        return null;
    }
}

if (!function_exists('report_export_src_to_relative')) {
    /**
     * Convert absolute URL / file path / relative path to FCPATH-relative path.
     */
    function report_export_src_to_relative($src)
    {
        $src = trim(html_entity_decode((string) $src, ENT_QUOTES, 'UTF-8'));
        if ($src === '') {
            return '';
        }
        if (preg_match('#^data:#i', $src)) {
            return '';
        }
        if (preg_match('#^cid:#i', $src)) {
            return '';
        }

        // file:///C:/... or absolute filesystem path
        if (preg_match('#^file:///#i', $src)) {
            $src = preg_replace('#^file:///#i', '', $src);
            $src = str_replace('/', DIRECTORY_SEPARATOR, $src);
        }
        if (preg_match('#^[a-zA-Z]:[\\\\/]#', $src) || (isset($src[0]) && ($src[0] === '/' || $src[0] === '\\'))) {
            $fc = rtrim(str_replace('\\', '/', FCPATH), '/');
            $norm = str_replace('\\', '/', $src);
            if (stripos($norm, $fc . '/') === 0) {
                return ltrim(substr($norm, strlen($fc)), '/');
            }
        }

        if (preg_match('#https?://#i', $src)) {
            $path = parse_url($src, PHP_URL_PATH);
            $src = $path ? $path : $src;
        }

        $src = str_replace('\\', '/', $src);
        $src = ltrim($src, '/');

        // Strip known app prefixes from URL path
        foreach (array('index.php/', 'kohareport/') as $prefix) {
            if (stripos($src, $prefix) === 0) {
                $src = substr($src, strlen($prefix));
            }
        }

        if (preg_match('#(?:^|/)(uploads/.+)$#i', $src, $m)) {
            return $m[1];
        }

        return $src;
    }
}

if (!function_exists('report_export_html_embed_local_images')) {
    /**
     * Replace local/remote app image URLs (and data-URIs) with cid: refs for MHTML.
     * @return array{html:string,images:array}
     */
    function report_export_html_embed_local_images($html, $existing_images = array())
    {
        $images = is_array($existing_images) ? $existing_images : array();
        $counter = 0;

        $html = preg_replace_callback(
            '/<img\b([^>]*?)src\s*=\s*(["\'])([^"\']+)\2([^>]*)>/i',
            function ($m) use (&$images, &$counter) {
                $before = $m[1];
                $after = $m[4];
                $src = html_entity_decode($m[3], ENT_QUOTES, 'UTF-8');

                if (stripos($src, 'cid:') === 0) {
                    return $m[0];
                }

                $file = null;
                if (preg_match('#^data:(image/[a-zA-Z0-9.+-]+);base64,(.+)$#s', $src, $dm)) {
                    $bin = base64_decode($dm[2]);
                    if ($bin !== false && $bin !== '') {
                        $file = array(
                            'path' => '',
                            'mime' => $dm[1],
                            'data' => $bin,
                        );
                    }
                } else {
                    $rel = report_export_src_to_relative($src);
                    if ($rel !== '') {
                        $file = report_export_logo_file($rel, '');
                        // Prefer png sibling for webp URLs even if webp file resolved
                        if ($file && !empty($file['path']) && preg_match('/\.webp$/i', $rel)) {
                            $png_rel = preg_replace('/\.webp$/i', '.png', $rel);
                            $png_file = report_export_logo_file($png_rel, '');
                            if ($png_file) {
                                $file = $png_file;
                            }
                        }
                    }
                }

                if (!$file) {
                    return $m[0];
                }

                $counter++;
                $cid = 'embed_img_' . $counter;
                $images[$cid] = $file;
                return '<img' . $before . 'src="cid:' . $cid . '"' . $after . '>';
            },
            $html
        );

        return array(
            'html' => $html,
            'images' => $images,
        );
    }
}

if (!function_exists('report_export_build_mhtml')) {
    /**
     * Build multipart MHTML so Word/Excel can show embedded CID images.
     *
     * @param string $body_html
     * @param array  $embedded_images
     * @param string $extra_styles
     * @param string $page_css Optional @page / section CSS
     */
    function report_export_build_mhtml($body_html, $embedded_images = array(), $extra_styles = '', $page_css = '')
    {
        $CI =& get_instance();
        $CI->load->helper('settings');
        $office_font = app_font_office();

        if ($page_css === '') {
            $page_css = '@page WordSection1 { size: 297mm 210mm; margin: 10mm 8mm; mso-page-orientation: landscape; }'
                . 'div.WordSection1 { page: WordSection1; }';
        }

        $styles = $page_css
            . 'body, body *, table, td, th, p, div, span, li, h1, h2, h3, h4, h5, h6 {'
            . 'font-family: ' . $office_font . ' !important; }'
            . 'body { font-size: 11pt; background:#ffffff; color:#111111; }'
            . 'table.header-table { width:100%; border-collapse:collapse; border:none; margin:0 0 12px 0; table-layout:fixed; background:#ffffff; }'
            . 'table.header-table td { border:none !important; vertical-align:middle; padding:4px; background:#ffffff; color:#111111; }'
            . 'img.krc-logo, img.dlrl-logo { width:70px; height:auto; border:0; }'
            . 'p.header-title { font-size:16px; line-height:20px; margin:0; padding:0; font-weight:bold; color:#111111; }'
            . 'p.header-subtitle { font-size:14px; line-height:18px; margin:3px 0 0 0; padding:0; font-weight:bold; color:#111111; }'
            . 'p.header-location { font-size:12px; line-height:16px; margin:3px 0 0 0; padding:0; font-weight:bold; color:#111111; }'
            . 'table.report-table { border-collapse:collapse; width:100%; table-layout:fixed; }'
            . 'table.report-table th, table.report-table td { border:1px solid #333; padding:5px 6px; vertical-align:top; word-wrap:break-word; font-size:10pt; color:#111; background:#fff; }'
            . 'table.report-table th { background:#f1f5f9; text-align:center; font-weight:bold; }'
            . 'table.report-table.cols-many th, table.report-table.cols-many td { font-size:9pt; padding:4px 5px; }'
            . $extra_styles;

        $doc_html = '<!DOCTYPE html><html xmlns:o="urn:schemas-microsoft-com:office:office" '
            . 'xmlns:w="urn:schemas-microsoft-com:office:word" '
            . 'xmlns:x="urn:schemas-microsoft-com:office:excel" '
            . 'xmlns="http://www.w3.org/TR/REC-html40">'
            . '<head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8">'
            . '<!--[if gte mso 9]><xml><w:WordDocument><w:View>Print</w:View>'
            . '<w:Zoom>100</w:Zoom></w:WordDocument></xml><![endif]-->'
            . '<style>' . $styles . '</style></head>'
            . '<body><div class="WordSection1">' . $body_html . '</div></body></html>';

        $boundary = '----=_NextPart_KRC_' . md5(uniqid((string) mt_rand(), true));

        $qp = function_exists('quoted_printable_encode')
            ? quoted_printable_encode($doc_html)
            : preg_replace('/[^\x20\x09\x0a\x0d\x21-\x3c\x3e-\x7e]/e', 'sprintf("=%02X", ord("$0"))', $doc_html);

        $mhtml = "MIME-Version: 1.0\r\n";
        $mhtml .= 'Content-Type: multipart/related; boundary="' . $boundary . "\"\r\n\r\n";
        $mhtml .= '--' . $boundary . "\r\n";
        $mhtml .= "Content-Type: text/html; charset=\"UTF-8\"\r\n";
        $mhtml .= "Content-Transfer-Encoding: quoted-printable\r\n";
        $mhtml .= "Content-Location: file:///C:/KRC_Report.htm\r\n\r\n";
        $mhtml .= $qp . "\r\n";

        foreach ($embedded_images as $cid => $img) {
            $data = isset($img['data']) ? $img['data'] : '';
            $mime = isset($img['mime']) ? $img['mime'] : 'image/png';
            if ($data === '' || $data === false) {
                continue;
            }
            $mhtml .= '--' . $boundary . "\r\n";
            $mhtml .= 'Content-Type: ' . $mime . "\r\n";
            $mhtml .= "Content-Transfer-Encoding: base64\r\n";
            $mhtml .= 'Content-ID: <' . $cid . ">\r\n";
            $mhtml .= 'Content-Disposition: inline; filename="' . $cid . "\"\r\n\r\n";
            $mhtml .= chunk_split(base64_encode($data), 76, "\r\n") . "\r\n";
        }

        $mhtml .= '--' . $boundary . "--\r\n";
        return $mhtml;
    }
}

if (!function_exists('report_export_logo_src')) {
    /**
     * Prefer base64 data URI for preview HTML; Excel/Word use CID via MHTML instead.
     */
    function report_export_logo_src($relative_path, $fallback_relative = '')
    {
        $file = report_export_logo_file($relative_path, $fallback_relative);
        if ($file) {
            return 'data:' . $file['mime'] . ';base64,' . base64_encode($file['data']);
        }
        $path = $relative_path ?: $fallback_relative;
        return $path ? base_url($path) : '';
    }
}

if (!function_exists('report_export_brand_header')) {
    /**
     * Branding for Excel (data-URI images).
     */
    function report_export_brand_header()
    {
        $CI =& get_instance();
        $logo1 = $CI->session->userdata('logo1');
        $logo2 = $CI->session->userdata('logo2');
        $src1 = report_export_logo_src($logo1, 'uploads/univlogo/KRC_logo.png');
        $src2 = report_export_logo_src($logo2, 'uploads/univlogo/DLRL_logo.png');

        $html = '<table class="header-table" width="100%" cellpadding="0" cellspacing="0" style="width:100%;border-collapse:collapse;border:none;margin:0 0 12px 0;table-layout:fixed;background:#ffffff;">';
        $html .= '<tr>';
        $html .= '<td width="15%" style="width:15%;border:none;text-align:left;vertical-align:middle;padding:0;background:#ffffff;">';
        if ($src1) {
            $html .= '<img src="' . htmlspecialchars($src1) . '" alt="KRC Logo" width="70" style="width:70px;max-width:70px;height:auto;border:0;">';
        }
        $html .= '</td>';
        $html .= '<td width="70%" style="width:70%;border:none;text-align:center;vertical-align:middle;padding:0 8px;background:#ffffff;color:#111111;">';
        $html .= '<p style="font-size:16px;line-height:20px;margin:0;padding:0;font-weight:bold;color:#111111;">Knowledge Resource Centre (KRC)</p>';
        $html .= '<p style="font-size:14px;line-height:18px;margin:3px 0 0 0;padding:0;font-weight:bold;color:#111111;">DLRL</p>';
        $html .= '<p style="font-size:12px;line-height:16px;margin:3px 0 0 0;padding:0;font-weight:bold;color:#111111;">Hyderabad</p>';
        $html .= '</td>';
        $html .= '<td width="15%" style="width:15%;border:none;text-align:right;vertical-align:middle;padding:0;background:#ffffff;">';
        if ($src2) {
            $html .= '<img src="' . htmlspecialchars($src2) . '" alt="DLRL Logo" width="70" style="width:70px;max-width:70px;height:auto;border:0;">';
        }
        $html .= '</td>';
        $html .= '</tr></table>';
        return $html;
    }
}

if (!function_exists('report_export_brand_header_word')) {
    /**
     * Branding for Word MHTML — returns HTML with cid: image refs + binary parts.
     * @return array{html:string,images:array}
     */
    function report_export_brand_header_word()
    {
        $CI =& get_instance();
        $logo1 = $CI->session->userdata('logo1');
        $logo2 = $CI->session->userdata('logo2');
        $file1 = report_export_logo_file($logo1, 'uploads/univlogo/KRC_logo.png');
        $file2 = report_export_logo_file($logo2, 'uploads/univlogo/DLRL_logo.png');

        $images = array();
        $html = '<table class="header-table" width="100%" cellpadding="0" cellspacing="0" style="width:100%;border-collapse:collapse;border:none;margin:0 0 12px 0;table-layout:fixed;background:#ffffff;">';
        $html .= '<tr>';
        $html .= '<td width="15%" style="width:15%;border:none;text-align:left;vertical-align:middle;padding:0;background:#ffffff;">';
        if ($file1) {
            $images['krc_logo'] = $file1;
            $html .= '<img class="krc-logo" src="cid:krc_logo" alt="KRC Logo" width="70" height="70" style="width:70px;height:auto;border:0;">';
        }
        $html .= '</td>';
        $html .= '<td width="70%" style="width:70%;border:none;text-align:center;vertical-align:middle;padding:0 8px;background:#ffffff;color:#111111;">';
        $html .= '<p class="header-title" style="font-size:16px;line-height:20px;margin:0;padding:0;font-weight:bold;color:#111111;">Knowledge Resource Centre (KRC)</p>';
        $html .= '<p class="header-subtitle" style="font-size:14px;line-height:18px;margin:3px 0 0 0;padding:0;font-weight:bold;color:#111111;">DLRL</p>';
        $html .= '<p class="header-location" style="font-size:12px;line-height:16px;margin:3px 0 0 0;padding:0;font-weight:bold;color:#111111;">Hyderabad</p>';
        $html .= '</td>';
        $html .= '<td width="15%" style="width:15%;border:none;text-align:right;vertical-align:middle;padding:0;background:#ffffff;">';
        if ($file2) {
            $images['dlrl_logo'] = $file2;
            $html .= '<img class="dlrl-logo" src="cid:dlrl_logo" alt="DLRL Logo" width="70" height="70" style="width:70px;height:auto;border:0;">';
        }
        $html .= '</td>';
        $html .= '</tr></table>';

        return array(
            'html' => $html,
            'images' => $images,
        );
    }
}

if (!function_exists('report_filter_empty_columns')) {
    /**
     * Keep only columns that have at least one non-empty value across rows.
     * @param array $columns label => key
     * @param array $rows
     * @param array $always_keep keys that must remain (e.g. S_No, Accession_No)
     * @return array label => key
     */
    function report_filter_empty_columns($columns, $rows, $always_keep = array())
    {
        if (!is_array($columns)) {
            return array();
        }
        if (empty($rows)) {
            return $columns;
        }
        $keep = array();
        foreach ($columns as $label => $key) {
            if (in_array($key, $always_keep, true)) {
                $keep[$label] = $key;
                continue;
            }
            $has_value = false;
            foreach ($rows as $row) {
                $val = report_cell($row, $key);
                if ($val !== null && trim((string) $val) !== '') {
                    $has_value = true;
                    break;
                }
            }
            if ($has_value) {
                $keep[$label] = $key;
            }
        }
        return $keep;
    }
}

if (!function_exists('report_itype_profile')) {
    /**
     * Map Koha itemtype code to a catalogue field profile used by barcode range.
     *
     * @param string $itype
     * @return string book|patent|ir|sd|er|application_notes|reports_book|journals|ebook|all
     */
    function report_itype_profile($itype)
    {
        $itype = strtoupper(trim((string) $itype));
        if ($itype === '' || $itype === 'ALL') {
            return 'all';
        }
        $map = array(
            'BK' => 'book',
            'PATENT' => 'patent',
            'IR' => 'ir',
            'SD' => 'sd',
            'ER' => 'er',
            'AL' => 'application_notes',
            'REPORT' => 'reports_book',
            'JRL' => 'journals',
            'EB' => 'ebook',
        );
        return isset($map[$itype]) ? $map[$itype] : 'all';
    }
}

if (!function_exists('report_catalogue_columns')) {
    /**
     * Column label => field key maps aligned with catalogue report layouts.
     *
     * @param string $profile
     * @return array
     */
    function report_catalogue_columns($profile)
    {
        $profile = strtolower(trim((string) $profile));
        switch ($profile) {
            case 'book':
                return array(
                    'Date' => 'Date',
                    'Acc No' => 'Accession_Number',
                    'Author 1' => 'Author_1',
                    'Author 2' => 'Author_2',
                    'Title' => 'Title',
                    'Edition' => 'Edition',
                    'Publisher' => 'Publisher',
                    'Place' => 'Place_of_Pub',
                    'Year' => 'Year',
                    'ISBN' => 'ISBN',
                    'Pages' => 'Pages',
                    'Vol' => 'Vol',
                    'Supplier' => 'Book_Supplier_Name',
                    'Invoice No' => 'Invoice_No',
                    'Invoice Date' => 'Invoice_Date',
                    'Curr Code' => 'Curr_Code',
                    'Price' => 'Price',
                    'Price INR' => 'Price_INR',
                    'Dis%' => 'Dis',
                    'Nature' => 'Nature',
                    'Status' => 'Status',
                    'Remarks' => 'Remarks',
                );
            case 'patent':
                return array(
                    'S.No' => 'S_No',
                    'Acc No' => 'ACCNO',
                    'Author' => 'AUTHOR',
                    'Title' => 'TITLE',
                    'Country' => 'COUNTRY',
                    'Patent No' => 'PATENT_NO',
                    'Subject' => 'SUBJECT',
                );
            case 'ir':
                return array(
                    'S.No' => 'S_No',
                    'Barcode' => 'Barcode',
                    'Title' => 'Title',
                    'Author' => 'Author',
                    'Publication Year' => 'Publication_Year',
                    'Publication Name' => 'Publication_Name',
                    'Period' => 'Period',
                    'Pages' => 'Pages',
                    'PDF Name' => 'PDF_Name',
                    'File Path' => 'File_Path',
                );
            case 'sd':
                return array(
                    'S.No' => 'S_No',
                    'Accession No.' => 'Accession_No',
                    'STANDARDIN' => 'STANDARDIN',
                    'STD NO' => 'STD_NO',
                    'Title' => 'Title',
                    'Document No.' => 'Document_No',
                );
            case 'er':
                return array(
                    'Acc Date' => 'Acc_Date',
                    'Acc No' => 'Acc_No',
                    'Title' => 'Title',
                    'Author' => 'Author',
                    'Copyright Year' => 'Copyright_Year',
                    'Pages' => 'Pages',
                    'Publisher' => 'Publisher',
                    'File Path' => 'File_Path',
                );
            case 'application_notes':
                return array(
                    'S.No.' => 'S_No',
                    'Accession No.' => 'Accession_No',
                    'Publisher' => 'Publisher',
                    'General Note' => 'General_Note',
                    'Title' => 'Title',
                    'Subject' => 'Subject',
                );
            case 'reports_book':
                return array(
                    'S.No.' => 'S_No',
                    'Accession No.' => 'Accession_No',
                    'REPORTNO' => 'REPORTNO',
                    'TITLE' => 'TITLE',
                    'SUBTITLE' => 'SUBTITLE',
                    'NOOFPAGES' => 'NOOFPAGES',
                    'PERORGREPN' => 'PERORGREPN',
                    'REPORTTYPE' => 'REPORTTYPE',
                    'PERORGID' => 'PERORGID',
                    'SPONBODYID' => 'SPONBODYID',
                    'LANGID' => 'LANGID',
                    'PUBLISHER' => 'PUBLISHER',
                    'REPDATE' => 'REPDATE',
                );
            case 'journals':
                return array(
                    'S.No.' => 'S_No',
                    'ACC_NO' => 'ACC_NO',
                    'TITLE' => 'TITLE',
                    'VOLUME' => 'VOLUME',
                    'PERIOD' => 'PERIOD',
                    'YEAR' => 'YEAR',
                );
            case 'ebook':
                return array(
                    'Accession Date' => 'Accession_Date',
                    'Accession No' => 'Accession_No',
                    'Title' => 'Title',
                    'Author' => 'Author',
                    'Subject' => 'Subject',
                    'Pages' => 'Pages',
                    'ISBN' => 'ISBN',
                    'Publisher' => 'Publisher',
                    'Year' => 'Year',
                    'File URL' => 'File_URL',
                );
            case 'all':
            default:
                return array(
                    'S.No' => 'S_No',
                    'Accession No' => 'Accession_No',
                    'Item Type' => 'Item_Type',
                    'Title' => 'Title',
                    'Author' => 'Author',
                    'Subtitle' => 'Subtitle',
                    'Edition' => 'Edition',
                    'Publisher' => 'Publisher',
                    'Year' => 'Year',
                    'Place' => 'Place',
                    'ISBN' => 'ISBN',
                    'Pages' => 'Pages',
                    'Subject' => 'Subject',
                    'File Path' => 'File_Path',
                    'File Name' => 'File_Name',
                    'Standard' => 'Standard',
                    'Standard No' => 'Standard_No',
                    'Period' => 'Period',
                    'Country' => 'Country',
                    'Patent No' => 'Patent_No',
                    'Report No' => 'Report_No',
                    'Report Type' => 'Report_Type',
                    'Org ID' => 'Org_ID',
                    'Sponsor' => 'Sponsor',
                    'Invoice No' => 'Invoice_No',
                    'Invoice Date' => 'Invoice_Date',
                    'Item Currency' => 'Item_Currency',
                    'Price (Foreign)' => 'Price_Foreign',
                    'Price Currency' => 'Price_Currency',
                    'Price INR' => 'Price_INR',
                    'Location' => 'Location',
                    'Nature' => 'Nature',
                    'Status' => 'Status',
                    'Remarks' => 'Remarks',
                    'Supplier' => 'Supplier',
                );
        }
    }
}

if (!function_exists('report_export_cell_align')) {
    /**
     * Content-based horizontal alignment for Word/Excel cells.
     */
    function report_export_cell_align($value, $label = '')
    {
        $v = trim((string) $value);
        $label_l = strtolower((string) $label);

        if ($v === '') {
            return 'center';
        }
        if (preg_match('/^(s\.?\s*no|rank|priority|pages|year|vol|count|overdue)/i', $label_l)) {
            return 'center';
        }
        if (preg_match('/date|time/i', $label_l) && strlen($v) <= 20) {
            return 'center';
        }
        if (preg_match('/^-?\d+([.,]\d+)?%?$/', $v)) {
            return 'right';
        }
        if (strlen($v) <= 8 && !preg_match('/\s/', $v)) {
            return 'center';
        }
        return 'left';
    }
}
