<?php
function checkMode()
{
    $clientnumber = (int)($_REQUEST['clientnumber'] ?? 0);
    if ($clientnumber < 1 || !isset($GLOBALS['con'])) {
        return;
    }

    $recall = mysqli_query($GLOBALS['con'], "SELECT `systemMode` FROM `clientdetails` WHERE `clientnumber`='" . $clientnumber . "'");
    $result = $recall ? mysqli_fetch_assoc($recall) : null;
    if (($result['systemMode'] ?? 0) == 1) { ?>
        <script>
            location.href = 'index.php?t=includes/master&p=elec.php&clientnumber=<?= $clientnumber ?>';
        </script>
<?php die();
    }
}

function clientAssetLightShortText($value, $limit = 30)
{
    $value = trim((string)$value);
    $limit = (int)$limit;

    if ($limit < 1) {
        return '';
    }

    if (function_exists('mb_strlen') && function_exists('mb_substr')) {
        if (mb_strlen($value) <= $limit) {
            return $value;
        }
        return mb_substr($value, 0, max(0, $limit - 3)) . '...';
    }

    if (strlen($value) <= $limit) {
        return $value;
    }
    return substr($value, 0, max(0, $limit - 3)) . '...';
}

function clientAssetLightDefaultPrefs()
{
    return [
        'itemnumber'   => ['label' => 'Item ID',      'visible' => true],
        'description'  => ['label' => 'Description',  'visible' => true],
        'manufacturer' => ['label' => 'Manufacturer', 'visible' => true],
        'make_model'   => ['label' => 'Make/Model',   'visible' => true],
        'condition'    => ['label' => 'Condition',    'visible' => true],
        'plantnumber'  => ['label' => 'Plant No.',    'visible' => true],
        'serialnumber' => ['label' => 'Serial',       'visible' => true],
        'locname'      => ['label' => 'Location',     'visible' => true],
        'subloc'       => ['label' => 'Sub-location', 'visible' => true],
        'postcode'     => ['label' => 'Post Code',    'visible' => true],
        'lastReport'   => ['label' => 'Result',       'visible' => true],
        'duedate'      => ['label' => 'Due',          'visible' => true],
        'actions'      => ['label' => 'Actions',      'visible' => true],
    ];
}

function clientAssetLightNormalisePrefs($prefs)
{
    $defaults = clientAssetLightDefaultPrefs();
    $prefs = is_array($prefs) ? $prefs : [];

    if (isset($prefs['model']) && !isset($prefs['make_model'])) {
        $prefs['make_model'] = $prefs['model'];
    }

    foreach ($defaults as $key => $default) {
        if (!isset($prefs[$key]) || !is_array($prefs[$key])) {
            $prefs[$key] = $default;
            continue;
        }

        $prefs[$key]['label'] = isset($prefs[$key]['label']) && trim((string)$prefs[$key]['label']) !== ''
            ? (string)$prefs[$key]['label']
            : $default['label'];

        if (array_key_exists('visible', $prefs[$key])) {
            $prefs[$key]['visible'] = (bool)$prefs[$key]['visible'];
        } elseif (array_key_exists('enabled', $prefs[$key])) {
            $prefs[$key]['visible'] = (bool)$prefs[$key]['enabled'];
        } else {
            $prefs[$key]['visible'] = (bool)$default['visible'];
        }
    }

    $prefs['actions'] = ['label' => $prefs['actions']['label'] ?? 'Actions', 'visible' => true];
    return $prefs;
}

function clientAssetLightColumnLabel(array $prefs, string $key): string
{
    return htmlspecialchars((string)($prefs[$key]['label'] ?? $key), ENT_QUOTES, 'UTF-8');
}

function clientAssetLightColumnVisible(array $prefs, string $key): bool
{
    return !isset($prefs[$key]['visible']) || (bool)$prefs[$key]['visible'];
}

function clientAssetLightAssignedSurveyorId(): int
{
    return (($_SESSION['usertype'] ?? '') === 'surveyor' && (int)($_SESSION['access'] ?? 0) === 3)
        ? (int)($_SESSION['userid'] ?? 0)
        : 0;
}

function clientAssetLightItemScopeSql(string $alias = 'a'): string
{
    $surveyorId = clientAssetLightAssignedSurveyorId();
    if ($surveyorId <= 0) {
        return '';
    }

    $alias = preg_replace('/[^A-Za-z0-9_]/', '', $alias) ?: 'a';
    return "
        AND EXISTS (
            SELECT 1
            FROM surveyor_assignments sa
            WHERE sa.surveyor = {$surveyorId}
              AND sa.client_id = {$alias}.clientnumber
              AND sa.status = 1
              AND (
                  (COALESCE(sa.asset_id, 0) > 0 AND sa.asset_id = {$alias}.itemnumber)
                  OR (COALESCE(sa.asset_id, 0) = 0 AND COALESCE(sa.site_id, 0) > 0 AND sa.site_id = {$alias}.locnumber)
                  OR (COALESCE(sa.asset_id, 0) = 0 AND COALESCE(sa.site_id, 0) = 0)
              )
        )
    ";
}

function clientAssetLightLocationScopeSql(string $alias = 'l'): string
{
    $surveyorId = clientAssetLightAssignedSurveyorId();
    if ($surveyorId <= 0) {
        return '';
    }

    $alias = preg_replace('/[^A-Za-z0-9_]/', '', $alias) ?: 'l';
    return "
        AND EXISTS (
            SELECT 1
            FROM surveyor_assignments sa
            WHERE sa.surveyor = {$surveyorId}
              AND sa.client_id = {$alias}.clientnumber
              AND sa.status = 1
              AND (
                  (COALESCE(sa.asset_id, 0) = 0 AND COALESCE(sa.site_id, 0) > 0 AND sa.site_id = {$alias}.locnumber)
                  OR (COALESCE(sa.asset_id, 0) = 0 AND COALESCE(sa.site_id, 0) = 0)
                  OR (
                      COALESCE(sa.asset_id, 0) > 0
                      AND EXISTS (
                          SELECT 1
                          FROM itemdetails ai
                          WHERE ai.itemnumber = sa.asset_id
                            AND ai.clientnumber = sa.client_id
                            AND ai.locnumber = {$alias}.locnumber
                            AND ai.statuslive = 1
                      )
                  )
              )
        )
    ";
}

function clientAssetLightLoadSystemPrefs()
{
    $prefs = $GLOBALS['assetPrefs'] ?? [];

    if (!isset($GLOBALS['con'])) {
        return $prefs;
    }

    try {
        $stmt = $GLOBALS['con']->prepare("SELECT `asset_table_prefs` FROM `system` WHERE `id`='1' LIMIT 1");
        if (!$stmt) {
            return $prefs;
        }

        $stmt->execute();
        $stmt->bind_result($prefsJson);
        if ($stmt->fetch() && trim((string)$prefsJson) !== '') {
            $decoded = json_decode((string)$prefsJson, true);
            if (is_array($decoded)) {
                $prefs = $decoded;
            }
        }
        $stmt->close();
    } catch (Throwable $e) {
        return $prefs;
    }

    return $prefs;
}

function getRenewal($client)
{
    $ret = '';
    $client = (int)$client;
    if ($client < 1 || !isset($GLOBALS['con'])) {
        return $ret;
    }

    $lcheck = mysqli_query($GLOBALS['con'], "SELECT `renewal_date` FROM `clientdetails` WHERE `clientnumber`='" . $client . "'");
    $ln = $lcheck ? mysqli_fetch_array($lcheck) : null;
    $renewal = $ln['renewal_date'] ?? '';

    if (is_numeric($renewal)) {
        $now = new DateTime();
        $renewal_date = date('d-m-Y', (int)$renewal);
        $datetime1 = new DateTime($now->format('d-m-Y'));
        $datetime2 = new DateTime($renewal_date);
        $difference = $datetime1->diff($datetime2);
        $days = (int)$difference->format("%r%a");
        $day = ($days < 0) ? abs($days) . ' days ago' : 'in ' . $days . ' days';

        if ($days === 0 && date('m', (int)$renewal) == date('m')) {
            $ret = '<div class="alert alert-success success-color-dark text-light text-center m-0" style="padding:3px">Renewal due today (' . $renewal_date . ')</div>';
        } elseif (($days < 30 && $days > 0) && date('m', (int)$renewal) == date('m')) {
            $ret = '<div class="alert alert-warning warning-color-dark text-light text-center m-0" style="padding:3px">Renewal due ' . $day . ' (' . $renewal_date . ')</div>';
        } elseif (date('m-Y', (int)$renewal) == date('m-Y')) {
            $ret = '<div class="alert alert-danger danger-color-dark text-light text-center m-0" style="padding:3px">Renewal due ' . $day . ' (' . $renewal_date . ')</div>';
        }
    }

    return $ret;
}

checkMode();

$clientnumber = (int)($_REQUEST['clientnumber'] ?? 0);
$filter = (string)($_REQUEST['filter'] ?? 'live');
$status = ($filter === 'archive') ? 0 : 1;
$clientName = function_exists('getClientName') ? getClientName($clientnumber) : '';
$clientNavName = clientAssetLightShortText($clientName, 30);
$tenantUrl = defined('TENANT_URL') ? TENANT_URL : ($_REQUEST['tenant'] ?? '');
$rootUrl = defined('ROOT_URL') ? ROOT_URL : '';
$assetGridJsVersion = @filemtime(__DIR__ . '/../asset/asset_grid.js') ?: time();

$clientLocationCount = 0;
$clientAssetCount = 0;
if ($clientnumber > 0 && isset($GLOBALS['con'])) {
    $locationScopeSql = clientAssetLightLocationScopeSql('l');
    $locationCountQuery = mysqli_query($GLOBALS['con'], "SELECT COUNT(*) AS total FROM `locations` l WHERE l.`clientnumber`='" . $clientnumber . "' {$locationScopeSql}");
    if ($locationCountQuery && ($locationCountRow = mysqli_fetch_assoc($locationCountQuery))) {
        $clientLocationCount = (int)($locationCountRow['total'] ?? 0);
    }

    $itemScopeSql = clientAssetLightItemScopeSql('a');
    $assetCountQuery = mysqli_query($GLOBALS['con'], "SELECT COUNT(*) AS total FROM `itemdetails` a WHERE a.`clientnumber`='" . $clientnumber . "' {$itemScopeSql}");
    if ($assetCountQuery && ($assetCountRow = mysqli_fetch_assoc($assetCountQuery))) {
        $clientAssetCount = (int)($assetCountRow['total'] ?? 0);
    }
}
$showScheduleOnboarding = $clientLocationCount < 1 || $clientAssetCount < 1;
$scheduleOnboardingStep = $clientLocationCount < 1 ? 'location' : ($clientAssetCount < 1 ? 'asset' : '');

$assetScheduleItemCount = 0;
if ($clientnumber > 0 && isset($GLOBALS['con'])) {
    $itemScopeSql = clientAssetLightItemScopeSql('a');
    $countSql = "SELECT COUNT(*) AS total FROM `itemdetails` a WHERE a.`clientnumber`='" . $clientnumber . "' AND a.`statuslive`='" . (int)$status . "' {$itemScopeSql}";
    $assetScheduleCountQuery = mysqli_query($GLOBALS['con'], $countSql);
    if ($assetScheduleCountQuery && ($assetScheduleCountRow = mysqli_fetch_assoc($assetScheduleCountQuery))) {
        $assetScheduleItemCount = (int)($assetScheduleCountRow['total'] ?? 0);
    }
}

$assetPrefs = clientAssetLightNormalisePrefs(clientAssetLightLoadSystemPrefs());
$GLOBALS['assetPrefs'] = $assetPrefs;
$assetColumnOrder = [
    'itemnumber',
    'description',
    'manufacturer',
    'make_model',
    'condition',
    'plantnumber',
    'serialnumber',
    'locname',
    'subloc',
    'postcode',
    'lastReport',
    'duedate',
];
?>

<div id="infoRow" class="row bg-light mt-n4 pt-3" style="position:fixed; width:100%; z-index:10; top:70px">
    <div class="col-12 col-md-3">
        <?= getRenewal($clientnumber) ?>
    </div>

    <div id="mainToolbar" class="col-12 col-md-9 text-center text-md-end mb-sm-0">
        <?php if ($filter === '' || $filter === 'current' || $filter === 'live') { ?>
            <a href="javascript:void(0)"
                onclick="loadModalContent('<?= $rootUrl ?>/includes/client/client-plant.php?clientnumber=<?= $clientnumber ?>&tenant=<?= htmlspecialchars($tenantUrl, ENT_QUOTES, 'UTF-8') ?>','popupBox', 'modal-xxl', 1060, 'true','Plant Summary','close')"
                class="btn btn-secondary btn-sm mb-3" data-mdb-tooltip-init data-mdb-trigger="hover"
                data-mdb-placement="bottom" title="Client plant summary">
                <i class="fa-duotone fa-clipboard-list"></i>
                <span class="d-inline d-xl-none ms-1">Plant Summary</span>
            </a>

            <a href="javascript:void(0)"
                onclick="printSchedule('<?= $rootUrl ?>/functions/print_schedule.php', 'Schedule','<?= $clientnumber ?>')"
                class="btn btn-secondary btn-sm mb-3" data-mdb-tooltip-init data-mdb-trigger="hover"
                data-mdb-placement="bottom" title="Pretty print schedule">
                <i class="fad fa-print"></i>
                <span class="d-inline d-xl-none ms-1">Pretty Print</span>
            </a>

            <a href="index.php?t=includes/client&p=client_schedule_print.php&clientnumber=<?= $clientnumber ?>"
                class="btn btn-secondary btn-sm mb-3" data-mdb-tooltip-init data-mdb-trigger="hover"
                data-mdb-placement="bottom" title="Custom Print">
                <i class="fad fa-cog"></i> <i class="fad fa-print"></i>
                <span class="d-inline d-xl-none ms-1">Custom print</span>
            </a>

            <a id="newAsset" href="javascript:void(0)" class="btn btn-sm btn-secondary formButton mb-3"
                data-values="<?= $clientnumber ?>||" data-href="<?= $rootUrl ?>/includes/master/formnew.php"
                data-mdb-tooltip-init data-mdb-trigger="hover" data-mdb-placement="bottom" title="Register Asset">
                <i class="fad fa-plus" aria-hidden="true"></i> New Asset
            </a>

            <a id="ImportAsset" href="javascript:void(0)" class="btn btn-sm btn-secondary importButton mb-3"
                data-values="<?= $clientnumber ?>||" data-href="<?= $rootUrl ?>/includes/asset/asset_import.php"
                data-mdb-tooltip-init data-mdb-trigger="hover" data-mdb-placement="bottom" title="Import Assets">
                <i class="fad fa-plus" aria-hidden="true"></i> Import Asset
            </a>

            <a id="newSite"
                href="index.php?t=includes/master&p=locations.php&clientnumber=<?= $clientnumber ?>&clientname=<?= urlencode($clientName) ?>&view=new&ref=asset"
                class="btn btn-secondary btn-sm mb-3" data-mdb-tooltip-init data-mdb-trigger="hover"
                data-mdb-placement="bottom" title="New Location">
                <i class="fad fa-building" aria-hidden="true"></i> New Location
            </a>

            <?php if (!empty($_SESSION['delivery'])) { ?>
                <a href="index.php?t=includes/master&p=delivery.php&clientnumber=<?= $clientnumber ?>"
                    class="btn btn-secondary btn-sm mb-3" data-mdb-tooltip-init data-mdb-trigger="hover"
                    data-mdb-placement="bottom" title="Report Delivery">
                    <i class="fad fa-share-square" aria-hidden="true"></i> Deliver Reports
                </a>
            <?php } ?>

            <?php if (function_exists('checkTemp') && checkTemp($clientnumber) == 1) { ?>
                <a href="index.php?t=includes/master&p=items.php&clientnumber=<?= $clientnumber ?>&view=incomplete"
                    class="btn btn-sm btn-info mb-3" data-mdb-tooltip-init data-mdb-trigger="hover" data-mdb-placement="bottom"
                    title="Incomplete Reports">
                    <i class="fad fa-hourglass-half fa-spin"></i> Incomplete Reports
                </a>
            <?php } ?>

            <a href="index.php?t=includes/master&p=client.php&clientnumber=<?= $clientnumber ?>&view=asset&filter=archive"
                class="btn btn-secondary btn-sm mb-3" data-mdb-tooltip-init data-mdb-trigger="hover"
                data-mdb-placement="bottom" title="View Archived Assets">
                <i class="fad fa-archive" aria-hidden="true"></i> View Archived Items
            </a>

            <a href="index.php?t=includes/master&p=client.php&clientnumber=<?= $clientnumber ?>&view=edit"
                class="btn btn-secondary btn-sm mb-3" data-mdb-tooltip-init data-mdb-trigger="hover"
                data-mdb-placement="bottom" title="View Client Details">
                <i class="fad fa-info-circle"></i>
                <span class="d-inline d-xl-none ms-1">Client Details</span>
            </a>

            <script>
                document.getElementById('navBox').innerHTML =
                    '<li class="breadcrumb-item"><a href="index.php?t=includes/master&p=client.php&view=list">Client List</a><i class="fad fa-angle-double-right mx-2 mt-1" aria-hidden="true"></i></li><li class="breadcrumb-item"><a href="index.php?t=includes/master&p=client.php&clientnumber=<?= $clientnumber ?>&view=edit"><?= addslashes(htmlspecialchars($clientNavName, ENT_QUOTES, 'UTF-8')) ?></a><i class="fad fa-angle-double-right mx-2 mt-1" aria-hidden="true"></i></li><li class="breadcrumb-item active">Schedule: Active Items</li>';
            </script>
        <?php } else { ?>
            <a href="index.php?t=includes/master&p=client.php&clientnumber=<?= $clientnumber ?>&view=asset&filter=current"
                class="btn btn-secondary btn-sm mb-3">
                <i class="fad fa-upload" aria-hidden="true"></i> View Active Items
            </a>
            <script>
                document.getElementById('navBox').innerHTML =
                    '<li class="breadcrumb-item"><a href="index.php?t=includes/master&p=client.php&view=list">Client List</a><i class="fad fa-angle-double-right mx-2 mt-1" aria-hidden="true"></i></li><li class="breadcrumb-item"><a href="index.php?t=includes/master&p=client.php&clientnumber=<?= $clientnumber ?>&view=load"><?= addslashes(htmlspecialchars($clientNavName, ENT_QUOTES, 'UTF-8')) ?></a><i class="fad fa-angle-double-right mx-2 mt-1" aria-hidden="true"></i></li><li class="breadcrumb-item active">Schedule: Archive Items</li>';
            </script>
        <?php } ?>


    </div>

    <div id="massToolbar" class="col-12 col-md-9 text-center text-md-end" style="display:none">
        <a id="massMigrate" href="javascript:void(0)" onclick="massMigrate()" class="btn btn-sm btn-info mb-3">
            <i class="fad fa-grid"></i> Item move
        </a>
        <a id="massArchive" href="javascript:void(0)" onclick="massArchive()" class="btn btn-sm btn-info mb-3">
            <i class="fad fa-file-archive"></i> Item Archive
        </a>
        <a id="massChain" href="javascript:void(0)" onclick="massChain()" class="btn btn-sm btn-info mb-3">
            <i class="fad fa-link-horizontal"></i> Chain Items
        </a>
        <a id="massMoveChain" href="javascript:void(0)" onclick="massMoveChain()" class="btn btn-sm btn-info mb-3">
            <i class="fad fa-link-broken"
                style="--fa-primary-color: rgb(255, 0, 0); --fa-secondary-color: rgb(255, 255, 255); --fa-secondary-opacity: 0.27;"></i>
            Edit Chain
        </a>
        <a id="massCode" href="javascript:void(0)" onclick="massCode()" class="btn btn-sm btn-info mb-3">
            <i class="fad fa-square-terminal"></i> Code Change
        </a>
        <a id="massPNA" href="javascript:void(0)" onclick="massPNA()" class="btn btn-sm btn-dark mb-3">
            <i class="fad fa-subtitles-slash"></i> PNA Items
        </a>
    </div>
</div>

<?php if ($showScheduleOnboarding) { ?>
    <div id="assetOnboarding" class="asset-onboarding container pt-4 my-4">
        <div id="assetOnboardingAlert" class="mt-3">
            <div class="col-md-12 alert alert-warning text-center">
                <b><?= $scheduleOnboardingStep === 'location' ? 'You have no locations defined for this client' : 'You have no assets defined for this client' ?></b>
            </div>
        </div>

        <section class="p-md-3 mx-md-5 text-lg-left">
            <div class="row text-center d-flex justify-content-center mt-4">
                <div id="S1"
                    class="col-lg-4 col-md-6 mb-5 <?= $scheduleOnboardingStep === 'location' ? 'asset-onboarding-active' : 'asset-onboarding-muted' ?>">
                    <i class="fad fa-building indigo-text fa-3x mb-4"></i>
                    <h4 class="font-weight-bold mb-4">Define At Least One Location</h4>
                    <p class="text-muted px-2 mb-lg-0">All schedules require a location, this can also be the same as the
                        client address.</p>
                </div>
                <div id="S2"
                    class="col-lg-4 col-md-6 mb-5 <?= $scheduleOnboardingStep === 'asset' ? 'asset-onboarding-active' : 'asset-onboarding-muted' ?>">
                    <i class="fad fa-starship-freighter green-text fa-3x mb-4"></i>
                    <h4 class="font-weight-bold mb-4">Add Assets</h4>
                    <p class="text-muted px-2 mb-lg-0">Once you have defined a location, begin adding your assets.</p>
                </div>
                <div id="S3" class="col-lg-4 col-md-6 mb-5 asset-onboarding-muted">
                    <i class="fad fa-search blue-text fa-3x mb-4"></i>
                    <h4 class="font-weight-bold mb-4">Inspect</h4>
                    <p class="text-muted px-2 mb-md-0">You have your location and registered assets. Now you can inspect.
                    </p>
                </div>
            </div>
            <div class="text-center">
                <?php if ($scheduleOnboardingStep === 'location') { ?>
                    <a href="index.php?t=includes/master&p=locations.php&clientnumber=<?= $clientnumber ?>&clientname=<?= urlencode($clientName) ?>&view=new&ref=asset"
                        class="btn btn-info asset-onboarding-action">
                        <i class="fad fa-building"></i> New Location
                    </a>
                <?php } else { ?>
                    <a href="javascript:void(0)" class="btn btn-info asset-onboarding-action formButton"
                        data-values="<?= $clientnumber ?>||" data-href="<?= $rootUrl ?>/includes/master/formnew.php"
                        title="Register Asset">
                        <i class="fad fa-plus"></i> New Asset
                    </a>
                <?php } ?>
            </div>
        </section>
    </div>
<?php } ?>

<div id="loadingOverlay"
    style="position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: rgba(255, 255, 255, 0.82); z-index: 9999; display: <?= $showScheduleOnboarding ? 'none' : 'flex' ?>; align-items: center; justify-content: center;">
    <h1 class="text-center"><i class="fad fa-spinner-third fa-spin fa-3x fa-fw"></i><br>Loading
        Schedule<br><small>Please wait</small></h1>
</div>

<div id="assetTableContainer" style="visibility:hidden;<?= $showScheduleOnboarding ? ' display:none;' : '' ?>">
    <div id="pageAlert" class="mt-5"></div>

    <div id="assetDesktopControls" class="row align-items-end g-2 mb-3 d-none d-xl-flex">
        <div class="col-lg-4">
            <label class="form-label mb-1">Search assets</label>
            <div class="input-group input-group-sm">
                <input type="search" id="assetDesktopSearch" class="form-control"
                    placeholder="Search text, results, dates; separate phrases with commas">
                <button type="button" class="btn btn-light" data-asset-clear-search title="Clear search">
                    <i class="fad fa-times"></i>
                </button>
            </div>
        </div>
        <div class="col-lg-2">
            <label class="form-label mb-1">Rows</label>
            <select id="assetGridPageSize" class="form-select form-select-sm">
                <option value="10">10</option>
                <option value="25" selected>25</option>
                <option value="50">50</option>
                <option value="100">100</option>
                <option value="250">250</option>
                <option value="-1">All</option>
            </select>
        </div>
        <div class="col-lg-3">
            <div class="d-flex gap-2">
                <button type="button" id="assetGridSelectVisible" class="btn btn-secondary btn-sm w-100">
                    <i class="fad fa-check-square"></i> Select Visible
                </button>
                <button type="button" id="assetGridClearVisible" class="btn btn-light btn-sm w-100">
                    <i class="fad fa-square"></i> Deselect Visible
                </button>
            </div>
        </div>
        <div class="col-lg-3 text-lg-end">
            <div id="assetGridProcessing" class="asset-processing-indicator" style="display:none;">Loading</div>
            <div id="assetGridSummary" class="small text-muted mt-2"></div>
        </div>
    </div>

    <div id="assetMobileStickyControls" class="d-xl-none">
        <div id="assetMobileQuickBar" class="d-flex align-items-center gap-2 flex-nowrap">
            <button type="button" class="btn btn-secondary btn-sm d-flex align-items-center gap-2 flex-shrink-0"
                data-mdb-offcanvas-init data-mdb-target="#assetActionsCanvas" aria-controls="assetActionsCanvas"
                title="Schedule actions">
                <i class="fad fa-bars"></i>
                <span>Actions</span>
            </button>
            <input type="search" id="assetQuickSearch" class="form-control form-control-sm"
                placeholder="Search assets">
            <select id="assetGridPageSizeMobile" class="form-select form-select-sm asset-mobile-rows-select"
                aria-label="Rows">
                <option value="10">10</option>
                <option value="25" selected>25</option>
                <option value="50">50</option>
                <option value="100">100</option>
                <option value="250">250</option>
                <option value="-1">All</option>
            </select>
            <button type="button" class="btn btn-light btn-sm" data-asset-clear-search><i
                    class="fad fa-times"></i></button>
            <button type="button" class="btn btn-info btn-sm flex-shrink-0" data-mdb-offcanvas-init
                data-mdb-target="#assetFiltersCanvas" aria-controls="assetFiltersCanvas" title="Status filters">
                <i class="fad fa-filter"></i>
            </button>
        </div>

        <div class="asset-active-filters asset-active-filters-mobile mt-2" data-asset-active-filters></div>

        <div id="assetMobilePagerHost" class="mt-2"></div>
    </div>

    <div class="offcanvas offcanvas-bottom" tabindex="-1" id="assetFiltersCanvas"
        aria-labelledby="assetFiltersCanvasLabel">
        <div class="offcanvas-header">
            <h5 class="offcanvas-title" id="assetFiltersCanvasLabel">Status Filters</h5>
            <button type="button" class="btn-close text-reset" data-mdb-dismiss="offcanvas" aria-label="Close"></button>
        </div>
        <div class="offcanvas-body">
            <div class="d-grid gap-2">
                <button type="button" class="btn danger-color-dark text-light"
                    data-asset-status-filter="overdue">Overdue</button>
                <button type="button" class="btn warning-color-dark text-light"
                    data-asset-status-filter="pending">Pending</button>
                <button type="button" class="btn success-color-dark text-light" data-asset-status-filter="not_due">Not
                    Due</button>
                <button type="button" class="btn btn-light" onclick="clearSearch()">Reset Filters</button>
            </div>
        </div>
    </div>

    <div class="offcanvas offcanvas-start" tabindex="-1" id="assetActionsCanvas"
        aria-labelledby="assetActionsCanvasLabel">
        <div class="offcanvas-header">
            <h5 class="offcanvas-title" id="assetActionsCanvasLabel">Schedule Actions</h5>
            <button type="button" class="btn-close text-reset" data-mdb-dismiss="offcanvas" aria-label="Close"></button>
        </div>
        <div class="offcanvas-body">
            <div id="assetActionsCanvasBody" class="d-grid gap-2"></div>
        </div>
    </div>

    <div id="assetDesktopFilters" class="mb-3 text-center text-md-start d-none d-xl-block">
        <button type="button" class="btn danger-color-dark text-light filterButtons"
            data-asset-status-filter="overdue">Overdue</button>
        <button type="button" class="btn warning-color-dark text-light filterButtons"
            data-asset-status-filter="pending">Pending</button>
        <button type="button" class="btn success-color-dark text-light filterButtons"
            data-asset-status-filter="not_due">Not Due</button>
        <button type="button" class="btn color bg-white filterButtons" onclick="clearSearch()">
            <i class="fad fa-refresh" aria-hidden="true"></i> Reset Filters
        </button>
        <span class="asset-active-filters asset-active-filters-desktop" data-asset-active-filters></span>
    </div>

    <div id="assetAllProgress" class="alert alert-info align-items-center gap-3 mb-3" style="display:none;">
        <i class="fad fa-spinner-third fa-spin fa-lg"></i>
        <div class="flex-grow-1">
            <div id="assetAllProgressText" class="fw-bold">Loading all matching assets</div>
            <div class="progress mt-2" style="height:8px;">
                <div id="assetAllProgressBar" class="progress-bar progress-bar-striped progress-bar-animated"
                    role="progressbar" style="width:0%"></div>
            </div>
        </div>
    </div>

    <div id="assetPagerRow" class="row g-2 align-items-center mb-3">
        <div class="col-12 col-lg-8">
            <div id="assetGridPager" class="d-flex align-items-center gap-3 flex-wrap">
                <button type="button" id="assetGridPrev" class="btn btn-secondary btn-sm">
                    <i class="fad fa-chevron-left"></i> Prev
                </button>
                <div id="assetGridPageInfo" class="small text-muted px-2">Page 1 of 1</div>
                <button type="button" id="assetGridNext" class="btn btn-secondary btn-sm">
                    Next <i class="fad fa-chevron-right"></i>
                </button>
                <button type="button" id="assetGridSelectVisibleMobile" class="btn btn-secondary btn-sm d-xl-none">
                    <i class="fad fa-check-square"></i>
                    <span class="d-none d-sm-inline">Select Visible</span><span class="d-inline d-sm-none">Select</span>
                </button>
                <button type="button" id="assetGridClearVisibleMobile" class="btn btn-light btn-sm d-xl-none">
                    <i class="fad fa-square"></i>
                    <span class="d-none d-sm-inline">Deselect Visible</span><span class="d-inline d-sm-none">Deselect</span>
                </button>
                <div id="assetGridSummaryMobile" class="small text-muted ms-auto text-end d-none d-sm-block d-xl-none"></div>
            </div>
        </div>
    </div>

    <div class="table-responsive d-none d-xl-block">
        <table id="assetGridTable" class="table table-sm table-hover align-middle">
            <thead class="table-dark">
                <tr>
                    <th></th>
                    <th></th>
                    <?php foreach ($assetColumnOrder as $columnKey) {
                        if (!clientAssetLightColumnVisible($assetPrefs, $columnKey)) {
                            continue;
                        }
                    ?>
                        <th data-sort-field="<?= htmlspecialchars($columnKey, ENT_QUOTES, 'UTF-8') ?>">
                            <?= clientAssetLightColumnLabel($assetPrefs, $columnKey) ?></th>
                    <?php } ?>
                    <th class="text-end"><?= clientAssetLightColumnLabel($assetPrefs, 'actions') ?></th>
                </tr>
            </thead>
            <tbody id="assetGridBody"></tbody>
        </table>
    </div>

    <div id="assetMobileBody" class="d-xl-none"></div>
</div>

<div id="selectedItems" style="display:none"></div>

<style>
    .asset-onboarding {
        min-height: 45vh;
    }

    .asset-onboarding-muted {
        opacity: .3;
        filter: grayscale(100%);
        -webkit-filter: grayscale(100%);
    }

    .asset-onboarding-active i {
        color: #0055A6 !important;
    }

    .asset-onboarding-action {
        min-width: 180px;
    }

    .asset-onboarding-toolbar-highlight {
        color: #ffffff !important;
    }

    @media (min-width: 1200px) {
        #assetOnboarding {
            margin-top: 60px !important;
        }

        #assetTableContainer {
            margin-top: 60px;
        }
    }

    #assetGridTable th[data-sort-field] {
        cursor: pointer;
        padding-right: 1.4rem;
        position: relative;
        white-space: nowrap;
    }

    #assetGridTable th[data-sort-field]::after {
        color: rgba(255, 255, 255, .45);
        content: "\f0dc";
        font-family: "Font Awesome 6 Duotone", "Font Awesome 5 Duotone", "Font Awesome 6 Pro", "Font Awesome 5 Pro", "Font Awesome 6 Free";
        font-weight: 900;
        font-size: .75rem;
        position: absolute;
        right: .45rem;
        top: 50%;
        transform: translateY(-50%);
    }

    #assetGridTable th[data-sort-field].asset-sort-active::after {
        color: #ffffff;
    }

    #assetGridTable th[data-sort-field].asset-sort-asc::after {
        content: "\f0de";
    }

    #assetGridTable th[data-sort-field].asset-sort-desc::after {
        content: "\f0dd";
    }

    #assetGridTable th[data-sort-field].asset-sort-disabled {
        cursor: wait;
        opacity: .65;
        pointer-events: none;
    }

    #assetTableContainer.asset-grid-loading {
        cursor: wait;
    }

    #assetGridTable tbody tr:not(.has-plant-row-colour)>td:not(.asset-status-cell) {
        background: #ffffff;
    }

    #assetGridTable tbody tr.asset-row-striped:not(.has-plant-row-colour)>td:not(.asset-status-cell) {
        background: #f8fafc;
    }

    #assetGridTable tbody tr.selected>td:not(.asset-status-cell) {
        background: #e8f1ff;
    }

    #assetGridTable tbody tr:hover>td {
        background: #0055A6 !important;
        color: #ffffff !important;
    }

    #assetGridTable tbody tr:hover>td a:not(.btn),
    #assetGridTable tbody tr:hover>td .asset-inline-filter,
    #assetGridTable tbody tr:hover>td .asset-description-text,
    #assetGridTable tbody tr:hover>td .asset-location-popover,
    #assetGridTable tbody tr:hover>td .asset-result-badge,
    #assetGridTable tbody tr:hover>td .asset-mobile-value,
    #assetGridTable tbody tr:hover>td .asset-mobile-label {
        color: #ffffff !important;
    }

    #assetGridTable tbody tr:hover>td .badge:not(.bg-light):not(.text-dark),
    #assetGridTable tbody tr:hover>td .btn:not(.btn-light):not(.btn-secondary) {
        color: #ffffff !important;
    }

    #assetGridTable tbody tr:hover>td .badge.bg-light.text-dark,
    #assetGridTable tbody tr.selected>td .badge.bg-light.text-dark {
        color: #000000 !important;
    }

    #assetGridTable tbody tr:hover>td .btn-light:not(:hover):not(:focus),
    #assetGridTable tbody tr:hover>td .btn-light:not(:hover):not(:focus) i,
    #assetGridTable tbody tr:hover>td .btn-light:not(:hover):not(:focus) span,
    #assetGridTable tbody tr:hover>td .btn-secondary:not(:hover):not(:focus),
    #assetGridTable tbody tr:hover>td .btn-secondary:not(:hover):not(:focus) i,
    #assetGridTable tbody tr:hover>td .btn-secondary:not(:hover):not(:focus) span {
        color: #000000 !important;
    }

    #assetGridTable .asset-action-wrap .btn:hover,
    #assetGridTable .asset-action-wrap .btn:focus,
    #assetGridTable .asset-action-wrap .btn:hover i,
    #assetGridTable .asset-action-wrap .btn:focus i,
    #assetGridTable .asset-action-wrap .btn:hover span,
    #assetGridTable .asset-action-wrap .btn:focus span {
        color: #ffffff !important;
    }

    .asset-strip {
        display: block;
        width: 100%;
        min-height: 38px;
        border-radius: 0;
    }

    #assetGridTable td.asset-status-cell {
        width: 10px !important;
        min-width: 10px !important;
        max-width: 10px !important;
        padding: 0 !important;
        vertical-align: stretch;
    }

    .asset-status-cell.overdue,
    .asset-strip.overdue,
    .asset-mobile-strip.overdue {
        background: #dc4c64;
    }

    .asset-status-cell.pending,
    .asset-strip.pending,
    .asset-mobile-strip.pending {
        background: #e4a11b;
    }

    .asset-status-cell.not-due,
    .asset-strip.not-due,
    .asset-mobile-strip.not-due {
        background: #14a44d;
    }

    .asset-status-cell.unknown,
    .asset-strip.unknown,
    .asset-mobile-strip.unknown {
        background: #6c757d;
    }

    .asset-action-wrap .btn {
        margin-right: .35rem;
        margin-bottom: .35rem;
    }

    .asset-action-wrap {
        display: inline-flex;
        flex-wrap: wrap;
        justify-content: flex-end;
        gap: .35rem;
    }

    .asset-action-wrap .btn {
        min-width: 36px;
    }

    .asset-result-badge {
        position: relative;
        display: inline-block;
    }

    .asset-itemnumber-wrap {
        display: inline-flex;
        align-items: center;
        gap: .35rem;
        flex-wrap: wrap;
    }

    .asset-itemnumber-text {
        font-weight: 600;
    }

    .asset-itemnumber-badges {
        display: inline-flex;
        align-items: center;
        gap: .25rem;
        flex-wrap: wrap;
    }

    .asset-scheme-badge {
        line-height: 1.1;
        vertical-align: middle;
    }

    .asset-scheme-badge small {
        display: inline-flex;
        align-items: center;
        gap: .2rem;
    }

    .asset-puwer-badge {
        background: #0055A6;
    }

    .asset-description-wrap {
        align-items: center;
        display: grid;
        gap: .75rem;
        grid-template-columns: minmax(0, 1fr) auto;
        min-width: 220px;
    }

    .asset-description-text {
        cursor: pointer;
        min-width: 0;
        overflow-wrap: anywhere;
    }

    .asset-inline-filter,
    .asset-description-text,
    .asset-location-popover,
    .asset-result-badge[data-asset-inline-filter] {
        color: inherit !important;
        cursor: pointer;
        text-decoration: none !important;
    }

    .asset-inline-filter:hover,
    .asset-description-text:hover,
    .asset-location-popover:hover,
    .asset-result-badge[data-asset-inline-filter]:hover {
        color: inherit !important;
        text-decoration: none !important;
    }

    .asset-period-badge {
        border-radius: .25rem;
        color: #ffffff !important;
        min-width: 70px;
        text-align: center;
    }

    #assetGridTable tbody tr.has-plant-row-colour:not(.selected)>td:not(.asset-status-cell) .asset-period-badge {
        color: #ffffff !important;
    }

    .asset-location-popover {
        cursor: pointer;
        overflow-wrap: anywhere;
    }

    .asset-pna-streak {
        position: absolute;
        top: -0.62rem;
        right: -0.62rem;
        width: 1.05rem;
        height: 1.05rem;
        padding: 0;
        border-radius: 999px;
        background: #dc4c64;
        color: #fff;
        border: 2px solid #fff;
        font-size: 0.68rem;
        line-height: 0.88rem;
        text-align: center;
        font-weight: 700;
        pointer-events: none;
    }

    #assetGridTable tbody tr.has-plant-row-colour:not(.selected)>td:not(.asset-status-cell) {
        background: var(--plant-row-bg) !important;
    }

    #assetGridTable tbody tr.has-plant-row-colour:hover>td:not(.asset-status-cell) {
        background: #0055A6 !important;
        color: #ffffff !important;
    }

    #assetGridTable tbody tr.has-plant-row-colour:not(.selected)>td:not(.asset-status-cell) .asset-period-badge {
        color: #ffffff !important;
    }

    .asset-mobile-row {
        border-left: 5px solid #e5e5e5 !important;
        overflow: hidden;
    }

    .asset-mobile-row.asset-status-not-due {
        border-left-color: #007e33 !important;
    }

    .asset-mobile-row.asset-status-pending {
        border-left-color: #ff8800 !important;
    }

    .asset-mobile-row.asset-status-overdue {
        border-left-color: #cc0000 !important;
    }

    .asset-mobile-row.asset-status-unknown {
        border-left-color: #6c757d !important;
    }

    .asset-mobile-row.selected {
        outline: 2px solid #54b4d3;
    }

    .asset-mobile-row.has-plant-row-colour {
        background: var(--plant-row-bg);
    }

    .asset-mobile-title {
        font-size: 1rem;
        line-height: 1.2;
    }

    .asset-mobile-summary {
        display: grid;
        grid-template-columns: repeat(2, minmax(0, 1fr));
        gap: .45rem .75rem;
    }

    .asset-mobile-label {
        display: block;
        color: #2f3b45;
        font-size: .72rem;
        text-transform: uppercase;
        font-weight: 800;
        line-height: 1.15;
        margin-bottom: .12rem;
    }

    .asset-mobile-value {
        display: block;
        min-width: 0;
        overflow-wrap: anywhere;
    }

    #assetMobileStickyControls {
        position: sticky;
        top: var(--asset-sticky-top, 48px);
        z-index: 1035;
        background: #fff;
        border-bottom: 1px solid rgba(0, 0, 0, .06);
        box-shadow: 0 8px 18px rgba(0, 0, 0, .04);
        margin: 0 -.25rem 1rem;
        padding: .45rem .25rem .55rem;
    }

    #assetMobilePagerHost #assetGridPager {
        align-items: center;
        background: #fff;
        display: flex;
        flex-wrap: wrap;
        margin: 0;
        padding-top: .5rem;
    }

    #assetMobileQuickBar .form-control {

        min-width: 0;
    }

    #assetMobilePagerHost #assetGridPager {
        gap: .75rem !important;
        justify-content: flex-start;
    }

    #assetMobilePagerHost #assetGridPageInfo {
        flex: 0 0 auto;
    }

    #assetMobilePagerHost #assetGridSelectVisibleMobile,
    #assetMobilePagerHost #assetGridClearVisibleMobile {
        display: inline-flex !important;
        flex: 0 0 auto;
    }

    #assetGridSummaryMobile {
        flex: 1 1 180px;
        min-width: 180px;
    }

    #pageAlert:empty {
        display: none;
    }

    .asset-mobile-rows-select {
        width: 72px;
        flex: 0 0 72px;
    }

    .asset-active-filters {
        align-items: center;
        display: inline-flex;
        flex-wrap: wrap;
        gap: .45rem;
        min-height: 32px;
        vertical-align: middle;
    }

    .asset-active-filters:empty {
        display: none;
    }

    .asset-active-filter-chip {
        align-items: center;
        background: #f7f9fb;
        border: 1px solid #d7dee5;
        border-left: 3px solid #6c757d;
        border-radius: 999px;
        color: #24313d;
        display: inline-flex;
        font-size: .74rem;
        font-weight: 500;
        gap: .45rem;
        line-height: 1.1;
        margin: 0;
        max-width: 260px;
        min-height: 31px;
        padding: .2rem .25rem .2rem .45rem;
        white-space: nowrap;
    }

    .asset-active-filter-label {
        align-items: center;
        background: #e6ebf0;
        border-radius: 999px;
        color: #455764;
        display: inline-flex;
        font-size: .64rem;
        font-weight: 700;
        min-height: 21px;
        padding: .18rem .45rem;
        text-transform: uppercase;
    }

    .asset-active-filter-value {
        color: #14212b;
        font-weight: 700;
        min-width: 0;
        overflow: hidden;
        text-overflow: ellipsis;
        text-transform: uppercase;
    }

    .asset-active-filter-clear {
        align-items: center;
        background: #dc4c64;
        border: 0;
        border-radius: 999px;
        color: #ffffff;
        display: inline-flex;
        flex: 0 0 28px;
        height: 21px;
        justify-content: center;
        padding: 0;
        transition: background .15s ease, color .15s ease;
        width: 28px;
    }

    .asset-active-filter-clear:hover,
    .asset-active-filter-clear:focus {
        background: #b23a4f;
        color: #ffffff;
    }

    .asset-active-filter-search {
        border-left-color: #1266f1;
    }

    .asset-active-filter-sort {
        border-left-color: #59698d;
    }

    .asset-active-filter-status-overdue {
        border-left-color: #dc4c64;
    }

    .asset-active-filter-status-pending {
        border-left-color: #e4a11b;
    }

    .asset-active-filter-status-not_due {
        border-left-color: #14a44d;
    }

    [data-asset-status-filter].asset-status-filter-active {
        box-shadow: inset 0 0 0 2px rgba(255, 255, 255, .9), 0 0 0 2px rgba(0, 0, 0, .14);
    }

    .asset-active-filters-desktop {
        margin-left: .35rem;
    }

    .asset-active-filters-mobile {
        background: #fff;
        display: flex;
        justify-content: flex-start;
        min-height: 0;
    }

    .asset-mobile-row {
        border-radius: 6px;
    }

    .asset-mobile-row .card-body {
        padding: .65rem !important;
    }

    .asset-mobile-r1,
    .asset-mobile-r3 {
        display: grid;
        grid-template-columns: auto minmax(0, 1fr) auto;
        gap: .65rem;
        align-items: start;
    }

    .asset-mobile-r3 {
        display: flex;
        align-items: center;
        justify-content: space-between;
    }

    .asset-mobile-result {
        justify-self: end;
        text-align: right;
    }

    .asset-mobile-result-line {
        align-items: center;
        display: flex;
        flex-wrap: wrap;
        gap: .35rem;
        justify-content: flex-end;
    }

    .asset-mobile-chain-btn {
        gap: .22rem;
        line-height: 1;
        min-height: 24px;
        padding: .18rem .45rem;
    }

    .asset-mobile-due {
        display: block;
        margin-top: .25rem;
    }

    .asset-mobile-due .asset-mobile-label,
    .asset-mobile-due .asset-mobile-value {
        display: inline;
        margin-bottom: 0;
    }

    .asset-mobile-title {
        margin: 0;
        overflow-wrap: anywhere;
    }

    .asset-mobile-title~.small {
        display: none;
    }

    .asset-mobile-summary {
        grid-template-columns: repeat(4, minmax(0, 1fr));
    }

    .asset-mobile-summary>div:nth-child(5) {
        display: none;
    }

    .asset-mobile-footer-btn {
        flex: 0 0 auto;
        min-height: 38px;
    }

    .asset-mobile-sort-panel {
        border-top: 1px solid rgba(0, 0, 0, .08);
        margin-top: 1.25rem;
        padding-top: 1.15rem;
    }

    .asset-mobile-sort-title {
        color: #2f3b45;
        font-size: .78rem;
        font-weight: 800;
        margin-bottom: .55rem;
        text-transform: uppercase;
    }

    .asset-mobile-sort-grid {
        display: block;
    }

    .asset-mobile-sort-btn {
        align-items: center;
        display: inline-flex;
        gap: .5rem;
        justify-content: center;
        margin: 0 .45rem .5rem 0;
        min-height: 36px;
        padding: .38rem .65rem;
        text-align: left;
    }

    .asset-mobile-sort-btn span:first-child {
        min-width: 0;
        overflow: hidden;
        text-overflow: ellipsis;
    }

    .asset-mobile-sort-dir {
        border-radius: 999px;
        background: rgba(255, 255, 255, .22);
        font-size: .68rem;
        font-weight: 800;
        padding: .12rem .45rem;
    }

    @media (max-width: 1199.98px) {
        #infoRow {
            position: static !important;
            top: auto !important;
            width: 100% !important;
            margin: 0 !important;
            padding: .5rem .75rem !important;
        }

        #assetTableContainer {
            padding-top: 0 !important;
        }

        #assetMobileStickyControls {
            margin-top: 0 !important;
        }

        #mainToolbar,
        #massToolbar,
        #assetDesktopControls,
        #assetDesktopFilters {
            display: none !important;
        }

        .offcanvas.offcanvas-bottom {
            height: auto;
            max-height: 75vh;
        }
    }

    @media (max-width: 575.98px) {
        .asset-mobile-summary {
            grid-template-columns: 1fr;
        }

        #assetMobileQuickBar .btn span {
            display: none;
        }

        .asset-mobile-summary {
            grid-template-columns: repeat(2, minmax(0, 1fr));
        }
    }
</style>

<script>
    window.assetGridConfig = {
        endpoint: '<?= $rootUrl ?>/includes/asset/asset_grid_data.php',
        rootUrl: '<?= $rootUrl ?>',
        tenant: '<?= addslashes($tenantUrl) ?>',
        clientNumber: <?= (int)$clientnumber ?>,
        status: <?= (int)$status ?>,
        filter: '<?= addslashes($filter) ?>',
        stateVersion: 10,
        scheduleItemCount: <?= (int)$assetScheduleItemCount ?>,
        showOnboarding: <?= $showScheduleOnboarding ? 'true' : 'false' ?>,
        onboardingStep: '<?= addslashes($scheduleOnboardingStep) ?>',
        stateKey: 'assetGridState_<?= addslashes($tenantUrl) ?>_<?= (int)$clientnumber ?>_<?= (int)$status ?>',
        labels: <?= json_encode([
                    'itemnumber' => $assetPrefs['itemnumber']['label'] ?? 'Item ID',
                    'description' => $assetPrefs['description']['label'] ?? 'Description',
                    'manufacturer' => $assetPrefs['manufacturer']['label'] ?? 'Manufacturer',
                    'make_model' => $assetPrefs['make_model']['label'] ?? 'Make/Model',
                    'condition' => $assetPrefs['condition']['label'] ?? 'Condition',
                    'plantnumber' => $assetPrefs['plantnumber']['label'] ?? 'Plant No.',
                    'serialnumber' => $assetPrefs['serialnumber']['label'] ?? 'Serial',
                    'locname' => $assetPrefs['locname']['label'] ?? 'Location',
                    'subloc' => $assetPrefs['subloc']['label'] ?? 'Sub-location',
                    'postcode' => $assetPrefs['postcode']['label'] ?? 'Post Code',
                    'lastReport' => $assetPrefs['lastReport']['label'] ?? 'Result',
                    'duedate' => $assetPrefs['duedate']['label'] ?? 'Due'
                ], JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE) ?>,
        prefs: <?= json_encode($assetPrefs, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE) ?>
    };
</script>
<script src="<?= $rootUrl ?>/includes/asset/asset_grid.js?rebuild=<?= (int)$assetGridJsVersion ?>"></script>
<script>
    window.clearSearch = function() {
        if (window.assetGrid && typeof window.assetGrid.resetFilters === 'function') {
            window.assetGrid.resetFilters();
        }
    };

    (function() {
        const mobilePagerHost = document.getElementById('assetMobilePagerHost');
        const pager = document.getElementById('assetGridPager');
        const desktopPagerHost = pager ? pager.parentNode : null;
        const desktopPagerNext = pager ? pager.nextSibling : null;
        const media = window.matchMedia ? window.matchMedia('(max-width: 1199.98px)') : null;

        window.updateAssetStickyOffset = function() {
            const nav = document.getElementById('mainNav') || document.querySelector('.navbar.fixed-top');
            if (!nav) return;

            const rect = nav.getBoundingClientRect();
            const top = Math.max(0, Math.ceil(rect.bottom));
            document.documentElement.style.setProperty('--asset-sticky-top', top + 'px');
        };

        window.moveAssetPagerIntoSticky = function() {
            if (!mobilePagerHost || !pager) return;

            if (media && media.matches) {
                if (pager.parentNode !== mobilePagerHost) {
                    mobilePagerHost.appendChild(pager);
                }
                return;
            }

            if (desktopPagerHost && pager.parentNode !== desktopPagerHost) {
                desktopPagerHost.insertBefore(pager, desktopPagerNext);
            }
        };

        window.updateAssetStickyOffset();
        window.moveAssetPagerIntoSticky();
        window.addEventListener('resize', window.updateAssetStickyOffset, { passive: true });
        window.addEventListener('orientationchange', function() {
            window.setTimeout(window.updateAssetStickyOffset, 100);
        });
        if (media) {
            if (typeof media.addEventListener === 'function') {
                media.addEventListener('change', function() {
                    window.updateAssetStickyOffset();
                    window.moveAssetPagerIntoSticky();
                });
            } else if (typeof media.addListener === 'function') {
                media.addListener(function() {
                    window.updateAssetStickyOffset();
                    window.moveAssetPagerIntoSticky();
                });
            }
        }
    })();

    document.addEventListener('DOMContentLoaded', function() {
        if (typeof window.updateAssetStickyOffset === 'function') {
            window.updateAssetStickyOffset();
        }
        if (typeof window.moveAssetPagerIntoSticky === 'function') {
            window.moveAssetPagerIntoSticky();
        }

        const isOnboarding = window.assetGridConfig && window.assetGridConfig.showOnboarding;
        if (isOnboarding) {
            const overlay = document.getElementById('loadingOverlay');
            if (overlay) overlay.style.display = 'none';

            const targetButtonId = window.assetGridConfig.onboardingStep === 'location' ? 'newSite' : 'newAsset';
            const button = document.getElementById(targetButtonId);
            if (button) {
                button.classList.remove('btn-secondary');
                button.classList.add('btn-info', 'asset-onboarding-toolbar-highlight');
                button.style.color = '#ffffff';
            }
        } else if (window.createAssetGrid) {
            window.assetGrid = window.createAssetGrid(window.assetGridConfig);
        } else {
            const overlay = document.getElementById('loadingOverlay');
            if (overlay) overlay.style.display = 'none';
            const container = document.getElementById('assetTableContainer');
            if (container) container.style.visibility = 'visible';
            if (typeof showResponse === 'function') {
                showResponse('danger', 'Asset grid script did not load correctly.');
            }
        }

        function openStandardAssetModal(button, modalId, fallbackTitle, modalSize) {
            const target = button.dataset.href || button.getAttribute('data-href');
            const string = button.dataset.values || button.getAttribute('data-values');
            const title = button.getAttribute('data-modal-title') || button.getAttribute('title') || fallbackTitle;
            if (!target || !string) {
                if (typeof showResponse === 'function') showResponse('danger', 'Button data is missing.');
                return;
            }
            const dest = encodeURI(`${target}?data=${string}&tenant=${TENANT_URL}`);
            loadModalContent(dest, modalId, modalSize, 1060, 'true', title);
        }

        function archiveConfirmAction(values, modalId) {
            const parts = String(values || '').split('|');
            const modalBody = document.querySelector('#' + modalId + ' .modal-body');
            if (modalBody) {
                modalBody.innerHTML =
                    '<h1 class="text-center"><i class="fad fa-file-archive fa-spin fa-3x fa-fw" style="--fa-primary-color: #0055A6; --fa-secondary-color: gray;"></i><br>Updating Asset <br><small>Please wait</small></h1>';
            }
            $.post(ROOT_URL + '/includes/master/archive.php', {
                tenant: TENANT_URL,
                mode: "update",
                clientnumber: parts[0] || '',
                itemnumber: parts[2] || '',
                statuslive: parts[3] || 'archive'
            }, function(data) {
                if ($.trim(data) == "done") {
                    location.reload();
                    return;
                }
                if (typeof showResponse === 'function') showResponse('danger', 'There has been an error');
            });
        }

        document.body.addEventListener('click', function(event) {
            const formButton = event.target.closest('.formButton');
            if (formButton) {
                event.preventDefault();
                openStandardAssetModal(formButton, 'popupBox', 'New Report', 'modal-xl');
                return;
            }

            const transferButton = event.target.closest('.transferButton');
            if (transferButton) {
                event.preventDefault();
                openStandardAssetModal(transferButton, 'transferBox', 'Move', 'modal-md');
                return;
            }

            const archiveButton = event.target.closest('.archiveButton');
            if (archiveButton) {
                event.preventDefault();
                const target = archiveButton.dataset.href || archiveButton.getAttribute('data-href');
                const string = archiveButton.dataset.values || archiveButton.getAttribute('data-values');
                const title = archiveButton.getAttribute('data-modal-title') || archiveButton.getAttribute(
                    'title') || 'Archive';
                if (!target || !string) {
                    if (typeof showResponse === 'function') showResponse('danger',
                        'Button data is missing.');
                    return;
                }
                const dest = encodeURI(`${target}?data=${string}&tenant=${TENANT_URL}`);
                loadModalContent(dest, 'popupBox', 'modal-md', 1060, 'true', title, 'cancelConfirm',
                    function() {
                        archiveConfirmAction(string, 'popupBox');
                    });
                return;
            }

            const cloneButton = event.target.closest('.cloneButton');
            if (cloneButton) {
                event.preventDefault();
                openStandardAssetModal(cloneButton, 'cloneBox', 'Clone Item', 'modal-xxl');
                return;
            }

            const importButton = event.target.closest('.importButton');
            if (importButton) {
                event.preventDefault();
                const target = importButton.dataset.href || importButton.getAttribute('data-href');
                const string = importButton.dataset.values || importButton.getAttribute('data-values');
                const dest = encodeURI(
                    `${target}?data=${string}&tenant=${TENANT_URL}&clientnumber=<?= $clientnumber ?>`);
                loadModalContent(dest, 'uploadBox', 'modal-xxl', 1060, 'true', 'Import Assets');
            }
        });
    });

    async function printSchedule(scriptPath, header, client = null) {
        const fullUrl =
            `${scriptPath}?clientnumber=${encodeURIComponent(client)}&tenant=${encodeURIComponent(TENANT_URL)}`;
        const response = await fetch(fullUrl);
        if (!response.ok) return;
        const contentHtml = await response.text();
        printContainer(contentHtml, {
            orientation: 'landscape',
            header: `<p>${header}</p>`,
            footer: `<p>Generated by EnRep Reporting System: ${new Date().toLocaleDateString()}</p>`,
            logoUrl: 'images/company/logo.jpg',
            styles: [`${ROOT_URL}/src/css/print.css`]
        });
    }

    async function getAssetSelectionItems() {
        if (window.assetGrid && typeof window.assetGrid.getSelectedItemArray === 'function') {
            const items = window.assetGrid.getSelectedItemArray();
            if (items.length < 1) {
                if (typeof showResponse === 'function') showResponse('warning', 'Please select at least one item.');
                return [];
            }
            return items;
        }
        return [];
    }

    async function getAssetSelectionParam() {
        const items = await getAssetSelectionItems();
        if (items.length < 1) return '';
        return 'items=' + encodeURIComponent(items.join(','));
    }

    async function openAssetMassModal(path, targetBox, modalClass, title, closeMode, extraParams, actionButton) {
        const selectionParam = await getAssetSelectionParam();
        if (!selectionParam) return;
        const params = [
            'clientnumber=<?= $clientnumber ?>',
            'tenant=' + encodeURIComponent(TENANT_URL),
            extraParams,
            selectionParam
        ].filter(Boolean).join('&');
        loadModalContent(ROOT_URL + path + '?' + params, targetBox, modalClass, 1060, 'true', title, closeMode,
            actionButton);
    }

    async function openAssetMassModalPost(path, targetBox, modalClass, title, closeMode, extraParams, actionButton) {
        const items = await getAssetSelectionItems();
        if (items.length < 1) return;

        const postData = new URLSearchParams({
            clientnumber: '<?= $clientnumber ?>',
            tenant: TENANT_URL,
            items: items.join(',')
        });

        if (extraParams) {
            new URLSearchParams(extraParams).forEach((value, key) => {
                postData.append(key, value);
            });
        }

        try {
            const response = await fetch(ROOT_URL + path, {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/x-www-form-urlencoded'
                },
                body: postData.toString()
            });

            if (!response.ok) {
                throw new Error(`Modal request failed with status ${response.status}`);
            }

            const modalHtml = await response.text();
            loadModalContent(modalHtml, targetBox, modalClass, 1060, 'true', title, closeMode, actionButton);
        } catch (error) {
            console.error('Mass action modal request failed:', error);
            if (typeof showResponse === 'function') {
                showResponse('danger', 'There was an error loading the mass action window.');
            }
        }
    }

    function massMigrate() {
        openAssetMassModal('/includes/master/transfer.php', 'transferBox', 'modal-xl', 'Mass move items', 'cancel',
            'mode=mass');
    }

    function massArchive() {
        openAssetMassModal('/includes/master/archive.php', 'popupBox', 'modal-xl', 'Mass archive items', 'cancelConfirm',
            'mode=mass',
            function() {
                const items = document.querySelector('#popupBox #itemList');
                if (items && typeof window.confirmMassArchive === 'function') {
                    window.confirmMassArchive(items.value);
                }
            });
    }

    function massCode() {
        openAssetMassModal('/includes/master/codeChange.php', 'popupBox', 'modal-xl', 'Mass code change items', 'cancel',
            'mode=mass');
    }

    function massChain() {
        openAssetMassModal('/includes/mass/massChain.php', 'popupBox', 'modal-md', 'Mass chain items', 'cancelConfirm',
            '', 'processLinking');
    }

    function massMoveChain() {
        openAssetMassModal('/includes/mass/massMoveChain.php', 'popupBox', 'modal-xl', 'Mass move chain items',
            'cancelConfirm', '', 'processChain');
    }

    function massPNA() {
        openAssetMassModalPost('/includes/mass/massPna.php', 'pnaBoxes', 'modal-xxl', 'Mass PNA items', 'cancelConfirm', '',
            'processPna');
    }
</script>
