<!DOCTYPE html>

<html lang="en">

  <head>

    <base target="_top">

    <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=0, viewport-fit=cover"/>

    <link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap" rel="stylesheet">

    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">

    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.10.5/font/bootstrap-icons.css">

    

    <link rel="stylesheet" href="https://cdn.datatables.net/1.13.6/css/jquery.dataTables.min.css">

    <link rel="stylesheet" href="https://cdn.datatables.net/responsive/2.5.0/css/responsive.dataTables.min.css">

    <link rel="stylesheet" href="https://cdn.datatables.net/rowgroup/1.4.0/css/rowGroup.dataTables.min.css">

    

    <script src="https://code.jquery.com/jquery-3.7.0.min.js"></script>

    <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>

    <script src="https://cdn.datatables.net/1.13.6/js/jquery.dataTables.min.js"></script>

    <script src="https://cdn.datatables.net/responsive/2.5.0/js/dataTables.responsive.min.js"></script>

    <script src="https://cdn.datatables.net/rowgroup/1.4.0/js/dataTables.rowGroup.min.js"></script>

    <script src="https://unpkg.com/html5-qrcode"></script>

    <script src="https://cdnjs.cloudflare.com/ajax/libs/xlsx/0.18.5/xlsx.full.min.js"></script>

    

    <style>

      :root { --gdt-bg: #f4f7f9; --gdt-card-bg: #ffffff; --gdt-primary: #4f46e5; --gdt-primary-hover: #4338ca; --gdt-text-main: #1e293b; --gdt-text-muted: #64748b; --gdt-border: #e2e8f0; }

      body { background-color: var(--gdt-bg); font-family: 'Inter', sans-serif; color: var(--gdt-text-main); min-height: 100vh; overflow-x: hidden; }

      .card, .modal-content { background-color: var(--gdt-card-bg) !important; border: 1px solid rgba(0,0,0,0.05) !important; border-radius: 16px; box-shadow: 0 4px 20px rgba(0, 0, 0, 0.03); }

      .modal-header { background-color: #f8fafc; border-bottom: 1px solid var(--gdt-border); border-top-left-radius: 16px; border-top-right-radius: 16px; color: var(--gdt-text-main); }

      .form-control, .form-select { border-radius: 8px; border: 1px solid #cbd5e1; font-size: 14px; padding: 10px 14px; transition: all 0.15s ease-in-out; }

      .form-control:focus, .form-select:focus { border-color: var(--gdt-primary); box-shadow: 0 0 0 3px rgba(79, 70, 229, 0.1); outline: none; }

      .form-control:disabled { background-color: #f1f5f9; }

      .btn { border-radius: 8px; font-weight: 500; font-size: 14px; }

      .btn-primary { background-color: var(--gdt-primary); border: none; }

      label.fw-bold { font-size: 0.75rem; color: var(--gdt-text-muted); margin-bottom: 6px; display: block; font-weight: 600; }

      .accordion-button { font-weight: 600; background-color: #f8fafc; border-radius: 8px !important; margin-bottom: 8px; border: 1px solid var(--gdt-border); font-size: 14px; }

      .accordion-button:not(.collapsed) { background-color: #eff6ff; color: var(--gdt-primary); box-shadow: none; border-bottom: none; }

      .accordion-body { background: #fff; border: 1px solid var(--gdt-border); border-top: none; margin-bottom: 8px; padding: 16px; border-radius: 0 0 8px 8px; }

      .top-badge { background-color: #e0e7ff; color: var(--gdt-primary); font-size: 0.65rem; font-weight: 700; padding: 4px 8px; border-radius: 4px; }

      

      .category-pill { background-color: #ffffff; border: 1px solid #e2e8f0; color: #4f46e5; font-weight: 600; padding: 8px 16px; border-radius: 50px; font-size: 13.5px; cursor: pointer; transition: all 0.2s ease; box-shadow: 0 2px 4px rgba(0,0,0,0.02); display: flex; align-items: center; gap: 8px; white-space: nowrap; }

      .category-pill:hover { border-color: #818cf8; transform: translateY(-1px); box-shadow: 0 4px 8px rgba(0,0,0,0.05); }

      .category-pill.active { background-color: #4f46e5; color: #ffffff; border-color: #4f46e5; }

      .category-pill .badge-count { background-color: #e0e7ff; color: #4f46e5; font-size: 11px; padding: 2px 8px; border-radius: 12px; font-weight: 700; }

      .category-pill.active .badge-count { background-color: #ffffff; color: #4f46e5; }

      .category-pill.warning-pill { border-color: #fca5a5; color: #dc2626; }

      .category-pill.warning-pill.active { background-color: #dc2626; color: #ffffff; border-color: #dc2626; }

      .category-pill.warning-pill .badge-count { background-color: #fee2e2; color: #dc2626; }

      .category-pill.warning-pill.active .badge-count { background-color: #ffffff; color: #dc2626; }

      

      .asset-card { background-color: #ffffff; border: 1px solid #bfdbfe; border-radius: 12px; padding: 16px; margin-bottom: 12px; cursor: pointer; transition: all 0.2s ease; box-shadow: 0 1px 3px rgba(0,0,0,0.03); }

      .asset-card:hover { border-color: #60a5fa; box-shadow: 0 4px 12px rgba(0,0,0,0.06); transform: translateY(-1px); }

      .asset-card.old-pc-alert { border: 2px solid #fb923c; background-color: #fffaf0; }

      .custom-badge { font-size: 11px; font-weight: 600; padding: 5px 14px; border-radius: 20px; display: inline-block; }

      .warning-badge { background-color: #fee2e2; color: #dc2626; font-size: 11px; font-weight: 700; padding: 5px 10px; border-radius: 20px; margin-right: 8px; }


      .search-container { position: relative; width: 100%; margin-bottom: 20px; }

      .search-container i { position: absolute; left: 14px; top: 12px; color: #94a3b8; }

      .search-container input { padding-left: 40px; border-radius: 12px; border: 1px solid #cbd5e1; width: 100%; padding-top: 12px; padding-bottom: 12px; font-size: 15px; }

      

      table.dataTable thead { display: none; }

      table.dataTable.no-footer { border-bottom: none !important; }

      table.dataTable tbody td { padding: 4px 0 !important; border-bottom: none !important; }

      .group-header { cursor:pointer; background-color: #f8fafc !important; font-weight: 600 !important; padding: 12px !important; border-radius: 8px; border: 1px solid #e2e8f0; margin-bottom: 8px; display: block; }

      .badge-count-folder { background-color: #1e293b !important; color: #ffffff !important; padding: 4px 10px; border-radius: 12px; font-size: 12px; font-weight: 700; margin-left: 8px; }


      #historyContainer::-webkit-scrollbar { width: 6px; }

      #historyContainer::-webkit-scrollbar-thumb { background-color: #cbd5e1; border-radius: 4px; }

      .timeline-change-box { background-color: #f8fafc; border: 1px dashed #cbd5e1; border-radius: 6px; padding: 10px; font-size: 12.5px; line-height: 1.5; color: #334155; }

    </style>

  </head>

  <body>

    <!-- LOGIN VIEW -->

    <div id="loginView" style="height: 100vh; display: flex; align-items: center; justify-content: center; padding: 15px;">

      <div class="card p-4 mx-auto w-100" style="max-width: 400px;">

        <div class="text-center mb-4"><h4 class="fw-bold mb-1">IT Asset Portal</h4><span class="top-badge">SECURE LOGIN</span></div>

        <form id="loginForm" onsubmit="event.preventDefault(); attemptLogin();">

            <div class="mb-3"><label class="fw-bold">Officer ID</label><input type="text" id="officerId" class="form-control" autocomplete="username"></div>

            <div class="mb-3"><label class="fw-bold">PIN Code</label><input type="password" id="pinCode" class="form-control" autocomplete="current-password"></div>

            <div class="d-flex justify-content-between align-items-center mb-4">

              <div class="form-check"><input class="form-check-input" type="checkbox" id="rememberMe"><label class="form-check-label text-muted small" for="rememberMe">Remember me</label></div>

              <a href="#" onclick="forgotPinModal.show(); return false;" class="small fw-bold text-primary text-decoration-none">Forgot PIN?</a>

            </div>

            <button type="submit" class="btn btn-primary w-100" id="loginBtn">Authenticate</button>

            <div id="loginMessage" class="mt-3 text-center fw-bold small"></div>

        </form>

      </div>

    </div>


    <!-- RECOVER PIN MODAL -->

    <div class="modal fade" id="forgotPinModal" tabindex="-1">

      <div class="modal-dialog modal-dialog-centered modal-sm">

        <div class="modal-content">

          <div class="modal-header p-3"><h6 class="modal-title fw-bold m-0 text-primary">Recover PIN</h6><button type="button" class="btn-close" data-bs-dismiss="modal"></button></div>

          <div class="modal-body p-4 bg-light">

            <label class="fw-bold">Officer ID</label><input type="text" id="fp_officerId" class="form-control mb-2">

            <div id="fpMessage" class="text-center small fw-bold"></div>

          </div>

          <div class="modal-footer p-3 bg-white"><button class="btn btn-primary w-100 fw-bold" id="fpSendBtn" onclick="submitForgotPin()">Send PIN to Email</button></div>

        </div>

      </div>

    </div>


    <!-- DASHBOARD VIEW -->

    <div id="dashboardView" style="display: none; padding: 20px 10px;">

       <div class="d-flex justify-content-between align-items-center mb-4 mx-auto" style="max-width: 1200px;">

          <div>

              <div class="d-flex align-items-center gap-2 mb-1"><h4 class="fw-bold m-0" id="welcomeName"></h4><span class="top-badge">LIVE MATRIX</span></div>

              <span class="text-muted small" id="assignedBranch"></span>

          </div>

          <div class="d-flex gap-2">

            <button class="btn btn-light btn-sm text-primary fw-bold shadow-sm" onclick="openPinModal()">Change PIN</button>

            <button class="btn btn-light btn-sm text-danger fw-bold shadow-sm" onclick="logout()">Logout</button>

          </div>

       </div>


       <div class="card mx-auto mb-4" style="max-width: 1200px; background: transparent; box-shadow: none; border: none !important;">

         <div class="d-flex justify-content-between align-items-center mb-3 flex-wrap gap-2">

            <div class="search-container mb-0" style="max-width: 400px; flex-grow: 1;">

              <i class="bi bi-search"></i>

              <input type="text" id="globalSearch" placeholder="Search by Hostname, Barcode, User, Serial..." onkeyup="handleSearch()">

            </div>

            <div class="d-flex gap-2">

                <button class="btn btn-success fw-bold text-white shadow-sm" onclick="triggerDownload()"><i class="bi bi-file-earmark-excel"></i> Export</button>

                <button class="btn btn-primary fw-bold shadow-sm" onclick="openModal('add')"><i class="bi bi-plus-lg"></i> Add Asset</button>

            </div>

         </div>


         <div class="d-flex flex-wrap gap-2 mb-4" id="categoryPillsContainer" style="overflow-x: auto; padding-bottom: 8px;"></div>

         

         <div id="loading" class="text-center my-5"><div class="spinner-border text-primary"></div></div>

         

         <div id="tableContainer" style="display: none; width: 100%;">

            <table id="assetTable" class="table w-100">

              <thead><tr><th>Group</th><th>Card</th></tr></thead>

              <tbody id="tableBody"></tbody>

            </table>

         </div>

       </div>

    </div>


    <!-- CHANGE PIN MODAL -->

    <div class="modal fade" id="pinModal" tabindex="-1">

      <div class="modal-dialog modal-dialog-centered modal-sm">

        <div class="modal-content">

          <div class="modal-header p-3"><h6 class="modal-title fw-bold text-primary">Change PIN</h6><button type="button" class="btn-close" data-bs-dismiss="modal"></button></div>

          <div class="modal-body p-4 bg-light">

            <label class="fw-bold">Current PIN</label><input type="password" id="p_oldPin" class="form-control mb-3">

            <label class="fw-bold">New PIN</label><input type="password" id="p_newPin" class="form-control mb-3">

            <label class="fw-bold">Confirm New PIN</label><input type="password" id="p_confirmPin" class="form-control mb-2">

            <div id="pinMessage" class="fw-bold text-center small"></div>

          </div>

          <div class="modal-footer p-3 bg-white"><button class="btn btn-primary w-100 fw-bold" id="pinSaveBtn" onclick="submitPinChange()">Update PIN</button></div>

        </div>

      </div>

    </div>


    <!-- EXPORT MODAL -->

    <div class="modal fade" id="downloadModal" tabindex="-1">

      <div class="modal-dialog modal-dialog-centered modal-sm">

        <div class="modal-content">

          <div class="modal-header p-3"><h6 class="modal-title fw-bold text-primary">Export Options</h6><button type="button" class="btn-close" data-bs-dismiss="modal"></button></div>

          <div class="modal-body p-3 bg-light">

            <label class="fw-bold mb-2">Export Scope:</label>

            <select id="exportScope" class="form-select mb-3">

              <option value="current">Current Dashboard View</option>

              <option value="all">All Inventory</option>

              <option value="old">Only 5+ Year PCs</option>

            </select>

            <label class="fw-bold mb-2">Select Target Branches:</label>

            <div class="form-check mb-2 pb-2 border-bottom"><input class="form-check-input" type="checkbox" id="selectAllBranches" checked onchange="toggleAllBranches(this)"><label class="form-check-label fw-bold text-primary small" for="selectAllBranches">Select All Branches</label></div>

            <div id="branchCheckboxes" style="max-height: 220px; overflow-y: auto;"></div>

          </div>

          <div class="modal-footer p-3 bg-white"><button class="btn btn-success w-100 fw-bold text-white" onclick="executeDownload()">Download Excel</button></div>

        </div>

      </div>

    </div>


    <!-- ASSET MODAL -->

    <div class="modal fade" id="assetModal" tabindex="-1" data-bs-backdrop="static">

      <div class="modal-dialog modal-dialog-scrollable modal-fullscreen-sm-down">

        <div class="modal-content">

          <div class="modal-header p-4"><h5 class="modal-title fw-bold m-0" id="modalTitle">Asset Details</h5><button type="button" class="btn-close" onclick="closeModal()"></button></div>

          <div class="modal-body bg-light p-4">

            <input type="hidden" id="formAction"> <input type="hidden" id="editIndex">

            <div id="hiddenReader" style="display:none;"></div>

            <input type="file" id="barcodeNativeCamera" accept="image/*" capture="environment" style="display:none;">

            <datalist id="suggestionList"></datalist>


            <div class="accordion" id="assetAccordion">

              <div class="accordion-item">

                <h2 class="accordion-header"><button class="accordion-button" type="button" data-bs-toggle="collapse" data-bs-target="#colId">1. ID & Status</button></h2>

                <div id="colId" class="accordion-collapse collapse show"><div class="accordion-body">

                    <div class="mb-3"><label class="fw-bold">Barcode ID *</label>

                      <div class="input-group"><input type="text" id="f_barcode" class="form-control req-field"><button class="btn btn-primary" type="button" id="scanBtn" onclick="document.getElementById('barcodeNativeCamera').click()"><i class="bi bi-camera-fill"></i></button></div>

                    </div>

                    <div class="mb-3"><label class="fw-bold" id="lbl_ciName">CI Name (Hostname) *</label><input type="text" id="f_ciName" class="form-control req-field"></div>

                    <div class="mb-3"><label class="fw-bold">Asset State *</label>

                      <select id="f_assetState" class="form-select req-field"><option value="In Use">In Use</option><option value="Repairing">Repairing</option><option value="Broken">Broken</option><option value="Request Deletion">Request Deletion</option></select>

                    </div>

                    <div class="row g-2 mb-0">

                        <div class="col-4"><label class="fw-bold text-truncate" style="font-size: 11px;">Label ខ្សែបណ្តាញ</label><select id="f_lblNetwork" class="form-select px-2 py-1" style="font-size: 13px;"><option value="" disabled selected></option><option value="មាន">មាន</option><option value="គ្មាន">គ្មាន</option><option value="មិនទាន់រៀបចំ">មិនទាន់រៀបចំ</option></select></div>

                        <div class="col-4"><label class="fw-bold text-truncate" style="font-size: 11px;">ស្លាកស្តង់ដារ</label><select id="f_lblStandard" class="form-select px-2 py-1" style="font-size: 13px;"><option value="" disabled selected></option><option value="មាន">មាន</option><option value="គ្មាន">គ្មាន</option><option value="រលុប">រលុប</option></select></div>

                        <div class="col-4"><label class="fw-bold text-truncate" style="font-size: 11px;">ខ្សែ Seal</label><select id="f_lblSeal" class="form-select px-2 py-1" style="font-size: 13px;"><option value="" disabled selected></option><option value="មាន">មាន</option><option value="គ្មាន">គ្មាន</option><option value="ដាច់">ដាច់</option></select></div>

                    </div>

                </div></div>

              </div>

              <div class="accordion-item">

                <h2 class="accordion-header"><button class="accordion-button collapsed" type="button" data-bs-toggle="collapse" data-bs-target="#colHard">2. Hardware Specs</button></h2>

                <div id="colHard" class="accordion-collapse collapse"><div class="accordion-body">

                    <div class="mb-2"><label class="fw-bold">Product Type</label>

                       <select id="f_prodType" class="form-select" onchange="toggleDynamicFields()">

                         <option value="Terminal Computer">Terminal Computer</option><option value="Workstation">Workstation</option>

                         <option value="Monitor">Monitor</option><option value="USB Printer">USB Printer</option>

                         <option value="Network Printer">Network Printer</option><option value="Barcode Reader">Barcode Reader</option>

                         <option value="IP Phone">IP Phone</option><option value="Scanner">Scanner</option>

                         <option value="Other">Other</option>

                       </select>

                    </div>

                    <div class="mb-2"><label class="fw-bold">Model</label><input type="text" id="f_model" class="form-control"></div>

                    <div class="mb-2"><label class="fw-bold" id="lbl_serviceTag">Service Tag (Serial)</label><input type="text" id="f_serviceTag" class="form-control"></div>

                    <div class="row g-2 mb-0" id="pcHardwareFields"><div class="col-6"><label class="fw-bold">Processor</label><input type="text" id="f_processor" class="form-control"></div><div class="col-6"><label class="fw-bold">Memory (RAM)</label><input type="text" id="f_memory" class="form-control"></div></div>

                </div></div>

              </div>

              <div class="accordion-item">

                <h2 class="accordion-header"><button class="accordion-button collapsed" type="button" data-bs-toggle="collapse" data-bs-target="#colLoc">3. Location & Network</button></h2>

                <div id="colLoc" class="accordion-collapse collapse"><div class="accordion-body">

                    <div class="mb-2"><label class="fw-bold">Department / Branch *</label><input type="text" id="f_department" class="form-control req-field"></div>

                    <div class="row g-2 mb-2"><div class="col-6"><label class="fw-bold">Building</label><input type="text" id="f_locationName" class="form-control"></div><div class="col-6"><label class="fw-bold">Floor</label><input type="text" id="f_floor" class="form-control"></div></div>

                    <div class="row g-2 mb-2"><div class="col-6"><label class="fw-bold">Room Name</label><input type="text" id="f_roomName" class="form-control"></div><div class="col-6"><label class="fw-bold">Table Num</label><input type="text" id="f_tableNum" class="form-control"></div></div>

                    <div class="row g-2 mb-0"><div class="col-6"><label class="fw-bold">Switch ID</label><input type="text" id="f_switchId" class="form-control"></div><div class="col-6"><label class="fw-bold">Switch Port</label><input type="text" id="f_switchPort" class="form-control"></div></div>

                    <input type="hidden" id="f_roomNum"> <input type="hidden" id="f_connType" value="Local"> <input type="hidden" id="f_domain" value="TAX.LOCAL">

                </div></div>

              </div>

              <div class="accordion-item">

                <h2 class="accordion-header"><button class="accordion-button collapsed" type="button" data-bs-toggle="collapse" data-bs-target="#colUser">4. User Assignment</button></h2>

                <div id="colUser" class="accordion-collapse collapse"><div class="accordion-body">

                    <div class="row g-2 mb-2"><div class="col-4"><label class="fw-bold">Staff ID</label><input type="text" id="f_staffId" class="form-control"></div><div class="col-8"><label class="fw-bold">User Name *</label><input type="text" id="f_user" class="form-control req-field"></div></div>

                    <div class="mb-0"><label class="fw-bold">Position</label><input type="text" id="f_position" class="form-control"></div>

                </div></div>

              </div>

              <div class="accordion-item">

                <h2 class="accordion-header"><button class="accordion-button collapsed" type="button" data-bs-toggle="collapse" data-bs-target="#colLife">5. Lifecycle Details</button></h2>

                <div id="colLife" class="accordion-collapse collapse"><div class="accordion-body">

                    <div class="row g-2 mb-2"><div class="col-6"><label class="fw-bold">Acquisition Date</label><input type="date" id="f_acqDate" class="form-control"></div><div class="col-6"><label class="fw-bold">Warranty Expiry</label><input type="date" id="f_warrantyDate" class="form-control"></div></div>

                    <div class="row g-2 mb-0"><div class="col-6"><label class="fw-bold">Vendor</label><input type="text" id="f_vendor" class="form-control"></div><div class="col-6"><label class="fw-bold">Source</label><input type="text" id="f_source" class="form-control"></div></div>

                    <input type="hidden" id="f_regDate"> <input type="hidden" id="f_remark">

                </div></div>

              </div>

              <div class="accordion-item">

                <h2 class="accordion-header"><button class="accordion-button collapsed" type="button" data-bs-toggle="collapse" data-bs-target="#colConnect"><i class="bi bi-link-45deg me-2 text-primary"></i>6. Connected Devices</button></h2>

                <div id="colConnect" class="accordion-collapse collapse"><div class="accordion-body">

                    <div class="mb-0">

                        <label class="fw-bold">Connected Asset (Hostname / Service Tag)</label>

                        <input type="text" id="f_connectedAsset" list="suggestionList" class="form-control" placeholder="Search or type manually...">

                    </div>

                </div></div>

              </div>

              <div class="accordion-item" id="historyAccordionWrapper" style="display:none;">

                <h2 class="accordion-header"><button class="accordion-button collapsed text-success" type="button" data-bs-toggle="collapse" data-bs-target="#colHistory"><i class="bi bi-clock-history me-2"></i>7. Asset Edit History</button></h2>

                <div id="colHistory" class="accordion-collapse collapse"><div class="accordion-body">

                    <div id="historyContainer" style="max-height: 300px; overflow-y: auto;" class="small text-muted text-center">Loading timeline...</div>

                </div></div>

              </div>

            </div>


            <div class="mt-4 p-3 bg-white rounded shadow-sm border">

              <h6 class="fw-bold mb-3"><i class="bi bi-shield-check text-primary me-1"></i> Mandatory Audit Trail</h6>

              <div class="mb-3"><label class="fw-bold">Reason for Change *</label><input type="text" id="f_reason" class="form-control req-field"></div>

              <div class="mb-0"><label class="fw-bold">Live Photo Proof (Optional)</label><input type="file" id="f_auditPhoto" accept="image/*" capture="environment" class="form-control"></div>

            </div>

            <div id="statusMessage" class="fw-bold mt-3 text-center"></div>

          </div>

          <div class="modal-footer p-3 bg-white d-flex gap-2">

            <button type="button" class="btn btn-light flex-grow-1" onclick="closeModal()">Cancel</button>

            <button type="button" class="btn btn-primary flex-grow-1" id="saveBtn" onclick="saveData()">Save Record</button>

          </div>

        </div>

      </div>

    </div>


    <!-- JS -->

    <script>

      // ==========================================

      // CLOUDFLARE API ENDPOINT CONFIGURATION

      // ==========================================

      const API_URL = "https://script.google.com/macros/s/AKfycbxkp0v8Vfdtanrb8HknIB04yQN-FM9chAfsQMhHH0UIHwsnlYHlVBGZUg3G-TmZhWNF/exec"; 


      function callApi(action, payload = {}) {

          payload.action = action;

          return fetch(API_URL, {

              method: 'POST',

              body: JSON.stringify(payload)

          })

          .then(res => res.json())

          .catch(err => {

              console.error("API Call Error:", err);

              return { success: false, error: err.message };

          });

      }


      let assetModal, downloadModal, pinModal, forgotPinModal, html5QrCode, userLat=null, userLng=null, fullDataset=[];

      let activeCategory = 'All'; 

      let collapsedGroups = {};

      let dataTableInstance = null;


      const categories = [

          { id: 'All', icon: 'bi-grid-fill', label: 'All Assets' },

          { id: 'Monitor', icon: 'bi-display', label: 'Monitor' },

          { id: 'Terminal Computer', icon: 'bi-pc-display-horizontal', label: 'Terminal Computer' },

          { id: 'USB Printer', icon: 'bi-printer', label: 'USB Printer' },

          { id: 'Network Printer', icon: 'bi-printer-fill', label: 'Network Printer' },

          { id: 'Barcode Reader', icon: 'bi-upc-scan', label: 'Barcode Reader' },

          { id: 'IP Phone', icon: 'bi-telephone-fill', label: 'IP Phone' },

          { id: 'Scanner', icon: 'bi-qr-code-scan', label: 'Scanner' },

          { id: '5+ Years', icon: 'bi-flag-fill', label: '5+ Year PCs', isWarning: true }

      ];


      function toggleDynamicFields() {

          const type = document.getElementById('f_prodType').value;

          const isPC = type === 'Terminal Computer' || type === 'Workstation';

          const isPhone = type === 'IP Phone';


          const hardwareDiv = document.getElementById('pcHardwareFields'); 

          const serialLabel = document.getElementById('lbl_serviceTag');

          const ciNameLabel = document.getElementById('lbl_ciName');


          if (isPC) {

              hardwareDiv.style.display = 'flex';

              serialLabel.innerText = 'Service Tag (Serial)';

              ciNameLabel.innerText = 'CI Name (Hostname) *';

          } else if (isPhone) {

              hardwareDiv.style.display = 'none';

              serialLabel.innerText = 'MAC Address / Serial';

              ciNameLabel.innerText = 'Extension / Hostname *';

          } else {

              hardwareDiv.style.display = 'none';

              serialLabel.innerText = 'Serial Number';

              ciNameLabel.innerText = 'CI Name / Device ID *';

          }

      }


      function safeDate(val) {

          if (!val) return '';

          let str = val.toString();

          if (str.includes('T')) return str.split('T')[0];

          if (str.includes(' ')) return str.split(' ')[0];

          return str;

      }


      $.fn.dataTable.ext.search.push(

          function(settings, data, dataIndex) {

              let row = fullDataset[dataIndex];

              if (!row) return true;

              

              if (activeCategory !== 'All') {

                  if (activeCategory === '5+ Years') {

                      if (!checkIsOldPC(row)) return false;

                  } else {

                      if ((row.productType || "").trim() !== activeCategory) return false;

                  }

              }

              return true; 

          }

      );


      window.onload = function() {

        assetModal = new bootstrap.Modal(document.getElementById('assetModal'));

        downloadModal = new bootstrap.Modal(document.getElementById('downloadModal'));

        pinModal = new bootstrap.Modal(document.getElementById('pinModal'));

        forgotPinModal = new bootstrap.Modal(document.getElementById('forgotPinModal'));

        html5QrCode = new Html5Qrcode("hiddenReader");

        

        document.getElementById('barcodeNativeCamera').addEventListener('change', function(e) {

            if (e.target.files.length == 0) return;

            const scanBtn = document.getElementById('scanBtn'); scanBtn.innerHTML = '<span class="spinner-border spinner-border-sm"></span>';

            html5QrCode.scanFile(e.target.files[0], false).then(decodedText => {

                document.getElementById('f_barcode').value = decodedText; document.getElementById('f_barcode').classList.remove('is-invalid');

                scanBtn.innerHTML = '<i class="bi bi-check-lg"></i>'; setTimeout(() => scanBtn.innerHTML = '<i class="bi bi-camera-fill"></i>', 2000);

            }).catch(err => { scanBtn.innerHTML = '<i class="bi bi-camera-fill"></i>'; alert("Barcode not detected."); }); e.target.value = ''; 

        });


        if (localStorage.getItem('gdt_remember') === 'true') {

            document.getElementById('officerId').value = localStorage.getItem('gdt_id') || "";

            document.getElementById('pinCode').value = localStorage.getItem('gdt_pin') || "";

            document.getElementById('rememberMe').checked = true;

        }

        if (sessionStorage.getItem('officerId')) showDashboard(); else showLogin();

      };


      function attemptLogin() {

        const id = document.getElementById('officerId').value.trim(), pin = document.getElementById('pinCode').value.trim(), btn = document.getElementById('loginBtn');

        if(!id || !pin) return document.getElementById('loginMessage').innerHTML = "<span class='text-danger'>Enter ID and PIN.</span>";

        btn.disabled = true; btn.innerHTML = 'Authenticating...';

        

        callApi('verifyLogin', { officerId: id, pin: pin }).then(res => {

            btn.disabled = false; btn.innerHTML = 'Authenticate';

            if(res.success) {

                if(document.getElementById('rememberMe').checked) {

                    localStorage.setItem('gdt_remember', 'true'); localStorage.setItem('gdt_id', id); localStorage.setItem('gdt_pin', pin);

                } else { localStorage.removeItem('gdt_remember'); localStorage.removeItem('gdt_id'); localStorage.removeItem('gdt_pin'); }

                sessionStorage.setItem('officerId', res.officerId); sessionStorage.setItem('name', res.name);

                sessionStorage.setItem('role', res.role); sessionStorage.setItem('branch', res.branch); 

                showDashboard();

            } else document.getElementById('loginMessage').innerHTML = `<span class='text-danger'>${res.message}</span>`;

        }).catch(err => { btn.disabled = false; btn.innerHTML = 'Authenticate'; document.getElementById('loginMessage').innerHTML = `<span class='text-danger'>Error: ${err.message}</span>`; });

      }


      function logout() { sessionStorage.clear(); if (localStorage.getItem('gdt_remember') !== 'true') { document.getElementById('officerId').value = ''; document.getElementById('pinCode').value = ''; } document.getElementById('loginMessage').innerText = ''; showLogin(); }

      function showLogin() { document.getElementById('dashboardView').style.display = 'none'; document.getElementById('loginView').style.display = 'flex'; }

      

      function showDashboard() {

        document.getElementById('loginView').style.display = 'none'; document.getElementById('dashboardView').style.display = 'block';

        document.getElementById('welcomeName').innerText = sessionStorage.getItem('name');

        document.getElementById('assignedBranch').innerText = `${sessionStorage.getItem('branch')} • ${sessionStorage.getItem('role')}`;

        loadTableData();

      }

      

      function populateSuggestions() {

          const dl = document.getElementById('suggestionList'); dl.innerHTML = ''; let opts = new Set();

          fullDataset.forEach(i => {

              if (i.rawRow[9] && i.rawRow[9] !== 'N/A') opts.add(i.rawRow[9].toString().trim()); 

              if (i.rawRow[18]) opts.add(i.rawRow[18].toString().trim());

          });

          opts.forEach(val => { let opt = document.createElement('option'); opt.value = val; dl.appendChild(opt); });

      }


      function checkIsOldPC(row) {

          const type = (row.productType || "").toLowerCase();

          if (!type.includes('workstation') && !type.includes('terminal') && !type.includes('pc')) return false;

          if (!row.rawRow[12]) return false;

          const acqDate = new Date(row.rawRow[12]);

          if (isNaN(acqDate.getTime())) return false;

          const ageMonths = (new Date() - acqDate) / (1000 * 60 * 60 * 24 * 30.44);

          return ageMonths > 60;

      }


      function loadTableData() {

        document.getElementById('tableContainer').style.display = 'none'; 

        document.getElementById('loading').style.display = 'block';

        

        callApi('getSecureReportData', { officerId: sessionStorage.getItem('officerId') })

          .then(data => {

              if (data && data.error) {

                  document.getElementById('loading').innerHTML = `<div class="text-danger fw-bold"><i class="bi bi-exclamation-triangle"></i> Backend Error: ${data.error}</div>`;

                  return;

              }

              if (!data || data.length === 0) {

                  document.getElementById('loading').innerHTML = `<div class="text-danger fw-bold"><i class="bi bi-database-x"></i> 0 Rows Found. Did your Google Sheet Tab name change?</div>`;

              } else {

                  document.getElementById('loading').style.display = 'none'; 

              }

              

              fullDataset = data || []; 

              populateSuggestions();

              updatePillCounts(); 

              renderTableOnce(fullDataset);

              document.getElementById('tableContainer').style.display = 'block';

          })

          .catch(err => {

              document.getElementById('loading').innerHTML = `<div class="text-danger fw-bold"><i class="bi bi-x-octagon-fill"></i> Connection Error: ${err.message}</div>`;

          });

      }


      function handleSearch() {

          let val = document.getElementById('globalSearch').value;

          if(dataTableInstance) dataTableInstance.search(val).draw();

          updatePillCounts();

      }


      function updatePillCounts() {

          const term = document.getElementById('globalSearch').value.toLowerCase().trim();

          let counts = { 'All': 0, 'Monitor': 0, 'Terminal Computer': 0, 'USB Printer': 0, 'Network Printer': 0, 'Barcode Reader': 0, 'IP Phone': 0, 'Scanner': 0, '5+ Years': 0 };

          

          fullDataset.forEach(r => {

              let matchesSearch = true;

              if(term) {

                  matchesSearch = (r.barcode||"").toLowerCase().includes(term) ||

                                  (r.ciName||"").toLowerCase().includes(term) ||

                                  (r.user||"").toLowerCase().includes(term) ||

                                  (r.rawRow[18]||"").toLowerCase().includes(term) || 

                                  (r.rawRow[30]||"").toLowerCase().includes(term); 

              }

              if(matchesSearch) {

                  counts['All']++;

                  let type = (r.productType||"").trim();

                  if (counts[type] !== undefined) counts[type]++;

                  if (checkIsOldPC(r)) counts['5+ Years']++;

              }

          });


          const pillCont = document.getElementById('categoryPillsContainer'); pillCont.innerHTML = '';

          categories.forEach(cat => {

              if (cat.id !== 'All' && counts[cat.id] === 0 && !cat.isWarning) return; 

              const isAct = activeCategory === cat.id ? 'active' : '';

              const isWarn = cat.isWarning ? 'warning-pill' : '';

              pillCont.innerHTML += `<div class="category-pill ${isWarn} ${isAct}" onclick="setCategory('${cat.id}')"><i class="bi ${cat.icon}"></i> ${cat.label} <span class="badge-count">${counts[cat.id]}</span></div>`;

          });

      }


      function setCategory(catId) { 

          activeCategory = (activeCategory === catId) ? 'All' : catId; 

          updatePillCounts(); 

          if(dataTableInstance) {

              Object.keys(collapsedGroups).forEach(k => collapsedGroups[k] = true);

              dataTableInstance.draw(); 

          }

      }


      function renderTableOnce(data) {

          if($.fn.DataTable.isDataTable('#assetTable')) $('#assetTable').DataTable().destroy();

          const tbody = document.getElementById('tableBody'); tbody.innerHTML = ''; 

          

          data.forEach((row, index) => {

              let isOld = checkIsOldPC(row);

              let warnBadge = isOld ? `<span class="warning-badge"><i class="bi bi-flag-fill"></i> 5+ Years</span>` : '';

              let oldClass = isOld ? 'old-pc-alert' : '';

              

              let badge = '<span class="custom-badge" style="background:#ecfdf5;color:#059669;">In Use</span>';

              if(row.assetState==='Broken') badge='<span class="custom-badge" style="background:#fef2f2;color:#dc2626;">Broken</span>';

              if(row.assetState==='Repairing') badge='<span class="custom-badge" style="background:#fffbeb;color:#b45309;">Repairing</span>';

              if(row.assetState==='Request Deletion') badge='<span class="custom-badge" style="background:#f1f5f9;color:#475569;">ស្នើសុំរំលាយចោល</span>';

              

              let rawDpt = (row.department||"").toString();

              let dpt = rawDpt.replace(/[\s\u200B-\u200D\uFEFF\u00A0]/g, '');

              dpt = dpt.replace(/មណ្ឌលគីរី/g, 'មណ្ឌលគិរី').replace(/បៃលិន/g, 'ប៉ៃលិន').replace(/ព្រះសីហនុ/g, 'ព្រះសីហនុ') 

                       .replace(/រដ្ឋបាលនិងកិច្ចការទូទៅ/g, 'រដ្ឋបាលនិងកិច្ចការទូទៅ').replace(/^ន\./g, 'នាយកដ្ឋាន'); 

              if (dpt.includes('នីតិកម្ម') && (dpt.includes('គោលនយោ') || dpt.includes('គោល'))) dpt = 'នាយកដ្ឋាននីតិកម្មគោលនយោបាយសារពើពន្ធនិងសហប្រតិបត្តិការពន្ធដារអន្តរជាតិ';

              if (dpt.startsWith("នាយកដ្ឋាន")) dpt = "នាយកដ្ឋាន " + dpt.substring(9);

              else if (dpt.startsWith("សាខាពន្ធដារខេត្ត")) dpt = "សាខាពន្ធដារខេត្ត " + dpt.substring(16);

              else if (dpt.startsWith("សាខាពន្ធដារខណ្ឌ")) dpt = "សាខាពន្ធដារខណ្ឌ " + dpt.substring(15);

              else if (dpt.startsWith("ទីចាត់ការ")) dpt = "ទីចាត់ការ " + dpt.substring(9);

              else if (dpt.startsWith("ខេត្ត")) dpt = "ខេត្ត " + dpt.substring(5);

              else if (dpt.startsWith("ខណ្ឌ")) dpt = "ខណ្ឌ " + dpt.substring(4);

      

              let cat = "🏢 HQ Department"; 

              if(dpt.includes("ខណ្ឌ")) cat = "📍 Khan Branch"; 

              else if(dpt.includes("ខេត្ត")) cat = "🗺 Provincial Branch"; 

              else if(!dpt || dpt.toLowerCase()==="notassigned") { cat = "⚠️ Unassigned"; dpt = "Not Assigned"; }

              let finalGroup = `${cat} — ${dpt}`;


              let ciDisplay = (row.ciName && row.ciName !== 'N/A') ? row.ciName : row.barcode;

              let displayModel = (row.productType || 'N/A') + ' ' + (row.model || '');

              let serial = row.rawRow[18] || 'No Serial';

              let connected = row.rawRow[30] ? `<span class="ms-3"><i class="bi bi-link-45deg" style="color: #64748b; font-size: 14px;"></i> តភ្ជាប់៖ <strong>${row.rawRow[30]}</strong></span>` : '';

              let acqDateText = (isOld && row.rawRow[12]) ? `<div class="ms-3 text-danger fw-bold"><i class="bi bi-calendar-x" style="font-size: 13px; margin-right: 4px;"></i> ទិញតាំងពី៖ ${safeDate(row.rawRow[12])}</div>` : '';


              let cardHtml = `

              <div class="asset-card ${oldClass}" onclick="openModal('edit', ${index})">

                  <div class="d-flex justify-content-between align-items-center mb-2">

                      <div class="fw-bold" style="color: #1e293b; font-size: 15px;">${ciDisplay} <span class="text-muted fw-normal ms-2" style="font-size: 12px;">| Barcode: ${row.barcode}</span></div>

                      <div>${warnBadge}${badge}</div>

                  </div>

                  <div class="d-flex justify-content-between align-items-center mb-2">

                      <div style="font-size: 13px; color: #1e293b;">ផលិតផល៖ <strong>${displayModel}</strong> <span class="ms-1 text-muted" style="font-size: 12px;">(${serial})</span></div>

                      <i class="bi bi-arrow-right" style="color: #94a3b8; font-size: 16px;"></i>

                  </div>

                  <div class="d-flex justify-content-start align-items-center flex-wrap" style="font-size: 13px; color: #1e293b; gap: 8px;">

                      <div><i class="bi bi-person-fill" style="color: #64748b; font-size: 14px; margin-right: 4px;"></i> អ្នកកាន់៖ <strong>${row.user}</strong></div>

                      <div class="ms-3"><i class="bi bi-building" style="color: #64748b; font-size: 14px; margin-right: 4px;"></i> ទីតាំង៖ <strong>${dpt}</strong></div>

                      ${connected}

                      ${acqDateText}

                  </div>

              </div>`;


              let tr = document.createElement('tr');

              tr.innerHTML = `<td>${finalGroup}</td><td>${cardHtml}</td>`;

              tbody.appendChild(tr);

          });


          dataTableInstance = $('#assetTable').DataTable({ 

              paging: false, 

              responsive: true, 

              order: [[0, 'asc']], 

              deferRender: true,

              columnDefs: [ { targets: [0], visible: false }, { targets: [1], className: 'p-0 border-0' } ],

              rowGroup: { dataSrc: 0, startRender: function (rows, group) {

                  if(collapsedGroups[group] === undefined) collapsedGroups[group] = true; 

                  rows.nodes().each(function (r) { r.style.display = collapsedGroups[group] ? 'none' : ''; });

                  let tr = document.createElement('tr'), td = document.createElement('td'); 

                  td.colSpan = 1; td.className = 'group-header'; td.setAttribute('data-name', group);

                  td.innerHTML = `<i class="bi ${collapsedGroups[group]?'bi-folder':'bi-folder2-open'} me-2 text-primary"></i> ${group} <span class="badge badge-count-folder ms-2">${rows.count()}</span>`; tr.appendChild(td); return tr;

              }},

              dom: "t"

          });


          $('#assetTable tbody').off('click', 'tr.dtrg-start').on('click', 'tr.dtrg-start', function () {

              let name = $(this).find('td.group-header').attr('data-name'); if(name !== undefined) { collapsedGroups[name] = !collapsedGroups[name]; dataTableInstance.draw(false); }

          });

      }


      function openModal(action, index = -1) {

        document.getElementById('editIndex').value = index; 

        document.querySelectorAll('input, select').forEach(el => { el.value = ''; el.classList.remove('is-invalid'); });

        document.getElementById('statusMessage').innerText = ''; document.getElementById('formAction').value = action;

        $('.accordion-collapse').collapse('hide');$('#colId').collapse('show');

        

        const ro = ['f_acqDate', 'f_warrantyDate', 'f_vendor', 'f_source'];

        if(action === 'add') {

            document.getElementById('modalTitle').innerText = 'Register Asset'; document.getElementById('f_department').value = sessionStorage.getItem('branch');

            document.getElementById('historyAccordionWrapper').style.display = 'none';

            let bc = document.getElementById('f_barcode'); bc.removeAttribute('readonly'); bc.style.pointerEvents='auto'; bc.style.backgroundColor='#fff';

            ro.forEach(id => { let el=document.getElementById(id); el.removeAttribute('readonly'); el.style.pointerEvents='auto'; el.style.backgroundColor='#fff'; });

            document.getElementById('f_lblNetwork').value = ''; document.getElementById('f_lblStandard').value = ''; document.getElementById('f_lblSeal').value = '';

            document.getElementById('f_prodType').value = 'Terminal Computer';

            toggleDynamicFields();

        } else {

            document.getElementById('modalTitle').innerText = 'Update Asset';

            let bc = document.getElementById('f_barcode'); bc.setAttribute('readonly', 'true'); bc.style.pointerEvents='none'; bc.style.backgroundColor='#e2e8f0';

            ro.forEach(id => { let el=document.getElementById(id); el.setAttribute('readonly', 'true'); el.style.pointerEvents='none'; el.style.backgroundColor='#e2e8f0'; });

            

            const r = fullDataset[index].rawRow; const tgt = r[10];

            document.getElementById('historyAccordionWrapper').style.display = 'block';

            document.getElementById('historyContainer').innerHTML = '<div class="spinner-border text-primary spinner-border-sm mt-2"></div> Loading timeline...';

            

            callApi('getAssetHistory', { barcode: tgt }).then(h => {

                let c = document.getElementById('historyContainer');

                if(!h || h.length===0) return c.innerHTML = "<p class='mt-2'>No history found for this asset.</p>";

                let html = "<ul class='list-unstyled m-0 text-start'>";

                h.forEach(l => {

                    let photoLink = (l.photo && l.photo !== 'No Photo' && l.photo !== 'Photo Error') ? `<div class="mt-2"><a href="${l.photo}" target="_blank" class="small text-decoration-none fw-bold"><i class="bi bi-image me-1"></i>View Photo Proof</a></div>` : '';

                    let changesHTML = l.changes;

                    if (!changesHTML) {

                        let leg = [];

                        if (l.oldUser && l.newUser && l.oldUser !== l.newUser && l.oldUser !== 'N/A') leg.push(`&bull; <b>User:</b> <del style="color:#ef4444;">${l.oldUser}</del> &rarr; <span style="color:#10b981; font-weight:600;">${l.newUser}</span>`);

                        if (l.oldLoc && l.newLoc && l.oldLoc !== l.newLoc && l.oldLoc !== 'N/A' && l.oldLoc !== 'None') leg.push(`&bull; <b>Location:</b> <del style="color:#ef4444;">${l.oldLoc}</del> &rarr; <span style="color:#10b981; font-weight:600;">${l.newLoc}</span>`);

                        if (leg.length > 0) changesHTML = leg.join("<br>");

                    }

                    let changesDiv = changesHTML ? `<div class="timeline-change-box mt-2">${changesHTML}</div>` : `<div class="timeline-change-box mt-2 text-muted"><i>No field changes recorded.</i></div>`;

                    html += `<li class='mb-3 pb-3 border-bottom'><div class="d-flex justify-content-between text-muted" style="font-size: 11.5px;"><span><i class="bi bi-clock me-1"></i>${l.date}</span><span class="fw-bold text-primary">${l.officer}</span></div><div class="fw-bold mt-1 text-dark" style="font-size: 13px;">Reason: ${l.reason}</div>${changesDiv}${photoLink}</li>`;

                });

                c.innerHTML = html + "</ul>";

            });


            document.getElementById('f_department').value=r[0]; document.getElementById('f_locationName').value=r[1]; document.getElementById('f_floor').value=r[2];

            document.getElementById('f_roomNum').value=r[3]; document.getElementById('f_roomName').value=r[4]; document.getElementById('f_tableNum').value=r[5];

            document.getElementById('f_user').value=r[6]; document.getElementById('f_staffId').value=r[7]; document.getElementById('f_position').value=r[8];

            document.getElementById('f_ciName').value=r[9]; document.getElementById('f_barcode').value=r[10]; document.getElementById('f_assetState').value=r[11];

            

            try{ document.getElementById('f_acqDate').value = safeDate(r[12]); }catch(e){}

            try{ document.getElementById('f_warrantyDate').value = safeDate(r[13]); }catch(e){}

            

            let pType = r[14] ? r[14].toString().trim() : '';

            if(Array.from(document.getElementById('f_prodType').options).some(o => o.value === pType)) document.getElementById('f_prodType').value = pType; else document.getElementById('f_prodType').value = 'Other';

            

            document.getElementById('f_model').value=r[15]; document.getElementById('f_processor').value=r[16];

            document.getElementById('f_memory').value=r[17]; document.getElementById('f_serviceTag').value=r[18]; document.getElementById('f_switchId').value=r[19];

            document.getElementById('f_switchPort').value=r[20]; document.getElementById('f_connType').value=r[21]; document.getElementById('f_domain').value=r[22];

            document.getElementById('f_source').value=r[23]; document.getElementById('f_vendor').value=r[24]; document.getElementById('f_regDate').value=r[25]; document.getElementById('f_remark').value=r[26];

            document.getElementById('f_lblNetwork').value=r[27]||''; document.getElementById('f_lblStandard').value=r[28]||''; document.getElementById('f_lblSeal').value=r[29]||'';

            document.getElementById('f_connectedAsset').value=r[30]||'';


            toggleDynamicFields();

        }

        navigator.geolocation.getCurrentPosition(p => { userLat=p.coords.latitude; userLng=p.coords.longitude; }, e => {}); assetModal.show();

      }


      function closeModal() { assetModal.hide(); }


      function saveData() {

        let valid = true; document.querySelectorAll('.req-field').forEach(el => { if(!el.value.trim()){ el.classList.add('is-invalid'); valid=false; } else el.classList.remove('is-invalid'); });

        if(!valid) return document.getElementById('statusMessage').innerHTML = "<span class='text-danger'>Fill all required fields.</span>";

        document.getElementById('saveBtn').disabled = true; document.getElementById('statusMessage').innerHTML = "<span class='text-primary'>Saving record & tracking changes...</span>";


        const p = {

            department: document.getElementById('f_department').value, locationName: document.getElementById('f_locationName').value, floor: document.getElementById('f_floor').value, roomNum: document.getElementById('f_roomNum').value, roomName: document.getElementById('f_roomName').value, tableNum: document.getElementById('f_tableNum').value, user: document.getElementById('f_user').value, staffId: document.getElementById('f_staffId').value, position: document.getElementById('f_position').value, ciName: document.getElementById('f_ciName').value, barcode: document.getElementById('f_barcode').value, assetState: document.getElementById('f_assetState').value, acqDate: document.getElementById('f_acqDate').value, warrantyDate: document.getElementById('f_warrantyDate').value, prodType: document.getElementById('f_prodType').value, model: document.getElementById('f_model').value, processor: document.getElementById('f_processor').value, memory: document.getElementById('f_memory').value, serviceTag: document.getElementById('f_serviceTag').value, switchId: document.getElementById('f_switchId').value, switchPort: document.getElementById('f_switchPort').value, connType: document.getElementById('f_connType').value, domain: document.getElementById('f_domain').value, source: document.getElementById('f_source').value, vendor: document.getElementById('f_vendor').value, regDate: document.getElementById('f_regDate').value, remark: document.getElementById('f_remark').value, lblNetwork: document.getElementById('f_lblNetwork').value, lblStandard: document.getElementById('f_lblStandard').value, lblSeal: document.getElementById('f_lblSeal').value, connectedAsset: document.getElementById('f_connectedAsset').value

        };


        const fileInput = document.getElementById('f_auditPhoto');

        const execSave = (b64) => {

            const act = document.getElementById('formAction').value; const idx = document.getElementById('editIndex').value;

            const pay = { action: act, reason: document.getElementById('f_reason').value, data: p, imageBase64: b64, lat: userLat, lng: userLng, officerId: sessionStorage.getItem('officerId') };

            const rData = [p.department, p.locationName, p.floor, p.roomNum, p.roomName, p.tableNum, p.user, p.staffId, p.position, p.ciName, p.barcode, p.assetState, p.acqDate, p.warrantyDate, p.prodType, p.model, p.processor, p.memory, p.serviceTag, p.switchId, p.switchPort, p.connType, p.domain, p.source, p.vendor, p.regDate, p.remark, p.lblNetwork, p.lblStandard, p.lblSeal, p.connectedAsset];

            

            if(act === 'edit') { fullDataset[idx].department = p.department; fullDataset[idx].productType = p.prodType; fullDataset[idx].ciName = p.ciName; fullDataset[idx].user = p.user; fullDataset[idx].assetState = p.assetState; fullDataset[idx].rawRow = rData; }

            else { fullDataset.push({ department: p.department, productType: p.prodType, barcode: p.barcode, ciName: p.ciName, user: p.user, assetState: p.assetState, rawRow: rData }); }

            

            closeModal(); populateSuggestions(); updatePillCounts(); renderTableOnce(fullDataset); document.getElementById('saveBtn').disabled = false;

            

            callApi('saveAssetSecure', pay).then(res => { if(!res.success) alert("Error: " + res.message); });

        };


        if(fileInput.files.length > 0) {

            const r = new FileReader(); r.onload = e => { const img = new Image(); img.src = e.target.result; img.onload = () => { const cvs = document.createElement("canvas"), ctx = cvs.getContext("2d"), s = 800/img.width; cvs.width=800; cvs.height=img.height*s; ctx.drawImage(img,0,0,cvs.width,cvs.height); execSave(cvs.toDataURL("image/jpeg", 0.7)); }}; r.readAsDataURL(fileInput.files[0]);

        } else execSave(null);

      }


      function submitForgotPin() {

          const id = document.getElementById('fp_officerId').value.trim(), msg = document.getElementById('fpMessage'), btn = document.getElementById('fpSendBtn');

          if(!id) return msg.innerHTML = "<span class='text-danger'>Enter Officer ID.</span>";

          btn.disabled = true; msg.innerHTML = "<span class='text-primary'>Sending...</span>";

          

          callApi('requestPasswordReset', { officerId: id }).then(res => {

              btn.disabled = false;

              if(res.success) { msg.innerHTML = `<span class='text-success'>${res.message}</span>`; setTimeout(() => forgotPinModal.hide(), 2500); }

              else msg.innerHTML = `<span class='text-danger'>${res.message}</span>`;

          }).catch(err => { btn.disabled = false; msg.innerHTML = `<span class='text-danger'>Error: ${err.message}</span>`; });

      }


      function openPinModal() { document.getElementById('p_oldPin').value=''; document.getElementById('p_newPin').value=''; document.getElementById('p_confirmPin').value=''; document.getElementById('pinMessage').innerText=''; pinModal.show(); }

      

      function submitPinChange() {

        const oldP = document.getElementById('p_oldPin').value.trim(), newP = document.getElementById('p_newPin').value.trim(), confP = document.getElementById('p_confirmPin').value.trim(), msg = document.getElementById('pinMessage'), btn = document.getElementById('pinSaveBtn');

        if(!oldP || !newP || !confP) return msg.innerHTML = "<span class='text-danger'>All fields required.</span>";

        if(newP !== confP) return msg.innerHTML = "<span class='text-danger'>PINs do not match.</span>";

        btn.disabled = true; msg.innerHTML = "<span class='text-primary'>Saving...</span>";

        

        callApi('changeUserPin', { officerId: sessionStorage.getItem('officerId'), oldPin: oldP, newPin: newP }).then(res => {

            if(res.success) {

                msg.innerHTML = "<span class='text-success'>PIN updated!</span>";

                if(localStorage.getItem('gdt_remember') === 'true') localStorage.setItem('gdt_pin', newP);

                setTimeout(() => { pinModal.hide(); btn.disabled = false; }, 1500);

            } else { btn.disabled = false; msg.innerHTML = `<span class='text-danger'>${res.message}</span>`; }

        });

      }


      function toggleAllBranches(src) { document.querySelectorAll('.branch-cb').forEach(cb => cb.checked = src.checked); }

      function updateSelectAllStatus() { document.getElementById('selectAllBranches').checked = (document.querySelectorAll('.branch-cb').length === document.querySelectorAll('.branch-cb:checked').length); }

      

      function triggerDownload() {

          const role = sessionStorage.getItem('role').toLowerCase();

          const c = document.getElementById('branchCheckboxes'); 

          c.innerHTML = ''; 

          document.getElementById('selectAllBranches').checked = true;


          let bSet = new Set();

          if (role.includes('admin')) {

              fullDataset.forEach(i => { if(i.department) bSet.add(i.department.toString().trim()); });

          } else {

              bSet.add(sessionStorage.getItem('branch'));

          }

          

          Array.from(bSet).sort().forEach((b, idx) => { 

              let disabled = !role.includes('admin') ? 'onclick="return false;"' : '';

              c.innerHTML += `<div class="form-check mb-2"><input class="form-check-input branch-cb" type="checkbox" value="${b}" id="cb_${idx}" checked onchange="updateSelectAllStatus()" ${disabled}><label class="form-check-label small" for="cb_${idx}">${b}</label></div>`; 

          });

          downloadModal.show();

      }


      function executeDownload(forceB = null) {

          let sel = []; let isAll = false;

          if(forceB) sel = forceB; else { document.querySelectorAll('.branch-cb:checked').forEach(cb => sel.value && sel.push(cb.value)); isAll = document.getElementById('selectAllBranches').checked; downloadModal.hide(); }

          if(sel.length===0 && !isAll) return alert("Select at least one branch.");


          let scope = document.getElementById('exportScope') ? document.getElementById('exportScope').value : 'all';

          let exp = fullDataset;

          let scopeName = "Inventory";


          if (scope === 'current') {

              if (activeCategory === '5+ Years') {

                  exp = exp.filter(r => checkIsOldPC(r));

                  scopeName = "5PlusYears";

              } else if (activeCategory !== 'All') {

                  exp = exp.filter(r => (r.productType||"").trim() === activeCategory);

                  scopeName = activeCategory.replace(/\s+/g, '');

              }

              const term = document.getElementById('globalSearch').value.toLowerCase().trim();

              if (term) {

                  exp = exp.filter(r => {

                      return (r.barcode||"").toLowerCase().includes(term) ||

                             (r.ciName||"").toLowerCase().includes(term) ||

                             (r.user||"").toLowerCase().includes(term) ||

                             (r.rawRow[18]||"").toLowerCase().includes(term) || 

                             (r.rawRow[30]||"").toLowerCase().includes(term); 

                  });

              }

          } else if (scope === 'old') {

              exp = exp.filter(r => checkIsOldPC(r));

              scopeName = "5PlusYears";

          }


          if(!isAll && !forceB) { 

              exp = exp.filter(i => sel.includes((i.department||"").toString().trim())); 

          } else if(forceB && forceB[0]!=="ALL") { 

              exp = exp.filter(i => (i.department||"").toString().trim() === forceB[0].trim()); 

          }


          let branchName = "Selected";

          if (isAll || (forceB && forceB[0] === "ALL")) branchName = "AllBranches";

          else if (sel.length === 1 || (forceB && forceB.length === 1)) branchName = sel[0] || forceB[0];

          branchName = branchName.replace(/[\s/\\:*?"<>|]/g, '_'); 


          let d = new Date(); 

          let fName = `GDT_${scopeName}_${branchName}_${d.getFullYear()}${String(d.getMonth()+1).padStart(2,'0')}${String(d.getDate()).padStart(2,'0')}.xlsx`;

          

          exp.sort((a, b) => {

              let dA = (a.department || "").toString().trim();

              let dB = (b.department || "").toString().trim();

              return dA.localeCompare(dB);

          });


          let finalExportData = [];

          let currentDept = null;

          let deptCount = 0;

          let grandTotal = 0;


          const getEmptyRow = () => ({ "Department": "", "Location": "", "Floor": "", "Room Name": "", "User": "", "Staff ID": "", "Position": "", "CI Name": "", "Barcode": "", "Asset State": "", "Acq Date": "", "Warranty": "", "Product": "", "Model": "", "Processor": "", "Memory": "", "Serial": "", "Vendor": "", "Remark": "", "Label ខ្សែបណ្តាញ": "", "ស្លាកស្តង់ដារ": "", "ខ្សែ Seal": "", "Connected Asset": "" });


          exp.forEach(i => {

              let r = i.rawRow;

              let dept = (r[0] || "").toString().trim() || "Unassigned";


              if (currentDept !== dept) {

                  if (currentDept !== null) {

                      let subRow = getEmptyRow();

                      subRow["Department"] = `▶ SUBTOTAL: ${currentDept}`;

                      subRow["Location"] = `${deptCount} Asset(s)`;

                      finalExportData.push(subRow);

                      finalExportData.push(getEmptyRow()); 

                  }

                  

                  deptCount = 0;

                  

                  let headerRow = getEmptyRow();

                  headerRow["Department"] = `▼ GROUP: ${dept.toUpperCase()} ▼`;

                  finalExportData.push(headerRow);

              }


              currentDept = dept;

              deptCount++;

              grandTotal++;


              finalExportData.push({

                  "Department": dept, "Location": r[1]||"", "Floor": r[2]||"", "Room Name": r[4]||"", "User": r[6]||"", "Staff ID": r[7]||"", "Position": r[8]||"", "CI Name": r[9]||"", "Barcode": r[10]||"", "Asset State": r[11]||"", "Acq Date": safeDate(r[12]), "Warranty": safeDate(r[13]), "Product": r[14]||"", "Model": r[15]||"", "Processor": r[16]||"", "Memory": r[17]||"", "Serial": r[18]||"", "Vendor": r[24]||"", "Remark": r[26]||"", "Label ខ្សែបណ្តាញ": r[27]||"", "ស្លាកស្តង់ដារ": r[28]||"", "ខ្សែ Seal": r[29]||"", "Connected Asset": r[30]||""

              });

          });


          if (currentDept !== null) {

              let subRow = getEmptyRow();

              subRow["Department"] = `▶ SUBTOTAL: ${currentDept}`;

              subRow["Location"] = `${deptCount} Asset(s)`;

              finalExportData.push(subRow);

          }


          if (grandTotal > 0) {

              finalExportData.push(getEmptyRow());

              let gtRow = getEmptyRow();

              gtRow["Department"] = "★ GRAND TOTAL ★";

              gtRow["Location"] = `${grandTotal} Asset(s)`;

              finalExportData.push(gtRow);

          }


          const ws = XLSX.utils.json_to_sheet(finalExportData);

          const wb = XLSX.utils.book_new(); XLSX.utils.book_append_sheet(wb, ws, "Assets"); XLSX.writeFile(wb, fName);

      }

    </script>

  </body>

</html>