<?php
require_once __DIR__ . '/config.php';
requireManagerLogin();
$managerName = $_SESSION['manager_name'] ?? 'Manager';
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<title>HHP Staff &amp; Site Manager</title>
<style>
*{box-sizing:border-box;margin:0;padding:0;}
body{font-family:Arial,sans-serif;background:#f0f4f8;color:#1a202c;font-size:14px;}
header{background:#1F4E79;color:#fff;padding:12px 20px;}
header h1{font-size:1.1rem;font-weight:700;}
header p{font-size:.75rem;opacity:.7;margin-top:1px;}
.tabs{display:flex;background:#163d60;border-bottom:3px solid #2E75B6;overflow-x:auto;}
.tab{padding:10px 16px;cursor:pointer;color:#aac5de;font-size:.82rem;font-weight:600;white-space:nowrap;border-right:1px solid #1c4f78;transition:.15s;}
.tab:hover{background:#1a4e7a;color:#fff;}
.tab.active{background:#2E75B6;color:#fff;border-bottom:3px solid #FFE699;margin-bottom:-3px;}
.badge{display:inline-block;background:#FFE699;color:#7F6000;border-radius:10px;padding:0 6px;font-size:.68rem;margin-left:4px;font-weight:700;}
.panel{display:none;padding:13px 17px;}.panel.active{display:block;}
.spinner{display:inline-block;width:20px;height:20px;border:3px solid #bee3f8;border-top-color:#2E75B6;border-radius:50%;animation:spin .7s linear infinite;margin-right:6px;vertical-align:middle;}
@keyframes spin{to{transform:rotate(360deg);}}
table{width:100%;border-collapse:collapse;background:#fff;border-radius:7px;overflow:hidden;box-shadow:0 1px 4px rgba(0,0,0,.08);font-size:.82rem;}
thead tr{background:#1F4E79;color:#fff;}
th{padding:9px 10px;text-align:left;font-weight:600;white-space:nowrap;}
td{padding:6px 10px;border-bottom:1px solid #e8edf2;vertical-align:middle;}
tr:last-child td{border-bottom:none;}
tr:nth-child(even) td{background:#f7fafc;}
tr:hover td{background:#ebf4ff;}
.toolbar{display:flex;gap:7px;margin-bottom:10px;flex-wrap:wrap;align-items:center;}
.toolbar input,.toolbar select{padding:7px 10px;border:1px solid #cbd5e0;border-radius:5px;font-size:.82rem;background:#fff;}
.toolbar input{flex:1;min-width:170px;}
.form-card{background:#fff;border:1px solid #bee3f8;border-radius:8px;padding:15px;margin-bottom:13px;box-shadow:0 1px 4px rgba(0,0,0,.06);}
.form-card h3{color:#1F4E79;font-size:.92rem;margin-bottom:12px;}
.sec-label{font-size:.7rem;font-weight:700;color:#2E75B6;text-transform:uppercase;letter-spacing:.5px;border-bottom:2px solid #bee3f8;padding-bottom:3px;margin:12px 0 8px;}
.form-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(200px,1fr));gap:9px;}
.fg{display:flex;flex-direction:column;gap:3px;}
.fg.wide{grid-column:1/-1;}
.fg label{font-size:.7rem;font-weight:700;color:#4a5568;text-transform:uppercase;letter-spacing:.3px;}
.fg input,.fg select,.fg textarea{padding:7px 9px;border:1px solid #cbd5e0;border-radius:5px;font-size:.82rem;background:#fff;font-family:Arial,sans-serif;}
.fg textarea{resize:vertical;min-height:56px;}
.fg input[readonly]{background:#f7fafc;color:#4a5568;}
.prio-wrap{display:flex;gap:0;border:1.5px solid #cbd5e0;border-radius:6px;overflow:hidden;}
.prio-btn{flex:1;padding:6px 3px;cursor:pointer;font-size:.74rem;font-weight:700;background:#fff;border:none;transition:.15s;text-align:center;}
.prio-btn.low.active{background:#16a34a;color:#fff;}
.prio-btn.med.active{background:#d97706;color:#fff;}
.prio-btn.high.active{background:#dc2626;color:#fff;}
.type-toggle{display:flex;border:2px solid #2E75B6;border-radius:6px;overflow:hidden;width:fit-content;margin-bottom:12px;}
.type-btn{padding:7px 20px;cursor:pointer;font-size:.83rem;font-weight:700;background:#fff;color:#2E75B6;border:none;transition:.15s;}
.type-btn.active{background:#2E75B6;color:#fff;}
.btn{padding:7px 14px;border:none;border-radius:5px;cursor:pointer;font-size:.8rem;font-weight:700;transition:.15s;}
.btn-primary{background:#2E75B6;color:#fff;}.btn-primary:hover{background:#1F4E79;}
.btn-success{background:#375623;color:#fff;}.btn-success:hover{background:#2a4119;}
.btn-danger{background:#c0392b;color:#fff;font-size:.74rem;padding:3px 7px;}
.btn-edit{background:#7c3aed;color:#fff;font-size:.74rem;padding:3px 8px;}
.btn-note{background:#0891b2;color:#fff;font-size:.74rem;padding:3px 8px;}
.btn-add{background:#0891b2;color:#fff;font-size:.8rem;padding:6px 12px;border-radius:5px;cursor:pointer;font-weight:700;border:none;}
.btn-row{display:flex;gap:8px;margin-top:12px;flex-wrap:wrap;}
.pill{display:inline-block;padding:2px 8px;border-radius:10px;font-size:.72rem;font-weight:700;}
.p-emp{background:#dbeafe;color:#1e40af;}.p-site{background:#d1fae5;color:#065f46;}
.p-pending{background:#fef3c7;color:#92400e;}.p-inprog{background:#dbeafe;color:#1e40af;}
.p-docu{background:#ede9fe;color:#5b21b6;}.p-complete{background:#d1fae5;color:#065f46;}
.p-filled{background:#fce7f3;color:#9d174d;}
.p-hi{background:#fee2e2;color:#991b1b;}.p-med{background:#fef3c7;color:#92400e;}.p-low{background:#d1fae5;color:#065f46;}
.dept-pill{padding:2px 7px;border-radius:9px;font-size:.71rem;font-weight:700;}
code{background:#edf2f7;padding:1px 5px;border-radius:4px;font-size:.76rem;}
a.ml{color:#2E75B6;text-decoration:none;font-size:.78rem;}a.ml:hover{text-decoration:underline;}
.count-info{font-size:.77rem;color:#718096;margin-bottom:7px;}
.stats{display:flex;gap:8px;margin-bottom:12px;flex-wrap:wrap;}
.stat{background:#fff;border-radius:7px;padding:9px 13px;box-shadow:0 1px 4px rgba(0,0,0,.07);flex:1;min-width:90px;text-align:center;}
.stat .num{font-size:1.35rem;font-weight:700;color:#2E75B6;}
.stat .lbl{font-size:.68rem;color:#718096;margin-top:1px;}

/* Compact expanded row */
.exp-row{background:#f0f7ff;border-left:3px solid #2E75B6;}
.exp-row td{padding:10px 13px;}
.exp-section{margin-bottom:10px;}
.exp-section-title{font-size:.68rem;font-weight:700;color:#2E75B6;text-transform:uppercase;letter-spacing:.5px;margin-bottom:5px;padding-bottom:3px;border-bottom:1px solid #bee3f8;}

/* Transfer chain */
.transfer-chain{display:flex;align-items:center;gap:6px;flex-wrap:wrap;font-size:.8rem;}
.chain-node{background:#fff;border:1px solid #bee3f8;border-radius:5px;padding:3px 8px;font-size:.76rem;}
.chain-arrow{color:#2E75B6;font-size:.9rem;font-weight:700;}
.chain-current{background:#dbeafe;border-color:#2E75B6;font-weight:700;}

/* History log */
.history-log{max-height:180px;overflow-y:auto;border:1px solid #e2e8f0;border-radius:5px;background:#fff;}
.history-entry{padding:6px 10px;border-bottom:1px solid #f0f4f8;font-size:.78rem;}
.history-entry:last-child{border-bottom:none;}
.history-meta{display:flex;gap:8px;align-items:center;margin-bottom:2px;}
.history-ts{color:#a0aec0;font-size:.68rem;}
.history-actor{font-weight:700;color:#1F4E79;font-size:.72rem;}
.history-type{font-size:.65rem;background:#e2e8f0;color:#4a5568;padding:1px 5px;border-radius:3px;font-weight:700;text-transform:uppercase;}
.history-text{color:#1a202c;line-height:1.4;}

/* Attachments */
.attachment-list{display:flex;flex-wrap:wrap;gap:5px;margin-top:4px;}
.attachment-item{display:flex;align-items:center;gap:4px;background:#f7fafc;border:1px solid #e2e8f0;border-radius:4px;padding:3px 7px;font-size:.74rem;}
.attachment-item a{color:#2E75B6;text-decoration:none;}
.attachment-item a:hover{text-decoration:underline;}
.att-thumb{width:32px;height:32px;object-fit:cover;border-radius:3px;cursor:pointer;}
.att-img-wrap{display:flex;flex-wrap:wrap;gap:5px;margin-top:4px;}

/* Add note inline */
.note-add-area{display:flex;gap:6px;align-items:flex-end;margin-top:6px;}
.note-add-area textarea{flex:1;padding:5px 8px;border:1px solid #cbd5e0;border-radius:5px;font-size:.78rem;min-height:38px;resize:vertical;font-family:Arial,sans-serif;}

/* Due date badge */
.due-badge{display:inline-flex;align-items:center;gap:4px;font-size:.76rem;white-space:nowrap;}
.due-badge.overdue{color:#dc2626;font-weight:700;}
.due-tz{font-size:.65rem;color:#a0aec0;font-weight:400;}

/* Attachment upload area */
.attach-zone{border:2px dashed #bee3f8;border-radius:6px;padding:10px;text-align:center;cursor:pointer;font-size:.78rem;color:#718096;transition:.15s;}
.attach-zone:hover{border-color:#2E75B6;color:#2E75B6;background:#f0f7ff;}
.attach-preview{display:flex;flex-wrap:wrap;gap:6px;margin-top:8px;}
.attach-preview-item{position:relative;display:inline-flex;align-items:center;}
.attach-preview-item img{width:48px;height:48px;object-fit:cover;border-radius:4px;border:1px solid #e2e8f0;}
.attach-preview-item .att-file{background:#edf2f7;padding:4px 8px;border-radius:4px;font-size:.72rem;display:flex;align-items:center;gap:4px;}
.attach-rm{position:absolute;top:-5px;right:-5px;background:#c0392b;color:#fff;border:none;border-radius:50%;width:16px;height:16px;font-size:.65rem;cursor:pointer;display:flex;align-items:center;justify-content:center;line-height:1;}
.link-row{display:flex;gap:6px;margin-top:6px;}
.link-row input{flex:1;padding:5px 8px;border:1px solid #cbd5e0;border-radius:5px;font-size:.78rem;}

.no-data{text-align:center;padding:32px;color:#a0aec0;}
.toast{position:fixed;bottom:20px;right:20px;background:#375623;color:#fff;padding:10px 18px;border-radius:7px;font-size:.85rem;font-weight:600;box-shadow:0 3px 10px rgba(0,0,0,.2);z-index:999;opacity:0;transition:opacity .3s;}
.toast.show{opacity:1;}
.sync-bar{background:#fff8e1;border-bottom:1px solid #fde68a;padding:6px 16px;font-size:.78rem;color:#92400e;display:flex;align-items:center;gap:8px;}
.new-tag{background:#0891b2;color:#fff;border-radius:4px;font-size:.65rem;padding:1px 5px;margin-left:4px;font-weight:700;}
/* Modals */
.modal-overlay{display:none;position:fixed;inset:0;background:rgba(0,0,0,.45);z-index:500;align-items:center;justify-content:center;}
.modal-overlay.open{display:flex;}
.modal{background:#fff;border-radius:10px;padding:20px;width:min(520px,96vw);box-shadow:0 8px 32px rgba(0,0,0,.2);max-height:90vh;overflow-y:auto;}
.modal h3{color:#1F4E79;font-size:.95rem;margin-bottom:14px;border-bottom:2px solid #bee3f8;padding-bottom:8px;}
.modal-footer{display:flex;gap:8px;justify-content:flex-end;margin-top:14px;padding-top:12px;border-top:1px solid #e2e8f0;}

/* Image lightbox */
.lightbox{display:none;position:fixed;inset:0;background:rgba(0,0,0,.85);z-index:1000;align-items:center;justify-content:center;cursor:pointer;}
.lightbox.open{display:flex;}
.lightbox img{max-width:90vw;max-height:88vh;border-radius:6px;object-fit:contain;}
/* Reference-inspired professional workspace */
:root{--ui-ink:#10233f;--ui-navy:#123f73;--ui-blue:#087cf0;--ui-sky:#eaf4ff;--ui-line:#dce8f4;--ui-muted:#728197}
body{font-family:Inter,ui-sans-serif,-apple-system,BlinkMacSystemFont,"Segoe UI",sans-serif;background:linear-gradient(135deg,#edf5fb,#dce9f5);color:var(--ui-ink);min-height:100vh;padding:22px}
header,.tabs,.sync-bar,.panel{max-width:1440px;margin-left:auto;margin-right:auto}
header{background:rgba(255,255,255,.9);color:var(--ui-ink);padding:18px 24px 12px;border-radius:28px 28px 0 0;border:1px solid #fff;border-bottom:0;backdrop-filter:blur(18px)}
header h1{font-size:1.05rem;letter-spacing:-.02em}header p{color:var(--ui-muted);opacity:1!important}.sync-bar{background:rgba(255,255,255,.9);border:0;padding:0 24px 12px;color:var(--ui-muted)}
.tabs{background:rgba(255,255,255,.9);border:0;padding:5px 18px 14px;gap:4px}.tab{border:0;border-radius:999px;padding:9px 14px;color:#526277;font-size:.76rem}.tab:hover{background:var(--ui-sky);color:var(--ui-navy)}.tab.active{background:var(--ui-navy);color:#fff;border:0;margin:0;box-shadow:0 8px 20px rgba(18,63,115,.2)}
.panel{background:rgba(247,251,255,.96);padding:20px;border-radius:0 0 28px 28px;min-height:590px;box-shadow:0 28px 70px rgba(30,63,94,.18)}.form-card,table,.stat{border:1px solid var(--ui-line);border-radius:18px;box-shadow:0 8px 24px rgba(32,74,111,.07)}table{border-radius:16px}thead tr{background:var(--ui-navy)}th{padding:12px}td{padding:9px 12px}.btn,.btn-add{border-radius:10px;padding:8px 13px}.btn-primary,.btn-add{background:var(--ui-blue)}.toolbar input,.toolbar select,.fg input,.fg select,.fg textarea{border-color:var(--ui-line);border-radius:10px;padding:9px 11px}
.dash-hero{display:flex;justify-content:space-between;align-items:flex-end;margin-bottom:18px}.dash-hero h2{font-size:2rem;font-weight:500;letter-spacing:-.04em}.dash-hero p{color:var(--ui-muted);margin-top:5px}.role-chip{background:var(--ui-sky);color:var(--ui-navy);border:1px solid #cfe4fa;border-radius:999px;padding:8px 13px;font-weight:700;font-size:.75rem}
.dashboard-grid{display:grid;grid-template-columns:1.1fr 1fr 1fr;gap:14px}.dash-card{background:#fff;border:1px solid var(--ui-line);border-radius:22px;padding:18px;min-height:160px;box-shadow:0 8px 25px rgba(32,74,111,.06)}.dash-card.wide{grid-column:span 2}.dash-card h3{font-size:.86rem;color:var(--ui-muted);font-weight:600;margin-bottom:14px}.metric-row{display:grid;grid-template-columns:repeat(3,1fr);gap:10px}.mini-metric{padding:14px;border-radius:15px;background:#f4f9fe}.mini-metric b{display:block;font-size:1.55rem}.mini-metric span{font-size:.7rem;color:var(--ui-muted)}
.progress-ring{width:112px;height:112px;border-radius:50%;display:grid;place-items:center;background:conic-gradient(var(--ui-blue) var(--progress),#e8f0f7 0);position:relative;margin:auto}.progress-ring:after{content:"";position:absolute;width:78px;height:78px;background:#fff;border-radius:50%}.progress-ring strong{z-index:1;font-size:1.35rem}.status-list{display:grid;gap:9px}.status-line{display:grid;grid-template-columns:92px 1fr 32px;align-items:center;gap:8px;font-size:.72rem}.status-track{height:8px;background:#edf3f8;border-radius:8px;overflow:hidden}.status-fill{height:100%;background:linear-gradient(90deg,var(--ui-navy),var(--ui-blue));border-radius:8px}.recent-task{display:grid;grid-template-columns:1fr auto;gap:4px;padding:9px 0;border-bottom:1px solid #edf2f7}.recent-task b,.recent-task span{display:block}.recent-task b{font-size:.78rem}.recent-task span{font-size:.68rem;color:var(--ui-muted)}
header{background:linear-gradient(135deg,#061b33 0%,#0d3b68 58%,#1268a7 100%);color:#fff;border-color:rgba(255,255,255,.12);box-shadow:0 18px 36px rgba(5,28,53,.24)}header p{color:#c9ddf0!important}.sync-bar{background:#0b3158;color:#bcd4ea}.tabs{background:linear-gradient(90deg,#071f3a,#0e4275)}.tab{color:#b8cee2}.tab:hover{background:rgba(255,255,255,.09);color:#fff}.tab.active{background:linear-gradient(135deg,#1678c7,#26a0f5);box-shadow:0 8px 20px rgba(0,121,214,.32)}.panel{background:linear-gradient(145deg,#f7fbff,#eaf3fb)}.dash-hero{background:linear-gradient(135deg,#082845,#0f4b80);color:#fff;border-radius:20px;padding:22px;box-shadow:0 12px 28px rgba(7,39,70,.2)}.dash-hero h2{color:#fff;text-shadow:0 2px 8px rgba(0,0,0,.18)}.dash-hero p{color:#c6dbed}.role-chip{background:rgba(255,255,255,.12);color:#d9edff;border-color:rgba(255,255,255,.2)}.dash-card h3,.form-card h3{color:#0b3158;font-size:.98rem;font-weight:800;letter-spacing:-.01em}.sec-label{color:#0e5e9e;border-color:#9dcaec}.mini-metric{background:linear-gradient(145deg,#edf7ff,#dceefd);border:1px solid #cee5f7}.mini-metric b{color:#0b3d6b}.btn-primary,.btn-add{background:linear-gradient(135deg,#0b477d,#138ddd);box-shadow:0 5px 14px rgba(14,89,151,.2)}
@media(max-width:900px){body{padding:0}.dashboard-grid{grid-template-columns:1fr}.dash-card.wide{grid-column:auto}.panel,header{border-radius:0}.dash-hero h2{font-size:1.55rem}}
</style>
</head>
<body>
<header>
  <h1>&#x1F6E1;&#xFE0F; Hammerhead Protection — Staff &amp; Site Manager</h1>
  <p style="display:flex;align-items:center;justify-content:space-between;flex-wrap:wrap;gap:6px;">
    <span>Collaborative · All changes sync instantly to Database</span>
    <span style="display:flex;align-items:center;gap:12px;">
      <span style="font-size:.78rem;opacity:.85;">👤 <?= htmlspecialchars($managerName) ?></span>
      <a href="/logout.php" style="font-size:.75rem;color:#fdba74;text-decoration:none;background:rgba(255,255,255,.1);padding:3px 10px;border-radius:12px;border:1px solid rgba(255,255,255,.15);">Sign Out</a>
    </span>
  </p>
</header>
<div class="sync-bar" id="sync-bar">
  <span class="spinner" id="sync-spin" style="display:none"></span>
  <span id="sync-msg">&#x1F504; Loading…</span>
</div>
<div class="tabs">
  <div class="tab active" onclick="showTab('dashboard')">&#x25A6; Dashboard</div>
  <div class="tab" onclick="showTab('employees')">&#x1F465; Employees <span class="badge" id="b-emp"></span></div>
  <div class="tab"        onclick="showTab('sites')">&#x1F4CD; Sites <span class="badge" id="b-site"></span></div>
  <div class="tab"        onclick="showTab('managers')">&#x1F9D1;&#x200D;&#x1F4BC; Managers <span class="badge" id="b-mgr"></span></div>
  <div class="tab"        onclick="showTab('newtask')">&#x2795; New Task</div>
  <div class="tab"        onclick="showTab('tasks')">&#x1F4CB; All Tasks <span class="badge" id="b-task"></span></div>
  <div class="tab"        onclick="showTab('followup')">&#x1F4DD; Follow Up <span class="badge" id="b-followup"></span></div>
</div>

<div class="panel active" id="panel-dashboard">
  <div class="dash-hero"><div><h2>Welcome in, <?= htmlspecialchars($managerName) ?></h2><p>Your people, sites, and work in motion.</p></div><span class="role-chip">Manager workspace</span></div>
  <div class="dashboard-grid">
    <section class="dash-card wide"><h3>Organization at a glance</h3><div class="metric-row"><div class="mini-metric"><b id="dm-employees">0</b><span>Employees</span></div><div class="mini-metric"><b id="dm-managers">0</b><span>Managers</span></div><div class="mini-metric"><b id="dm-sites">0</b><span>Active sites</span></div></div></section>
    <section class="dash-card"><h3>Task completion</h3><div class="progress-ring" id="dm-ring" style="--progress:0%"><strong id="dm-progress">0%</strong></div></section>
    <section class="dash-card"><h3>Workload</h3><div class="status-list" id="dm-status"></div></section>
    <section class="dash-card wide"><h3>Recent activity</h3><div id="dm-recent"><div class="no-data">Tasks will appear here when loaded.</div></div></section>
  </div>
</div>

<!-- EMPLOYEES -->
<div class="panel" id="panel-employees">
  <div class="toolbar">
    <input id="eq" placeholder="&#x1F50D; Search name, phone, or extension…" oninput="renderEmp()">
    <button class="btn-add" onclick="openModal('modal-emp')">&#x2795; Add Employee</button>
  </div>
  <div class="count-info" id="ecnt"></div>
  <table><thead><tr><th>#</th><th>Name</th><th>Primary Phone</th><th>Secondary Phone</th><th>Ext</th><th></th></tr></thead>
  <tbody id="eb"></tbody></table>
</div>

<!-- SITES -->
<div class="panel" id="panel-sites">
  <div class="toolbar">
    <input id="sq" placeholder="&#x1F50D; Search sites…" oninput="renderSites()">
    <button class="btn-add" onclick="openModal('modal-site')">&#x2795; Add Site</button>
  </div>
  <div class="count-info" id="scnt"></div>
  <table><thead><tr><th>#</th><th>Site Name</th><th></th></tr></thead><tbody id="sb"></tbody></table>
</div>

<!-- MANAGERS -->
<div class="panel" id="panel-managers">
  <div class="toolbar">
    <input id="mq" placeholder="&#x1F50D; Search managers…" oninput="renderMgr()">
    <select id="mdept" onchange="renderMgr()"><option value="all">All Departments</option></select>
    <button class="btn-add" onclick="openModal('modal-mgr')">&#x2795; Add Manager</button>
  </div>
  <div class="count-info" id="mcnt"></div>
  <table><thead><tr><th>#</th><th>Manager Name</th><th>Department</th><th>Email</th><th>Tasks By</th><th>Tasks To</th><th></th></tr></thead>
  <tbody id="mb"></tbody></table>
</div>

<!-- NEW TASK -->
<div class="panel" id="panel-newtask">
<div class="form-card">
<h3>&#x2795; Create New Task</h3>
<div class="sec-label">Task Type</div>
<div class="type-toggle">
  <button class="type-btn active" id="tt-e" onclick="setType('employee')">&#x1F464; Employee Task</button>
  <button class="type-btn"        id="tt-s" onclick="setType('site')">&#x1F4CD; Site Task</button>
</div>
<div id="sec-emp">
  <div class="sec-label">Employee Information</div>
  <div class="form-grid">
    <div class="fg"><label>Employee Name</label><select id="f-en" onchange="fillEmpId()"><option value="">— Select Employee —</option></select></div>
    <div class="fg"><label>Employee ID (Extension)</label><input id="f-ei" readonly placeholder="Auto-fills"></div>
  </div>
</div>
<div id="sec-site" style="display:none">
  <div class="sec-label">Site Information</div>
  <div class="form-grid">
    <div class="fg wide"><label>Site Name</label><select id="f-sn"><option value="">— Select Site —</option></select></div>
  </div>
</div>
<div class="sec-label">Task Details</div>
<div class="form-grid">
  <div class="fg wide"><label>Process Type *</label><select id="f-con" onchange="document.getElementById('f-other-con-wrap').style.display=this.value==='Others'?'block':'none';if(this.value!=='Others')document.getElementById('f-other-con').value='';"><option value="">— Select Process Type —</option><option>Attendance</option><option>Cell Phone / Conduct Violations</option><option>Client Complaint</option><option>Client Satisfaction Feedback</option><option>Dishonesty/falsification</option><option>Employee Feedback</option><option>Employee Satisfaction Feedback</option><option>Employee Training</option><option>Excessive or Missing breaks</option><option>Failure to conduct required patrols</option><option>Failure to document incidents</option><option>Failure to follow client safety procedures</option><option>Failure to follow supervisor instructions</option><option>Failure to perform job duties</option><option>Falsifying patrol activity</option><option>Fighting</option><option>Harassment/discrimination</option><option>Leaving assigned post without authorization</option><option>Others</option><option>Possession of weapons not authorized</option><option>Sleeping on duty</option><option>Supply Needed</option><option>Threatening behavior</option><option>Uniform / Appearance Violations</option><option>Unprofessional communication with client/employees</option><option>Unsafe driving</option><option>Use of drugs/alcohol on duty</option></select></div>
  <div id="f-other-con-wrap" class="fg wide" style="display:none"><label>Other Process Type</label><input id="f-other-con" type="text" placeholder="Describe the process type…"></div>
  <div class="fg wide"><label>Findings / Notes</label><textarea id="f-find" placeholder="Enter findings or observations…"></textarea></div>
  <div class="fg"><label>Date *</label><input id="f-date" type="date" onchange="onDateChange()"></div>
  <div class="fg"><label>Sheet ID</label><input id="f-shid" readonly></div>
  <div class="fg"><label>Task ID</label><input id="f-tid" readonly></div>
</div>
<div class="sec-label">Assigning Manager</div>
<div class="form-grid">
  <div class="fg"><label>Manager (Assigned By) *</label><select id="f-mby" onchange="fillEmail('f-mby','f-mbye')"><option value="">— Select Manager —</option></select></div>
  <div class="fg"><label>Email ID</label><input id="f-mbye" readonly placeholder="Auto-fills"></div>
</div>
<div class="sec-label">Assigned To</div>
<div class="form-grid">
  <div class="fg"><label>Assign To Manager *</label><select id="f-mto" onchange="fillEmail('f-mto','f-mtoe')"><option value="">— Select Manager —</option></select></div>
  <div class="fg"><label>Email ID</label><input id="f-mtoe" readonly placeholder="Auto-fills"></div>
  <div class="fg">
    <label>Priority</label>
    <div class="prio-wrap">
      <button class="prio-btn low"  onclick="setPrio('low')"  id="pb-low">&#x1F7E2; Low (3d)</button>
      <button class="prio-btn med"  onclick="setPrio('med')"  id="pb-med">&#x1F7E1; Med (2d)</button>
      <button class="prio-btn high" onclick="setPrio('high')" id="pb-high">&#x1F534; High (1d)</button>
    </div>
  </div>
  <div class="fg">
    <label>Due Date</label>
    <input id="f-due" type="date" style="width:100%">
  </div>
</div>

<!-- Transfer toggle link -->
<div style="margin:6px 0 2px">
  <button type="button" id="btn-show-transfer" class="btn" style="background:none;color:#ffffff;padding:0;font-size:.82rem;font-weight:600;text-decoration:underline;cursor:pointer;border:none;box-shadow:none" onclick="toggleTransferSection(true)">＋ Add Transfer / Site Details (optional)</button>
  <button type="button" id="btn-hide-transfer" class="btn" style="display:none;background:none;color:#ffffff;padding:0;font-size:.82rem;font-weight:600;text-decoration:underline;cursor:pointer;border:none;box-shadow:none" onclick="toggleTransferSection(false)">－ Hide Transfer / Site Details</button>
</div>

<div id="transfer-section" style="display:none">
<div class="sec-label">Transfer (Optional)</div>
<div class="form-grid">
  <div class="fg"><label>Transfer To</label><select id="f-tto" onchange="fillEmail('f-tto','f-ttoe')"><option value="">— None —</option></select></div>
  <div class="fg"><label>Email ID</label><input id="f-ttoe" readonly placeholder="Auto-fills"></div>
  <div class="fg"><label>Transfer Status</label>
    <select id="f-tstat"><option value="">— None —</option>
      <option>Pending</option><option>In Progress</option><option>Completed</option><option>Escalated</option>
    </select>
  </div>
  <div class="fg"><label>Follow-up Required</label>
    <select id="f-followup-required">
      <option value="No">No</option>
      <option value="Yes">Yes</option>
    </select>
  </div>
  <div class="fg"><label>Follow-Up Type</label>
    <select id="f-fup"><option value="">— Select —</option>
      <option>Daily</option>
      <option>Weekly</option>
      <option>Bi Weekly</option>
      <option>Monthly</option>
      <option>3 Months</option>
      <option>6 Months</option>
      <option>Yearly</option>
      <option>Closed</option>
    </select>
  </div>
  <div class="fg"><label>Transfer Follow-Up Type</label>
    <select id="f-tfup"><option value="">— None —</option>
      <option>Call</option><option>Email</option><option>In-Person Visit</option>
      <option>Report</option><option>Meeting</option><option>Other</option>
    </select>
  </div>
  <div class="fg wide"><label>Site (related to this assignment)</label><select id="f-asite"><option value="">— Select Site (optional) —</option></select></div>
  <div class="fg wide"><label>Description of Finding (from Assigned-To Manager)</label><textarea id="f-adesc" placeholder="Notes or response…"></textarea></div>
</div>
</div>

<!-- ATTACHMENTS SECTION -->
<div class="sec-label">Attachments &amp; Links</div>
<div style="margin-bottom:6px;">
  <label class="attach-zone" id="attach-zone-new">
    📎 Click to attach photos or files
    <input id="att-file-new" type="file" multiple accept="image/*,.pdf,.doc,.docx,.txt" style="display:none" onchange="handleAttachNew(this)">
  </label>
  <div class="attach-preview" id="att-preview-new"></div>
</div>
<div style="font-size:.72rem;color:#4a5568;font-weight:700;text-transform:uppercase;letter-spacing:.3px;margin-bottom:4px;">Add Link</div>
<div class="link-row">
  <input id="f-link-url" type="text" placeholder="https://…" style="flex:1" oninput="document.getElementById('f-link-error').style.display='none';this.style.border='';">
  <input id="f-link-label" type="text" placeholder="Label (optional)" style="width:140px">
  <button class="btn btn-primary" onclick="addLinkNew()" style="white-space:nowrap;padding:5px 10px;">+ Add</button>
</div>
<div id="f-link-error" style="font-size:.75rem;color:#c0392b;margin-top:3px;display:none;">Please enter a URL.</div>
<div id="new-links-list" style="margin-top:5px;"></div>

<div class="btn-row">
  <button class="btn btn-success" onclick="createTask()">&#x2705; Create Task</button>
  <button class="btn btn-primary" onclick="clearForm()">&#x1F504; Clear</button>
</div>
</div>
</div>

<!-- ALL TASKS -->
<div class="panel" id="panel-tasks">
  <div class="stats" id="ts"></div>
  <div class="toolbar">
    <input id="tq" placeholder="&#x1F50D; Search tasks…" oninput="renderTasks()">
    <select id="tf-type" onchange="renderTasks()">
      <option value="all">All Types</option><option value="employee">Employee</option><option value="site">Site</option>
    </select>
    <select id="tf-mgr" onchange="renderTasks()"><option value="all">All Managers</option></select>
    <select id="tf-stat" onchange="renderTasks()">
      <option value="all">All Statuses</option>
      <option>Pending</option><option>In Progress</option><option>Docu Signed</option><option>Completed</option><option>Filled</option>
    </select>
    <select id="tf-prio" onchange="renderTasks()">
      <option value="all">All Priorities</option>
      <option value="high">High</option><option value="med">Medium</option><option value="low">Low</option>
    </select>
    <select id="tf-assigned" onchange="renderTasks()"><option value="all">Currently Assigned To</option></select>
    <button class="btn btn-primary" onclick="loadTasks()">&#x1F504; Refresh</button>
    <button class="btn btn-primary" onclick="exportTasks()">&#x2B07; CSV</button>
  </div>
  <div class="count-info" id="tcnt"></div>
  <table>
    <thead><tr>
      <th></th><th>Task ID</th><th>Type</th><th>Subject</th><th>Concern</th>
      <th>By → To</th><th>Currently Assigned To</th><th>Priority</th><th>Due Date</th><th>Status</th><th>Follow-up Required</th><th>Actions</th>
    </tr></thead>
    <tbody id="tb"></tbody>
  </table>
</div>

<!-- FOLLOW UP -->
<div class="panel" id="panel-followup">
  <div class="stats" id="fu-ts"></div>
  <div class="toolbar">
    <input id="fu-q" placeholder="&#x1F50D; Search follow-up tasks…" oninput="renderFollowUp()">
    <button class="btn btn-primary" onclick="loadTasks()">&#x1F504; Refresh</button>
  </div>
  <div class="count-info" id="fucnt"></div>
  <table>
    <thead><tr>
      <th></th><th>Task ID</th><th>Type</th><th>Subject</th><th>Concern</th>
      <th>By → To</th><th>Currently Assigned To</th><th>Start Date</th><th>End Date</th><th>Status</th><th>Follow-up Required</th><th>Actions</th>
    </tr></thead>
    <tbody id="futb"></tbody>
  </table>
</div>

<!-- ADD EMPLOYEE MODAL -->
<div class="modal-overlay" id="modal-emp" onclick="if(event.target===this)closeModal('modal-emp')">
  <div class="modal">
    <h3>&#x2795; Add Employee</h3>
    <div class="form-grid">
      <div class="fg wide"><label>Full Name *</label><input id="ae-name" placeholder="First Last"></div>
      <div class="fg"><label>Primary Phone</label><input id="ae-phone" placeholder="209-555-0000"></div>
      <div class="fg"><label>Secondary Phone</label><input id="ae-phone2" placeholder="Optional"></div>
      <div class="fg"><label>Extension *</label><input id="ae-ext" placeholder="e.g. 1850"></div>
    </div>
    <div class="modal-footer">
      <button class="btn" style="background:#e2e8f0;color:#4a5568" onclick="closeModal('modal-emp')">Cancel</button>
      <button class="btn btn-success" onclick="saveEmployee()">&#x2705; Add Employee</button>
    </div>
  </div>
</div>

<!-- ADD SITE MODAL -->
<div class="modal-overlay" id="modal-site" onclick="if(event.target===this)closeModal('modal-site')">
  <div class="modal">
    <h3>&#x2795; Add Site</h3>
    <div class="form-grid">
      <div class="fg wide"><label>Site Name *</label><input id="as-name" placeholder="Enter site name"></div>
    </div>
    <div class="modal-footer">
      <button class="btn" style="background:#e2e8f0;color:#4a5568" onclick="closeModal('modal-site')">Cancel</button>
      <button class="btn btn-success" onclick="saveSite()">&#x2705; Add Site</button>
    </div>
  </div>
</div>

<!-- ADD MANAGER MODAL -->
<div class="modal-overlay" id="modal-mgr" onclick="if(event.target===this)closeModal('modal-mgr')">
  <div class="modal">
    <h3>&#x2795; Add Manager</h3>
    <div class="form-grid">
      <div class="fg wide"><label>Full Name *</label><input id="am-name" placeholder="First Last"></div>
      <div class="fg"><label>Department</label>
        <select id="am-dept">
          <option value="">— Select —</option>
          <option>Operation</option><option>Field Team</option><option>SOC</option>
          <option>Purchasing</option><option>Training</option><option>Human Resources</option>
          <option>Recruiting</option><option>Patrol</option><option>Finance</option>
          <option>CEO</option><option>Account Manager</option><option>Other</option>
        </select>
      </div>
      <div class="fg"><label>Email *</label><input id="am-email" placeholder="name@hammerheadprotection.com"></div>
    </div>
    <div class="modal-footer">
      <button class="btn" style="background:#e2e8f0;color:#4a5568" onclick="closeModal('modal-mgr')">Cancel</button>
      <button class="btn btn-success" onclick="saveManager()">&#x2705; Add Manager</button>
    </div>
  </div>
</div>

<!-- TRANSFER MODAL (now with notes) -->
<div class="modal-overlay" id="transfer-modal" onclick="if(event.target===this)closeTransferModal()">
  <div class="modal">
    <h3>&#x21C4; Transfer Task — <span id="tm-taskid"></span></h3>
    <div class="form-grid">
      <div class="fg"><label>Transfer To</label>
        <select id="tm-tto" onchange="tmFillEmail()"><option value="">— None —</option></select>
      </div>
      <div class="fg"><label>Transfer Email</label><input id="tm-ttoe" readonly placeholder="Auto-fills"></div>
      <!-- Transfer Status, Transfer Follow-Up Type hidden — preserved for data integrity -->
      <div style="display:none"><select id="tm-tstat"><option value="">— None —</option><option>Pending</option><option>In Progress</option><option>Completed</option><option>Escalated</option></select></div>
      <div style="display:none"><select id="tm-tfup"><option value="">— None —</option><option>Call</option><option>Email</option><option>In-Person Visit</option><option>Report</option><option>Meeting</option><option>Other</option></select></div>
      <!-- Follow-Up Type and Follow-Up Date — visible -->
      <div class="fg"><label>Follow-Up Type</label>
        <select id="tm-fup" onchange="tmUpdateFollowupRequired()">
          <option value="">— None —</option>
          <option>Daily</option><option>Weekly</option><option>Bi Weekly</option>
          <option>Monthly</option><option>3 Months</option><option>6 Months</option>
          <option>Yearly</option><option>Closed</option>
        </select>
      </div>
      <div class="fg"><label>Follow-Up Date</label>
        <input id="tm-followup-date" type="date" style="width:100%">
      </div>
      <div class="fg wide"><label>Note about this transfer</label>
        <textarea id="tm-note" placeholder="Add context for this transfer…" style="min-height:50px"></textarea>
      </div>
            <div class="fg">
              <label>Upload Attachment</label>
              <input id="tm-file" type="file" multiple style="padding:6px" onchange="handleAttachTransfer(this)">
              <div class="attach-preview" id="tm-att-preview" style="margin-top:6px"></div>
            </div>
    </div>
    <div class="modal-footer">
      <button class="btn" style="background:#e2e8f0;color:#4a5568" onclick="closeTransferModal()">Cancel</button>
      <button class="btn btn-success" onclick="saveTransfer()">&#x2705; Save Transfer</button>
    </div>
  </div>
</div>

<!-- ADD NOTE MODAL -->
<div class="modal-overlay" id="note-modal" onclick="if(event.target===this)closeNoteModal()">
  <div class="modal" style="width:min(460px,96vw)">
    <h3>📝 Add Note — <span id="nm-taskid"></span></h3>
    <div class="fg">
      <label>Note</label>
      <textarea id="nm-note" placeholder="Enter your note…" style="min-height:80px"></textarea>
    </div>
    <div class="modal-footer">
      <button class="btn" style="background:#e2e8f0;color:#4a5568" onclick="closeNoteModal()">Cancel</button>
      <button class="btn btn-success" onclick="saveNote()">✅ Save Note</button>
    </div>
  </div>
</div>

<!-- IMAGE LIGHTBOX -->
<div class="lightbox" id="lightbox" onclick="document.getElementById('lightbox').classList.remove('open')">
  <img id="lightbox-img" src="" alt="">
</div>

<div class="toast" id="toast"></div>

<script>
// ── PHP API helper — replaces google.script.run ──────────────────────────────
function api(action, payload) {
  return fetch('/api.php?action=' + encodeURIComponent(action), {
    method: 'POST',
    headers: {'Content-Type': 'application/json'},
    body: JSON.stringify(payload || {})
  }).then(function(r){
    return r.text().then(function(text){
      var j;try{j=JSON.parse(text)}catch(e){throw 'HTTP '+r.status+' — '+(text||'Invalid server response').slice(0,180)}
      if(!r.ok)throw j.message||('HTTP '+r.status);
      return j;
    });
  }).then(function(j){
    if(j && j.success === false) throw j.message || 'API error';
    return j ? j.data : null;
  });
}

// Upload files using FormData (multipart)
function uploadFilesAPI(files, taskId, fileType) {
  var fd = new FormData();
  fd.append('action', 'uploadAttachments');
  fd.append('taskId', taskId);
  fd.append('fileType', fileType || 'created');
  files.forEach(function(f, i) {
    // Convert dataUrl to Blob
    var arr = f.dataUrl.split(','), mime = arr[0].match(/:(.*?);/)[1];
    var bstr = atob(arr[1]), n = bstr.length, u8 = new Uint8Array(n);
    for (var j = 0; j < n; j++) u8[j] = bstr.charCodeAt(j);
    fd.append('files[]', new Blob([u8], {type: mime}), f.name);
  });
  return fetch('/api.php', {method: 'POST', body: fd})
    .then(function(r){return r.json();})
    .then(function(j){return j.data || [];});
}
</script>
<script>
// ── Built-in data ─────────────────────────────────────────────────────────────
var BUILT_EMP  = [];
var BUILT_MGR  = [];
var BUILT_SITES= [];

var EMPLOYEES = BUILT_EMP.slice();
var MANAGERS  = BUILT_MGR.slice();
var SITES     = BUILT_SITES.slice();

var STATUSES=['Pending','In Progress','Docu Signed','Completed','Filled'];
var PRIO_DAYS={low:3,med:2,high:1};
var PRIO_LABELS={low:'&#x1F7E2; Low',med:'&#x1F7E1; Med',high:'&#x1F534; High'};
var DEPT_C={'Operation':['dbeafe','1e40af'],'Field Team':['d1fae5','065f46'],'SOC':['ede9fe','5b21b6'],
  'Purchasing':['fef3c7','92400e'],'Training':['fee2e2','991b1b'],'Human Resources':['fce7f3','9d174d'],
  'Recruiting':['ecfdf5','065f46'],'Patrol':['e0f2fe','0369a1'],'Finance':['f0fdf4','166534'],
  'CEO':['1F4E79','FFFFFF'],'Account Manager':['fdf4ff','7e22ce']};

var tasks=[];
var idCtr=Date.now();
function genId(p){return p+'-'+(++idCtr);}
// Transfer-modal attachment state
var tmAttachFiles = [];

// ── Helpers ───────────────────────────────────────────────────────────────────
function dp(d){if(!d)return'<span style="color:#a0aec0">—</span>';var c=DEPT_C[d]||['e2e8f0','4a5568'];return'<span class="dept-pill" style="background:#'+c[0]+';color:#'+c[1]+'">'+d+'</span>';}
function toast(msg,ok){var t=document.getElementById('toast');t.textContent=msg;t.style.background=ok===false?'#c0392b':'#375623';t.classList.add('show');setTimeout(function(){t.classList.remove('show');},3200);}
function setSyncing(on,msg){document.getElementById('sync-spin').style.display=on?'inline-block':'none';if(msg!==undefined)document.getElementById('sync-msg').textContent=msg;}
function openModal(id){document.getElementById(id).classList.add('open');}
function closeModal(id){document.getElementById(id).classList.remove('open');}

// Due date display: "Jun 18"
function fmtDuePST(dateStr){
  if(!dateStr) return '—';
  var parts = dateStr.split('-');
  var months=['Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec'];
  var mon = months[parseInt(parts[1],10)-1];
  var day = parseInt(parts[2],10);
  return mon+' '+day;
}

function showTab(id){
  document.querySelectorAll('.tab').forEach(function(t){t.classList.remove('active');});
  document.querySelectorAll('.panel').forEach(function(p){p.classList.remove('active');});
  var ids=['dashboard','employees','sites','managers','newtask','tasks','followup'];
  document.querySelectorAll('.tab')[ids.indexOf(id)].classList.add('active');
  document.getElementById('panel-'+id).classList.add('active');
  if(id==='dashboard')renderDashboard();
  if(id==='tasks')renderTasks();
  if(id==='managers')renderMgr();
  if(id==='followup')renderFollowUp();
}

function renderDashboard(){
  var put=function(id,v){var e=document.getElementById(id);if(e)e.textContent=v;};
  put('dm-employees',EMPLOYEES.length);put('dm-managers',MANAGERS.length);put('dm-sites',SITES.length);
  var done=tasks.filter(function(t){return t.status==='Completed';}).length,pct=tasks.length?Math.round(done/tasks.length*100):0;
  put('dm-progress',pct+'%');document.getElementById('dm-ring').style.setProperty('--progress',pct+'%');
  var counts={};STATUSES.forEach(function(s){counts[s]=0});tasks.forEach(function(t){counts[t.status||'Pending']=(counts[t.status||'Pending']||0)+1});
  var max=Math.max.apply(null,Object.keys(counts).map(function(k){return counts[k]}).concat([1]));
  document.getElementById('dm-status').innerHTML=Object.keys(counts).map(function(k){return'<div class="status-line"><span>'+k+'</span><div class="status-track"><div class="status-fill" style="width:'+Math.round(counts[k]/max*100)+'%"></div></div><b>'+counts[k]+'</b></div>'}).join('');
  document.getElementById('dm-recent').innerHTML=tasks.length?tasks.slice().sort(function(a,b){return String(b.created||b.date).localeCompare(String(a.created||a.date))}).slice(0,5).map(function(t){return'<div class="recent-task"><div><b>'+escHtml(t.subj||t.concern||'Untitled task')+'</b><span>'+escHtml(t.mgrBy||'System')+' → '+escHtml(t.currentlyAssignedTo||t.mgrTo||'Unassigned')+'</span></div><span>'+escHtml(t.status||'Pending')+'</span></div>'}).join(''):'<div class="no-data">No tasks yet.</div>';
}

// ── Render lists ──────────────────────────────────────────────────────────────
function renderEmp(){
  var q=document.getElementById('eq').value.toLowerCase();
  var f=EMPLOYEES.filter(function(e){return e.name.toLowerCase().indexOf(q)>-1||e.phone.indexOf(q)>-1||e.ext.indexOf(q)>-1;});
  document.getElementById('ecnt').textContent='Showing '+f.length+' of '+EMPLOYEES.length+' employees';
  document.getElementById('b-emp').textContent=EMPLOYEES.length;
  document.getElementById('eb').innerHTML=f.map(function(e,i){
    var newTag=e._new?'<span class="new-tag">NEW</span>':'';
    return'<tr><td style="color:#a0aec0;width:28px">'+(i+1)+'</td><td><strong>'+e.name+'</strong>'+newTag+'</td><td>'+e.phone+'</td><td style="color:#718096">'+(e.phone2||'')+'</td><td><code>'+e.ext+'</code></td><td></td></tr>';
  }).join('');
}
function renderSites(){
  var q=document.getElementById('sq').value.toLowerCase();
  var f=SITES.filter(function(s){return s.toLowerCase().indexOf(q)>-1;});
  document.getElementById('scnt').textContent='Showing '+f.length+' of '+SITES.length+' sites';
  document.getElementById('b-site').textContent=SITES.length;
  document.getElementById('sb').innerHTML=f.map(function(s,i){
    return'<tr><td style="color:#a0aec0;width:28px">'+(i+1)+'</td><td>'+s+'</td><td></td></tr>';
  }).join('');
}
function renderMgr(){
  var q=document.getElementById('mq').value.toLowerCase();
  var df=document.getElementById('mdept').value;
  var f=MANAGERS.filter(function(m){var ok=m.name.toLowerCase().indexOf(q)>-1||m.dept.toLowerCase().indexOf(q)>-1||m.email.toLowerCase().indexOf(q)>-1;return df==='all'?ok:ok&&m.dept===df;});
  document.getElementById('mcnt').textContent='Showing '+f.length+' of '+MANAGERS.length+' managers';
  document.getElementById('b-mgr').textContent=MANAGERS.length;
  document.getElementById('mb').innerHTML=f.map(function(m,i){
    var by=tasks.filter(function(t){return t.mgrBy===m.name;}).length;
    var to=tasks.filter(function(t){return t.mgrTo===m.name||t.transferTo===m.name;}).length;
    var newTag=m._new?'<span class="new-tag">NEW</span>':'';
    return'<tr><td style="color:#a0aec0;width:28px">'+(i+1)+'</td>'
      +'<td><strong>'+m.name+'</strong>'+newTag+'</td><td>'+dp(m.dept)+'</td>'
      +'<td><a class="ml" href="mailto:'+m.email+'">'+m.email+'</a></td>'
      +'<td>'+(by?'<span class="pill p-emp">'+by+'</span>':'<span style="color:#a0aec0">—</span>')+'</td>'
      +'<td>'+(to?'<span class="pill p-site">'+to+'</span>':'<span style="color:#a0aec0">—</span>')+'</td>'
      +'<td></td></tr>';
  }).join('');
}

// ── Add Employee / Site / Manager ─────────────────────────────────────────────
function saveEmployee(){
  var name=document.getElementById('ae-name').value.trim();
  var ext=document.getElementById('ae-ext').value.trim();
  if(!name||!ext){alert('Name and Extension are required.');return;}
  var emp={name:name,phone:document.getElementById('ae-phone').value.trim(),phone2:document.getElementById('ae-phone2').value.trim(),ext:ext,_new:true};
  EMPLOYEES.push(emp);EMPLOYEES.sort(function(a,b){return a.name.localeCompare(b.name);});
  rebuildDropdowns();renderEmp();closeModal('modal-emp');toast('Employee added — syncing…');
  api('addEmployee',{emp:emp}).then(function(){toast(name+' saved');}).catch(function(e){toast('Save error: '+e,false);});
  ['ae-name','ae-phone','ae-phone2','ae-ext'].forEach(function(id){document.getElementById(id).value='';});
}
function saveSite(){
  var name=document.getElementById('as-name').value.trim();
  if(!name){alert('Site name is required.');return;}
  SITES.push(name);SITES.sort();rebuildSiteOpts();renderSites();closeModal('modal-site');toast('Site added — syncing…');
  api('addSite',{name:name}).then(function(){toast(name+' saved');}).catch(function(e){toast('Save error: '+e,false);});
  document.getElementById('as-name').value='';
}
function saveManager(){
  var name=document.getElementById('am-name').value.trim();
  var email=document.getElementById('am-email').value.trim();
  if(!name||!email){alert('Name and Email are required.');return;}
  var mgr={name:name,dept:document.getElementById('am-dept').value,email:email,_new:true};
  MANAGERS.push(mgr);MANAGERS.sort(function(a,b){return a.name.localeCompare(b.name);});
  rebuildDropdowns();renderMgr();closeModal('modal-mgr');toast('Manager added — syncing…');
  api('addManager',{mgr:mgr}).then(function(){toast(name+' saved');}).catch(function(e){toast('Save error: '+e,false);});
  ['am-name','am-email'].forEach(function(id){document.getElementById(id).value='';});document.getElementById('am-dept').value='';
}

// ── Task form helpers ─────────────────────────────────────────────────────────
var curType='employee',curPrio='';
// Attachment state for new task form
var newAttachFiles=[]; // [{name, dataUrl, isImage}]
var newLinks=[]; // [{url, label}]

// PIN required to access Transfer / Site Details section
// Change this value to set a different access PIN
var TRANSFER_PIN = '1234';
var _transferUnlocked = false;

function toggleTransferSection(show){
  if(show && !_transferUnlocked){
    var entered = prompt('Enter PIN to access Transfer / Site Details:');
    if(entered === null) return; // user cancelled
    if(entered !== TRANSFER_PIN){
      alert('Incorrect PIN. Access denied.');
      return;
    }
    _transferUnlocked = true;
  }
  document.getElementById('transfer-section').style.display = show ? 'block' : 'none';
  document.getElementById('btn-show-transfer').style.display = show ? 'none' : 'inline-block';
  document.getElementById('btn-hide-transfer').style.display = show ? 'inline-block' : 'none';
  // Re-lock when hidden so PIN is required again next time
  if(!show) _transferUnlocked = false;
}

function setType(t){curType=t;document.getElementById('sec-emp').style.display=t==='employee'?'block':'none';document.getElementById('sec-site').style.display=t==='site'?'block':'none';document.getElementById('tt-e').classList.toggle('active',t==='employee');document.getElementById('tt-s').classList.toggle('active',t==='site');}
function setPrio(p){curPrio=p;['low','med','high'].forEach(function(x){document.getElementById('pb-'+x).classList.toggle('active',x===p);});var base=document.getElementById('f-date').value||new Date().toISOString().split('T')[0];var d=new Date(base);d.setDate(d.getDate()+PRIO_DAYS[p]);document.getElementById('f-due').value=d.toISOString().split('T')[0];}
function onDateChange(){if(curPrio)setPrio(curPrio);}
function mgrEmail(n){var m=MANAGERS.filter(function(x){return x.name===n;})[0]||{};return m.email||'';}
function fillEmail(si,ii){document.getElementById(ii).value=mgrEmail(document.getElementById(si).value);}
function fillEmpId(){var e=EMPLOYEES.filter(function(x){return x.name===document.getElementById('f-en').value;})[0]||{};document.getElementById('f-ei').value=e.ext||'';}

function initForm(){
  document.getElementById('f-date').value=new Date().toISOString().split('T')[0];
  document.getElementById('f-due').value='';
  curPrio='';['low','med','high'].forEach(function(x){document.getElementById('pb-'+x).classList.remove('active');});
  document.getElementById('f-shid').value=genId('SHT');
  document.getElementById('f-tid').value=genId('TASK');
}

// ── Attachment handling (new task) ────────────────────────────────────────────
function handleAttachNew(input){
  var files=Array.from(input.files);
  if(!files.length) return;
  var pending=files.length;
  files.forEach(function(file){
    if(file.size > 52428800){toast('❌ File '+file.name+' is too large (max 50MB)',false);pending--;if(!pending)input.value='';return;}
    var reader=new FileReader();
    reader.onerror=function(e){console.error('FileReader error for '+file.name+':',e);toast('❌ Failed to read file: '+file.name,false);pending--;if(!pending)input.value='';};
    reader.onload=function(e){
      var isImg=file.type.startsWith('image/');
      newAttachFiles.push({name:file.name,dataUrl:e.target.result,isImage:isImg,type:file.type});
      renderAttachPreview();
      pending--;
      if(!pending) input.value='';
    };
    reader.readAsDataURL(file);
  });
}
function renderAttachPreview(){
  var el=document.getElementById('att-preview-new');
  el.innerHTML=newAttachFiles.map(function(f,i){
    if(f.isImage) return '<div class="attach-preview-item"><img src="'+f.dataUrl+'" style="width:48px;height:48px;object-fit:cover;border-radius:4px;border:1px solid #e2e8f0" title="'+f.name+'"><button class="attach-rm" onclick="removeAttachNew('+i+')">✕</button></div>';
    return '<div class="attach-preview-item"><div class="att-file">📄 '+f.name+'</div><button class="attach-rm" style="position:relative;top:0;right:0;margin-left:4px" onclick="removeAttachNew('+i+')">✕</button></div>';
  }).join('');
}
function removeAttachNew(i){newAttachFiles.splice(i,1);renderAttachPreview();}

// Transfer modal attachment handlers
function handleAttachTransfer(input){
  var files=Array.from(input.files||[]);
  if(!files.length) return;
  var pending=files.length;
  files.forEach(function(file){
    if(file.size > 52428800){toast('❌ File '+file.name+' is too large (max 50MB)',false);pending--;if(!pending)input.value='';return;}
    var reader=new FileReader();
    reader.onerror=function(e){console.error('FileReader error for '+file.name+':',e);toast('❌ Failed to read file: '+file.name,false);pending--;if(!pending)input.value='';};
    reader.onload=function(e){
      var isImg=file.type.startsWith('image/');
      tmAttachFiles.push({name:file.name,dataUrl:e.target.result,isImage:isImg,type:file.type});
      renderTmAttachPreview();
      pending--;
      if(!pending) input.value='';
    };
    reader.readAsDataURL(file);
  });
}
function renderTmAttachPreview(){
  var el=document.getElementById('tm-att-preview');
  el.innerHTML=(tmAttachFiles||[]).map(function(f,i){
    if(f.isImage) return '<div class="attach-preview-item"><img src="'+f.dataUrl+'" style="width:48px;height:48px;object-fit:cover;border-radius:4px;border:1px solid #e2e8f0" title="'+f.name+'"><button class="attach-rm" onclick="removeTmAttach('+i+')">✕</button></div>';
    return '<div class="attach-preview-item"><div class="att-file">📄 '+f.name+'</div><button class="attach-rm" style="position:relative;top:0;right:0;margin-left:4px" onclick="removeTmAttach('+i+')">✕</button></div>';
  }).join('');
}
function removeTmAttach(i){tmAttachFiles.splice(i,1);renderTmAttachPreview();}

function addLinkNew(){
  var urlEl=document.getElementById('f-link-url');
  var lblEl=document.getElementById('f-link-label');
  var errEl=document.getElementById('f-link-error');
  if(!urlEl||!lblEl)return;
  var url=urlEl.value.trim();
  if(!url){
    if(errEl){errEl.style.display='block';}
    urlEl.style.border='1.5px solid #c0392b';
    urlEl.focus();
    return;
  }
  // Clear any previous error
  if(errEl) errEl.style.display='none';
  urlEl.style.border='';
  // Prepend https:// if no protocol given
  if(!/^https?:\/\//i.test(url)) url='https://'+url;
  var label=lblEl.value.trim()||url;
  newLinks.push({url:url,label:label});
  urlEl.value='';
  lblEl.value='';
  renderNewLinks();
}
function renderNewLinks(){
  var el=document.getElementById('new-links-list');
  if(!el)return;
  if(!newLinks.length){el.innerHTML='';return;}
  el.innerHTML='<div style="margin-top:6px;font-size:.75rem;color:#4a5568;font-weight:700;text-transform:uppercase;">Links Added:</div>'+
    newLinks.map(function(l,i){
      return '<div class="attachment-item" style="margin-top:3px;display:flex;align-items:center;gap:6px;">🔗 <a href="'+escHtml(l.url)+'" target="_blank" style="flex:1;word-break:break-all">'+escHtml(l.label)+'</a><button class="attach-rm" style="position:relative;top:0;right:0;flex-shrink:0" onclick="removeLinkNew('+i+')">✕</button></div>';
    }).join('');
}
function removeLinkNew(i){newLinks.splice(i,1);renderNewLinks();}

// ── Create Task ───────────────────────────────────────────────────────────────
function nowPST(){
  return new Date().toLocaleString('en-US',{timeZone:'America/Los_Angeles',hour:'numeric',minute:'2-digit',month:'short',day:'numeric',year:'numeric'});
}

function createTask(){
  var isEmp=curType==='employee';
  var subj=isEmp?document.getElementById('f-en').value:document.getElementById('f-sn').value;
  var concern=document.getElementById('f-con').value.trim();
  var otherProcessType=document.getElementById('f-other-con')?document.getElementById('f-other-con').value.trim():'';
  var mgrBy=document.getElementById('f-mby').value;
  var mgrTo=document.getElementById('f-mto').value;
  if(!concern||!mgrBy||!mgrTo){alert('Required: Process Type, Assigned By, Assigned To');return;}
  var findings=document.getElementById('f-find').value.trim();
  var firstEntry=[];
  if(findings) firstEntry.push({ts:nowPST(),actor:mgrBy,type:'Note',text:findings});
  // Add each link as a history entry so it appears in History & Notes
  newLinks.forEach(function(l){
    firstEntry.push({ts:nowPST(),actor:mgrBy,type:'Link',text:l.label,url:l.url});
  });
  var followUpValue=document.getElementById('f-fup').value;
  var followupRequiredValue = followUpValue ? 'Yes' : 'No';
  document.getElementById('f-followup-required').value = followupRequiredValue;
  var transferToValue=document.getElementById('f-tto').value;
  var currentAssignedValue=transferToValue || mgrTo;
  var t={
    id:document.getElementById('f-tid').value,
    sheetId:document.getElementById('f-shid').value,
    type:curType,subj:subj,empId:document.getElementById('f-ei').value,
    concern:concern,
    otherProcessType:otherProcessType,
    findings:findings,
    date:document.getElementById('f-date').value,
    mgrBy:mgrBy,mgrByEmail:document.getElementById('f-mbye').value,
    mgrTo:mgrTo,mgrToEmail:document.getElementById('f-mtoe').value,
    currentlyAssignedTo:currentAssignedValue,
    startDate:curPrio,
    endDate:document.getElementById('f-due').value,
    followupRequired:followupRequiredValue,
    assignedSite:document.getElementById('f-asite').value,
    assignedDesc:document.getElementById('f-adesc').value.trim(),
    followUp:followUpValue,
    'followUp-Date':'',
    transferTo:transferToValue,
    transferEmail:document.getElementById('f-ttoe').value,
    transferStatus:document.getElementById('f-tstat').value,
    transferFollowUp:document.getElementById('f-tfup').value,
    status:'Pending',
    created:new Date().toLocaleDateString(),
    createdTasksFiles:'',
    transferTasksFiles:'',
    // Transfer chain: array of {from, to, ts, note}
    transferHistory:[],
    // History log: array of {ts, actor, type, text}
    history: firstEntry,
    // Attachments: array of {name, dataUrl, isImage}
    attachments: newAttachFiles.slice(),
    // Links: array of {url, label}
    links: newLinks.slice()
  };
  tasks.push(t);
  toast('Task '+t.id+' created!');
  renderTasks();
  renderFollowUp();
  clearForm();
  setSyncing(true,'Saving to Google Sheets…');
  var post = Object.assign({}, t);
  post.history = JSON.stringify(t.history||[]);
  post.attachments = JSON.stringify(t.attachments||[]);
  post.links = JSON.stringify(t.links||[]);

  function saveTaskRow(attachments){
    if (attachments && attachments.length) {
      t.attachments = attachments;
      post.attachments = JSON.stringify(attachments);
      // Store as HYPERLINK formulas so Sheets shows a short label
      post.createdTasksFiles = attachments.map(function(a){
        return '=HYPERLINK("'+(a.url||'')+'","Open Pic")';
      }).join('\n');
      attachments.forEach(function(a){
        var exists = (t.history||[]).some(function(h){return h && h.type==='Attachment' && h.text===a.name && h.url===a.url;});
        if(!exists){
          t.history.push({ts:nowPST(),actor:mgrBy,type:'Attachment',text:a.name,url:a.url,previewUrl:a.previewUrl});
        }
      });
      post.history = JSON.stringify(t.history||[]);
    } else {
      post.createdTasksFiles = '';
    }
    post.transferTasksFiles = t.transferTasksFiles || '';
    api('createTask',{task:post}).then(function(){
      setSyncing(false,'✅ Saved — '+tasks.length+' tasks');
    }).catch(function(e){setSyncing(false,'⚠ Save error');toast('Error saving task: '+e,false);});
  }

  if (t.attachments && t.attachments.length) {
    uploadFilesAPI(t.attachments, t.id, 'created').then(saveTaskRow).catch(function(e){
      console.error('Upload failed:', e);
      toast('⚠️ Attachment upload failed, but task created anyway',true);
      saveTaskRow([]);
    });
  } else {
    saveTaskRow([]);
  }
}

function clearForm(){
  ['f-en','f-sn','f-con','f-find','f-mby','f-mto','f-tto','f-tstat','f-fup','f-tfup','f-asite','f-adesc','f-other-con'].forEach(function(id){var el=document.getElementById(id);if(el)el.value='';});
  var _ow=document.getElementById('f-other-con-wrap');if(_ow)_ow.style.display='none';;
  ['f-ei','f-mbye','f-mtoe','f-ttoe','f-due'].forEach(function(id){var el=document.getElementById(id);if(el)el.value='';});
  newAttachFiles=[];newLinks=[];
  renderAttachPreview();renderNewLinks();
  toggleTransferSection(false);
  initForm();
}

// ── Load / update tasks ───────────────────────────────────────────────────────
function loadTasks(){
  setSyncing(true,'Loading…');
  api('getTasks',{}).then(function(data){
    tasks=normaliseTaskData(data||[]);
    setSyncing(false,'✅ Synced — '+tasks.length+' tasks');
      renderTasks();renderMgr();renderFollowUp();renderDashboard();
  }).catch(function(e){setSyncing(false,'⚠ Could not load');toast('Load error: '+e,false);});
}

function updateStatus(taskId,status){
  var t=tasks.filter(function(x){return x.id===taskId;})[0];
  if(t){
    t.status=status;
    if(!t.history)t.history=[];
    t.history.push({ts:nowPST(),actor:'System',type:'Status',text:'Status changed to '+status});
  }
  renderTasks();
  api('updateTaskStatus',{taskId:taskId,status:status}).then(function(){toast('Status updated');}).catch(function(e){toast('Status error: '+e,false);});
  api('updateTaskHistory',{taskId:taskId,historyJson:JSON.stringify((t&&t.history)||[])}).catch(function(){});
}

function removeTask(taskId){
  if(!confirm('Delete task '+taskId+'?'))return;
  tasks=tasks.filter(function(x){return x.id!==taskId;});
  renderTasks();toast('Task deleted');
  api('deleteTask',{taskId:taskId}).catch(function(e){toast('Delete error: '+e,false);});
}

// ── Transfer modal ────────────────────────────────────────────────────────────
var tmCurrentId='';
function openTransferModal(taskId){
  var t=tasks.filter(function(x){return x.id===taskId;})[0];if(!t)return;
  tmCurrentId=taskId;
  document.getElementById('tm-taskid').textContent=taskId;
  var mOpts='<option value="">— None —</option>'+MANAGERS.map(function(m){return'<option value="'+m.name+'"'+(t.transferTo===m.name?' selected':'')+'>'+m.name+(m.dept?' ('+m.dept+')':'')+'</option>';}).join('');
  document.getElementById('tm-tto').innerHTML=mOpts;
  document.getElementById('tm-ttoe').value=t.transferEmail||'';
  document.getElementById('tm-tstat').value=t.transferStatus||'';
  document.getElementById('tm-fup').value=t.followUp||'';
  document.getElementById('tm-tfup').value=t.transferFollowUp||'';
  document.getElementById('tm-followup-date').value=t.followUpDate||'';
  document.getElementById('tm-note').value='';
  tmAttachFiles = [];
  document.getElementById('tm-att-preview').innerHTML='';
  document.getElementById('transfer-modal').classList.add('open');
}
function closeTransferModal(){document.getElementById('transfer-modal').classList.remove('open');tmCurrentId='';}
function tmFillEmail(){var m=MANAGERS.filter(function(x){return x.name===document.getElementById('tm-tto').value;})[0]||{};document.getElementById('tm-ttoe').value=m.email||'';}

function tmUpdateFollowupRequired(){
  var fup=document.getElementById('tm-fup').value;
  // Clear date when type is deselected, but never disable the input (disabled inputs return empty string)
  if(!fup) document.getElementById('tm-followup-date').value='';
}

function saveTransfer(){
  if(!tmCurrentId)return;
  var savedTaskId = tmCurrentId;
  var newTo=document.getElementById('tm-tto').value;
  var note=document.getElementById('tm-note').value.trim();
  var followUpType=document.getElementById('tm-fup').value;
  var followUpDate=document.getElementById('tm-followup-date').value; // YYYY-MM-DD or ''
  var _followUpStartDate = (function(){var _ex=tasks.filter(function(x){return x.id===tmCurrentId;})[0];return(followUpType&&!(_ex&&_ex.followUpStartDate))?new Date().toLocaleDateString('en-CA',{timeZone:'America/Los_Angeles'}):'';})();
  var t=tasks.filter(function(x){return x.id===savedTaskId;})[0];
  if(!t){toast('Task not found',false);return;}
  var data={
    transferTo:newTo,
    transferEmail:document.getElementById('tm-ttoe').value,
    transferStatus:document.getElementById('tm-tstat').value,
    followUp:followUpType,
    followUpDate:followUpDate,
    'followUp-Date':followUpDate,
    followUpStartDate:_followUpStartDate,
    startDate:_followUpStartDate||t.startDate||'',
    endDate:followUpDate||t.endDate||'',
    otherProcessType:t.otherProcessType||'',
    transferFollowUp:document.getElementById('tm-tfup').value,
    currentlyAssignedTo:newTo||'',
    followupRequired:followUpType?'Yes':'No'
  };

  var prevTo=t.transferTo||t.mgrTo||'';
  var actorName=prevTo||t.currentlyAssignedTo||t.mgrBy||'Unknown'; // defined in outer scope for persistTransfer
  t.transferTo=data.transferTo;t.transferEmail=data.transferEmail;
  t.transferStatus=data.transferStatus;
  t.followUp=followUpType;  // store decoded type, not pipe-encoded string
  t.transferFollowUp=data.transferFollowUp;
  t.followUpDate=followUpDate;
  // Record the date this task entered Follow Up (used as Start Date in Follow Up tab)
  if(followUpType && !t.followUpStartDate) t.followUpStartDate=new Date().toLocaleDateString('en-CA',{timeZone:'America/Los_Angeles'});
  t.currentlyAssignedTo=data.currentlyAssignedTo||t.mgrTo;
  t.followupRequired=data.followupRequired;
  if(!t.history)t.history=[];
  if(!t.transferHistory)t.transferHistory=[];
  var ts=nowPST();
  t.transferHistory.push({from:prevTo,to:newTo,ts:ts});
  t.history.push({ts:ts,actor:actorName,type:'Transfer',text:'Transferred to '+(newTo||'—')+(note?' — '+note:'')});
  if(note) t.history.push({ts:ts,actor:actorName,type:'Note',text:note});

  var pendingFiles=tmAttachFiles.slice(); // capture before modal close clears tmAttachFiles
  renderTasks();renderFollowUp();
  toast('Transfer updated for '+savedTaskId);
  closeTransferModal();

  function persistTransfer(attachments){
    if(attachments && attachments.length){
      t.attachments=(t.attachments||[]).concat(attachments);
      var existingUrls=(t.transferTasksFiles||'').split('\n').filter(Boolean);
      attachments.forEach(function(a){
        var exists=(t.history||[]).some(function(h){return h&&h.type==='Attachment'&&h.text===a.name&&h.url===a.url;});
        if(!exists) t.history.push({ts:nowPST(),actor:actorName,type:'Attachment',text:a.name,url:a.url,previewUrl:a.previewUrl});
        existingUrls.push('=HYPERLINK("'+(a.url||'')+'","Open Pic")');
      });
      t.transferTasksFiles=existingUrls.filter(function(u,i){return existingUrls.indexOf(u)===i;}).join('\n');
    }
    var post=Object.assign({},data);
    post.transferTasksFiles=t.transferTasksFiles||'';
    post.history=JSON.stringify(t.history||[]);
    post.attachments=JSON.stringify(t.attachments||[]);
    post._prevAssignee = prevTo;   // for email notification
    post._note         = note;     // transfer note for email
    setSyncing(true,'Saving transfer…');
    api('updateTaskTransfer',{taskId:savedTaskId,data:post}).then(function(){
      setSyncing(false,'✅ Transfer saved');renderTasks();renderFollowUp();
    }).catch(function(e){setSyncing(false);toast('Transfer save error: '+e,false);});
  }

  if(pendingFiles && pendingFiles.length){
    setSyncing(true,'Uploading transfer attachments…');
    uploadFilesAPI(pendingFiles,savedTaskId,'transfer').then(persistTransfer).catch(function(e){
      toast('⚠️ Attachment upload failed, transfer saved without file',true);
      persistTransfer([]);
    });
  } else {
    persistTransfer([]);
  }
}

// ── Notes modal ───────────────────────────────────────────────────────────────
var nmCurrentId='';
function openNoteModal(taskId){
  nmCurrentId=taskId;
  document.getElementById('nm-taskid').textContent=taskId;
  document.getElementById('nm-note').value='';
  document.getElementById('note-modal').classList.add('open');
}
function closeNoteModal(){document.getElementById('note-modal').classList.remove('open');nmCurrentId='';}
function saveNote(){
  if(!nmCurrentId)return;
  var note=document.getElementById('nm-note').value.trim();
  if(!note)return;
  var t=tasks.filter(function(x){return x.id===nmCurrentId;})[0];
  if(t){
    if(!t.history)t.history=[];
    var actorName = t.currentlyAssignedTo || t.mgrTo || t.mgrBy || 'Unknown';
    t.history.push({ts:nowPST(),actor:actorName,type:'Note',text:note});
  }
  renderTasks();toast('Note added');closeNoteModal();
  api('updateTaskHistory',{taskId:nmCurrentId,historyJson:JSON.stringify(t?t.history:[])}).catch(function(e){toast('Note save error: '+e,false);});
}

// ── Render tasks table ────────────────────────────────────────────────────────
var _openExpId = null;
function toggleExp(id, prefix){
  prefix = prefix || 't';
  var r=document.getElementById(prefix+'-exp-'+id);
  if(!r) return;
  var willOpen = r.style.display==='none';
  // Close any currently open row in either panel
  if(_openExpId){
    var prev=document.getElementById('t-exp-'+_openExpId)||document.getElementById('f-exp-'+_openExpId);
    if(prev && prev.id !== r.id) prev.style.display='none';
  }
  r.style.display = willOpen ? 'table-row' : 'none';
  _openExpId = willOpen ? id : null;
}

function renderTasks(){
  var q=document.getElementById('tq')?document.getElementById('tq').value.toLowerCase():'';
  var tf=document.getElementById('tf-type')?document.getElementById('tf-type').value:'all';
  var mf=document.getElementById('tf-mgr')?document.getElementById('tf-mgr').value:'all';
  var sf=document.getElementById('tf-stat')?document.getElementById('tf-stat').value:'all';
  var pf=document.getElementById('tf-prio')?document.getElementById('tf-prio').value:'all';
  var af=document.getElementById('tf-assigned')?document.getElementById('tf-assigned').value:'all';
  var today=new Date().toLocaleDateString('en-CA',{timeZone:'America/Los_Angeles'});
  var f=tasks.filter(function(t){
    var m=t.id.toLowerCase().indexOf(q)>-1||t.subj.toLowerCase().indexOf(q)>-1||t.concern.toLowerCase().indexOf(q)>-1||t.mgrBy.toLowerCase().indexOf(q)>-1||t.mgrTo.toLowerCase().indexOf(q)>-1;
    return m&&(tf==='all'||t.type===tf)&&(mf==='all'||t.mgrBy===mf||t.mgrTo===mf)&&(sf==='all'||t.status===sf)&&(pf==='all'||t.startDate===pf)&&(af==='all'||(t.currentlyAssignedTo||t.mgrTo)===af);
  });
  var total=tasks.length;
  var cnt={};STATUSES.forEach(function(s){cnt[s]=tasks.filter(function(t){return t.status===s;}).length;});
  var ov=tasks.filter(function(t){return t.endDate&&t.endDate<today&&t.status!=='Completed'&&t.status!=='Filled';}).length;
  document.getElementById('ts').innerHTML=
    '<div class="stat"><div class="num">'+total+'</div><div class="lbl">Total</div></div>'
    +'<div class="stat"><div class="num" style="color:#92400e">'+(cnt['Pending']||0)+'</div><div class="lbl">Pending</div></div>'
    +'<div class="stat"><div class="num" style="color:#1e40af">'+(cnt['In Progress']||0)+'</div><div class="lbl">In Progress</div></div>'
    +'<div class="stat"><div class="num" style="color:#5b21b6">'+(cnt['Docu Signed']||0)+'</div><div class="lbl">Docu Signed</div></div>'
    +'<div class="stat"><div class="num" style="color:#065f46">'+(cnt['Completed']||0)+'</div><div class="lbl">Completed</div></div>'
    +'<div class="stat"><div class="num" style="color:#9d174d">'+(cnt['Filled']||0)+'</div><div class="lbl">Filled</div></div>'
    +'<div class="stat"><div class="num" style="color:#dc2626">'+ov+'</div><div class="lbl">Overdue</div></div>';
  document.getElementById('b-task').textContent=total;
  document.getElementById('b-followup').textContent=tasks.filter(function(t){return t.followupRequired==='Yes';}).length;
  document.getElementById('tcnt').textContent='Showing '+f.length+' of '+total+' tasks';
  if(!f.length){document.getElementById('tb').innerHTML='<tr><td colspan="12" class="no-data">No tasks. Use ➕ New Task to create one.</td></tr>';return;}

  var _prevOpenId = _openExpId;
  document.getElementById('tb').innerHTML=f.map(function(t){
    var ov2=t.endDate&&t.endDate<today&&t.status!=='Completed'&&t.status!=='Filled';
    var pc=t.startDate==='high'?'p-hi':t.startDate==='med'?'p-med':'p-low';
    var pl=(t.startDate&&PRIO_LABELS[t.startDate])||'—';
    var tid=t.id.replace(/\\/g,'\\\\').replace(/'/g,"\\'");
    // Compact "By → To" column (current assignment only)
    var byTo='<span style="font-size:.74rem">'+t.mgrBy+'</span><span style="color:#a0aec0;margin:0 3px">→</span><span style="font-size:.74rem">'+(t.transferTo||t.mgrTo)+'</span>';
    // Due date compact (endDate from sheet, or followUpDate fallback)
    var dueHtml=t.endDate?('<span class="due-badge'+(ov2?' overdue':'')+'">'+fmtDuePST(t.endDate)+'</span>'):(t.followUpDate?'<span class="due-badge" style="color:#5b21b6">📅 '+t.followUpDate+'</span>':'—');

    // Expanded row: history log + compact transfer chain + attachments/links
    var chain='';
    var chainNodes=[t.mgrTo];
    if(t.transferHistory&&t.transferHistory.length){
      t.transferHistory.forEach(function(h){if(h.to)chainNodes.push(h.to);});
    }
    chain='<div class="exp-section"><div class="exp-section-title">Assignment Chain</div><div class="transfer-chain">'
      +chainNodes.map(function(n,i){
        var isCurrent=(i===chainNodes.length-1);
        return'<span class="chain-node'+(isCurrent?' chain-current':'')+'">'+n+'</span>'+(i<chainNodes.length-1?'<span class="chain-arrow">→</span>':'');
      }).join('')+'</div></div>';

    // History log
    var hist='';
    var entries=t.history||[];
    if(entries.length){
      hist='<div class="exp-section"><div class="exp-section-title">History &amp; Notes ('+entries.length+')</div>'
        +'<div class="history-log">'+entries.slice().reverse().map(function(e){
          var content = escHtml(e.text || '');
          if (e.type==='Attachment' && e.url) {
            var linkLabel = /drive\.google|docs\.google|drive\.googleusercontent/.test(e.url) ? 'Open Pic' : escHtml(e.text || 'Attachment');
            content = '<a href="'+e.url+'" target="_blank">'+linkLabel+'</a>';
          } else if (e.type==='Link' && e.url) {
            content = '🔗 <a href="'+escHtml(e.url)+'" target="_blank">'+escHtml(e.text||e.url)+'</a>';
          }
          return'<div class="history-entry"><div class="history-meta"><span class="history-ts">'+e.ts+'</span><span class="history-actor">'+escHtml(e.actor||'')+'</span><span class="history-type">'+escHtml(e.type||'')+'</span></div><div class="history-text">'+content+'</div></div>';
        }).join('')+'</div></div>';
    } else {
      hist='<div class="exp-section"><div class="exp-section-title">History &amp; Notes</div><div style="font-size:.78rem;color:#a0aec0;padding:6px 0">No notes yet.</div></div>';
    }

    // Attachments + links
    var attHtml='';
    var atts=t.attachments||[];
    var lnks=t.links||[];
    if(atts.length||lnks.length){
      attHtml='<div class="exp-section"><div class="exp-section-title">Attachments &amp; Links</div>';
      if(atts.length){
        var isImgAtt=function(a){return a.isImage||!!a.previewUrl||(a.dataUrl&&a.dataUrl.startsWith('data:image'))||/\.(jpe?g|png|gif|webp|bmp|svg)(\?|$)/i.test(a.url||a.name||'');};
        var imgs=atts.filter(isImgAtt);
        var files=atts.filter(function(a){return !isImgAtt(a);});
        if(imgs.length) attHtml+='<div class="att-img-wrap">'+imgs.map(function(a){var src=a.previewUrl||a.url||a.dataUrl||'';var safeSrc=src.replace(/\\/g,'\\\\').replace(/'/g,"\\'");return'<img src="'+src+'" class="att-thumb" title="'+escHtml(a.name)+'" onclick="event.stopPropagation();openLightbox(\''+safeSrc+'\')">';}).join('')+'</div>';
        if(files.length) files.forEach(function(a){
          var href = a.url||a.dataUrl||'#';
          var linkLabel = /drive\.google|docs\.google|drive\.googleusercontent/.test(href) ? 'Open Pic' : escHtml(a.name);
          attHtml += '<div class="attachment-item">📄 <a href="'+href+'" target="_blank" onclick="event.stopPropagation()">'+linkLabel+'</a></div>';
        });
      }
      if(lnks.length) attHtml+='<div class="attachment-list">'+lnks.map(function(l){return'<div class="attachment-item">🔗 <a href="'+l.url+'" target="_blank" onclick="event.stopPropagation()">'+escHtml(l.label)+'</a></div>';}).join('')+'</div>';
      attHtml+='</div>';
    }

    // Key details row (compact)
    var details='<div class="exp-section" style="display:flex;flex-wrap:wrap;gap:12px 20px;font-size:.78rem;">'
      +'<span><span style="color:#718096;font-size:.68rem;text-transform:uppercase;font-weight:700">ID</span> <code>'+t.id+'</code></span>'
      +'<span><span style="color:#718096;font-size:.68rem;text-transform:uppercase;font-weight:700">Sheet</span> <code>'+t.sheetId+'</code></span>'
      +'<span><span style="color:#718096;font-size:.68rem;text-transform:uppercase;font-weight:700">Created</span> '+t.date+'</span>'
      +(t.concern==='Others'&&t.otherProcessType?'<span><span style="color:#718096;font-size:.68rem;text-transform:uppercase;font-weight:700">Other Process Type</span> '+escHtml(t.otherProcessType)+'</span>':'')
      +(t.assignedSite?'<span><span style="color:#718096;font-size:.68rem;text-transform:uppercase;font-weight:700">Site</span> '+escHtml(t.assignedSite)+'</span>':'')
      +(t.followUp?'<span><span style="color:#718096;font-size:.68rem;text-transform:uppercase;font-weight:700">Follow-Up</span> '+escHtml(t.followUp)+'</span>':'')
      +(t.assignedDesc?'<div style="width:100%;margin-top:4px"><span style="color:#718096;font-size:.68rem;text-transform:uppercase;font-weight:700">Description</span><p style="white-space:pre-wrap;margin-top:2px">'+escHtml(t.assignedDesc)+'</p></div>':'')
      +'</div>';

    var currentAssignedText = t.currentlyAssignedTo || t.transferTo || t.mgrTo || '—';
    var followupRequiredText = t.followupRequired || (t.followUp ? 'Yes' : 'No');
    return'<tr style="cursor:pointer'+(ov2?';background:#fff1f0':'')+'" onclick="toggleExp(\''+tid+'\',\'t\')">'
      +'<td>▶</td>'
      +'<td><code style="font-size:.72rem">'+t.id+'</code></td>'
      +'<td><span class="pill '+(t.type==='employee'?'p-emp':'p-site')+'">'+(t.type==='employee'?'👤':'📍')+'</span></td>'
      +'<td><strong style="font-size:.8rem">'+t.subj+'</strong>'+(t.empId?' <code style="font-size:.7rem">'+t.empId+'</code>':'')+'</td>'
      +'<td style="max-width:130px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:.78rem" title="'+(t.concern==='Others'&&t.otherProcessType?'Others: '+t.otherProcessType:t.concern)+'">'+((t.concern==='Others'&&t.otherProcessType)?escHtml('Others: '+t.otherProcessType):t.concern)+'</td>'
      +'<td style="font-size:.76rem;white-space:nowrap">'+byTo+'</td>'
      +'<td style="font-size:.76rem;white-space:nowrap">'+escHtml(currentAssignedText)+'</td>'
      +'<td><span class="pill '+(t.startDate?pc:'')+'">'+pl+'</span></td>'
      +'<td style="font-size:.75rem;white-space:nowrap">'+dueHtml+'</td>'
      +'<td><select onchange="updateStatus(\''+tid+'\',this.value)" onclick="event.stopPropagation()" style="padding:3px 6px;border:1px solid #cbd5e0;border-radius:4px;font-size:.73rem;background:#fff">'
      +STATUSES.map(function(s){return'<option'+(s===t.status?' selected':'')+'>'+s+'</option>';}).join('')+'</select></td>'
      +'<td style="font-size:.76rem;white-space:nowrap">'+escHtml(followupRequiredText)+'</td>'
      +'<td onclick="event.stopPropagation()" style="white-space:nowrap">'
      +'<button class="btn btn-note" onclick="event.stopPropagation();openNoteModal(\''+tid+'\')">📝</button> '
      +'<button class="btn btn-edit" onclick="event.stopPropagation();openTransferModal(\''+tid+'\')">⇄</button> '
      +'<button class="btn btn-danger" onclick="event.stopPropagation();removeTask(\''+tid+'\')">✕</button></td></tr>'
      +'<tr id="t-exp-'+t.id+'" style="display:none" class="exp-row"><td colspan="12">'
      +chain+hist+details+attHtml
      +'</td></tr>';
  }).join('');
  // Restore previously open expanded row so Assignment Chain stays visible after save/transfer
  if(_prevOpenId){var _r=document.getElementById('t-exp-'+_prevOpenId);if(_r)_r.style.display='table-row';}
}

function escHtml(s){return String(s||'').replace(/&/g,'&amp;').replace(/</g,'&lt;').replace(/>/g,'&gt;').replace(/"/g,'&quot;');}

function openLightbox(src){
  document.getElementById('lightbox-img').src=src;
  document.getElementById('lightbox').classList.add('open');
}

function renderFollowUp(){
  var q=document.getElementById('fu-q')?document.getElementById('fu-q').value.toLowerCase():'';
  var today=new Date().toLocaleDateString('en-CA',{timeZone:'America/Los_Angeles'}); // YYYY-MM-DD in PST
  var f=tasks.filter(function(t){
    if(t.followupRequired!=='Yes') return false;
    var txt=(t.id+' '+t.subj+' '+t.concern+' '+t.mgrBy+' '+t.mgrTo+' '+(t.currentlyAssignedTo||'')).toLowerCase();
    return txt.indexOf(q) > -1;
  });
  var total=tasks.filter(function(t){return t.followupRequired==='Yes';}).length;
  document.getElementById('b-followup').textContent=total;
  document.getElementById('fucnt').textContent='Showing '+f.length+' of '+total+' follow-up tasks';
  if(!f.length){document.getElementById('futb').innerHTML='<tr><td colspan="12" class="no-data">No follow-up tasks. Mark Follow-up Required = Yes to add one.</td></tr>';return;}

  document.getElementById('futb').innerHTML=f.map(function(t){
    var ov2=t.followUpDate&&t.followUpDate<today&&t.status!=='Completed'&&t.status!=='Filled';
    var tid=t.id.replace(/\\/g,'\\\\').replace(/'/g,"\\'");
    // Start Date = date task entered Follow Up; fallback to task creation date
    var startDate = t.followUpStartDate || t.date || '—';
    // End Date = user-selected follow-up date
    var endDateHtml = t.followUpDate
      ? '<span class="due-badge'+(ov2?' overdue':'')+'">'+t.followUpDate+(ov2?' ⚠️':'')+'</span>'
      : '—';
    var chainNodes=[t.mgrTo];
    if(t.transferHistory&&t.transferHistory.length){
      t.transferHistory.forEach(function(h){if(h.to)chainNodes.push(h.to);});
    }
    var byTo='<span style="font-size:.74rem">'+t.mgrBy+'</span><span style="color:#a0aec0;margin:0 3px">→</span><span style="font-size:.74rem">'+(t.transferTo||t.mgrTo)+'</span>';
    var chain='<div class="exp-section"><div class="exp-section-title">Assignment Chain</div><div class="transfer-chain">'+chainNodes.map(function(n,i){var isCurrent=(i===chainNodes.length-1);return'<span class="chain-node'+(isCurrent?' chain-current':'')+'">'+n+'</span>'+(i<chainNodes.length-1?'<span class="chain-arrow">→</span>':'');}).join('')+'</div></div>';
    var entries=t.history||[];
    var hist='';
    if(entries.length){
      hist='<div class="exp-section"><div class="exp-section-title">History &amp; Notes ('+entries.length+')</div><div class="history-log">'
        +entries.slice().reverse().map(function(e){
          var content = escHtml(e.text || '');
          if (e.type==='Attachment' && e.url) {
            var linkLabel = /drive\.google|docs\.google|drive\.googleusercontent/.test(e.url) ? 'Open Pic' : escHtml(e.text || 'Attachment');
            content = '<a href="'+e.url+'" target="_blank">'+linkLabel+'</a>';
          } else if (e.type==='Link' && e.url) {
            content = '🔗 <a href="'+escHtml(e.url)+'" target="_blank">'+escHtml(e.text||e.url)+'</a>';
          }
          return'<div class="history-entry"><div class="history-meta"><span class="history-ts">'+e.ts+'</span><span class="history-actor">'+escHtml(e.actor||'')+'</span><span class="history-type">'+escHtml(e.type||'')+'</span></div><div class="history-text">'+content+'</div></div>';
        }).join('')
        +'</div></div>';
    } else {
      hist='<div class="exp-section"><div class="exp-section-title">History &amp; Notes</div><div style="font-size:.78rem;color:#a0aec0;padding:6px 0">No notes yet.</div></div>';
    }
    var atts=t.attachments||[];
    var lnks=t.links||[];
    var attHtml='';
    if(atts.length||lnks.length){
      attHtml='<div class="exp-section"><div class="exp-section-title">Attachments &amp; Links</div>';
        if(atts.length){
        var isImgAtt2=function(a){return a.isImage||!!a.previewUrl||(a.dataUrl&&a.dataUrl.startsWith('data:image'))||/\.(jpe?g|png|gif|webp|bmp|svg)(\?|$)/i.test(a.url||a.name||'');};
        var imgs=atts.filter(isImgAtt2);
        var files=atts.filter(function(a){return !isImgAtt2(a);});
        if(imgs.length) attHtml+='<div class="att-img-wrap">'+imgs.map(function(a){var src=a.previewUrl||a.url||a.dataUrl||'';var safeSrc=src.replace(/\\/g,'\\\\').replace(/'/g,"\\'");return'<img src="'+src+'" class="att-thumb" title="'+escHtml(a.name)+'" onclick="event.stopPropagation();openLightbox(\''+safeSrc+'\')">';}).join('')+'</div>';
        if(files.length) files.forEach(function(a){
          var href = a.url||a.dataUrl||'#';
          var linkLabel = /drive\.google|docs\.google|drive\.googleusercontent/.test(href) ? 'Open Pic' : escHtml(a.name);
          attHtml += '<div class="attachment-item">📄 <a href="'+href+'" target="_blank" onclick="event.stopPropagation()">'+linkLabel+'</a></div>';
        });
      }
      if(lnks.length) attHtml+='<div class="attachment-list">'+lnks.map(function(l){return'<div class="attachment-item">🔗 <a href="'+l.url+'" target="_blank" onclick="event.stopPropagation()">'+escHtml(l.label)+'</a></div>';}).join('')+'</div>';
      attHtml+='</div>';
    }
    var currentAssignedText=t.currentlyAssignedTo||t.transferTo||t.mgrTo||'—';
    var followupRequiredText=t.followupRequired|| (t.followUp ? 'Yes' : 'No');
    var details='<div class="exp-section" style="display:flex;flex-wrap:wrap;gap:12px 20px;font-size:.78rem;">'
      +'<span><span style="color:#718096;font-size:.68rem;text-transform:uppercase;font-weight:700">ID</span> <code>'+t.id+'</code></span>'
      +'<span><span style="color:#718096;font-size:.68rem;text-transform:uppercase;font-weight:700">Sheet</span> <code>'+t.sheetId+'</code></span>'
      +'<span><span style="color:#718096;font-size:.68rem;text-transform:uppercase;font-weight:700">Created</span> '+t.date+'</span>'
      +(t.concern==='Others'&&t.otherProcessType?'<span><span style="color:#718096;font-size:.68rem;text-transform:uppercase;font-weight:700">Other Process Type</span> '+escHtml(t.otherProcessType)+'</span>':'')
      +(t.assignedSite?'<span><span style="color:#718096;font-size:.68rem;text-transform:uppercase;font-weight:700">Site</span> '+escHtml(t.assignedSite)+'</span>':'')
      +(t.followUp?'<span><span style="color:#718096;font-size:.68rem;text-transform:uppercase;font-weight:700">Follow-Up</span> '+escHtml(t.followUp)+'</span>':'')
      +(t.followUpDate?'<span><span style="color:#718096;font-size:.68rem;text-transform:uppercase;font-weight:700">End Date</span> '+escHtml(t.followUpDate)+'</span>':'')
      +(t.assignedDesc?'<div style="width:100%;margin-top:4px"><span style="color:#718096;font-size:.68rem;text-transform:uppercase;font-weight:700">Description</span><p style="white-space:pre-wrap;margin-top:2px">'+escHtml(t.assignedDesc)+'</p></div>':'')
      +'</div>';
    return'<tr style="cursor:pointer'+(ov2?';background:#fff1f0':'')+'" onclick="toggleExp(\''+tid+'\',\'f\')">'
      +'<td>▶</td>'
      +'<td><code style="font-size:.72rem">'+t.id+'</code></td>'
      +'<td><span class="pill '+(t.type==='employee'?'p-emp':'p-site')+'">'+(t.type==='employee'?'👤':'📍')+'</span></td>'
      +'<td><strong style="font-size:.8rem">'+t.subj+'</strong>'+(t.empId?' <code style="font-size:.7rem">'+t.empId+'</code>':'')+'</td>'
      +'<td style="max-width:130px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:.78rem" title="'+(t.concern==='Others'&&t.otherProcessType?'Others: '+t.otherProcessType:t.concern)+'">'+((t.concern==='Others'&&t.otherProcessType)?escHtml('Others: '+t.otherProcessType):t.concern)+'</td>'
      +'<td style="font-size:.76rem;white-space:nowrap">'+byTo+'</td>'
      +'<td style="font-size:.76rem;white-space:nowrap">'+escHtml(currentAssignedText)+'</td>'
      +'<td style="font-size:.75rem;white-space:nowrap">'+escHtml(startDate)+'</td>'
      +'<td style="font-size:.75rem;white-space:nowrap">'+endDateHtml+'</td>'
      +'<td><select onchange="updateStatus(\''+tid+'\',this.value)" onclick="event.stopPropagation()" style="padding:3px 6px;border:1px solid #cbd5e0;border-radius:4px;font-size:.73rem;background:#fff">'
      +STATUSES.map(function(s){return'<option'+(s===t.status?' selected':'')+'>'+s+'</option>';}).join('')+'</select></td>'
      +'<td style="font-size:.76rem;white-space:nowrap">'+escHtml(followupRequiredText)+'</td>'
      +'<td onclick="event.stopPropagation()" style="white-space:nowrap">'
      +'<button class="btn btn-note" onclick="event.stopPropagation();openNoteModal(\''+tid+'\')">📝</button> '
      +'<button class="btn btn-edit" onclick="event.stopPropagation();openTransferModal(\''+tid+'\')">⇄</button> '
      +'<button class="btn btn-danger" onclick="event.stopPropagation();removeTask(\''+tid+'\')">✕</button></td></tr>'
      +'<tr id="f-exp-'+t.id+'" style="display:none" class="exp-row"><td colspan="12">'+chain+hist+details+attHtml+'</td></tr>';
  }).join('');
  // Restore previously open expanded row
  if(_openExpId){var _r2=document.getElementById('f-exp-'+_openExpId);if(_r2)_r2.style.display='table-row';}
}

function exportTasks(){
  if(!tasks.length){alert('No tasks to export.');return;}
  var hdr='Task ID,Sheet ID,Type,Subject,Emp ID,Concern,Findings,Date,Mgr By,Email By,Mgr To,Email To,Currently Assigned To,Priority,Due Date,Follow-up Required,Assigned Site,Description,Follow-Up,Transfer To,Transfer Email,Transfer Status,Transfer Follow-Up,Status,Created,Created Tasks Files,Transfer Tasks Files';
  var rows=tasks.map(function(t){return[t.id,t.sheetId,t.type,t.subj,t.empId,t.concern,t.findings,t.date,t.mgrBy,t.mgrByEmail,t.mgrTo,t.mgrToEmail,t.currentlyAssignedTo,t.priority,t.dueDate,t.followupRequired,t.assignedSite,t.assignedDesc,t.followUp,t.transferTo,t.transferEmail,t.transferStatus,t.transferFollowUp,t.status,t.created,t.createdTasksFiles||'',t.transferTasksFiles||''].map(function(v){return'"'+String(v||'').replace(/"/g,'""')+'"';}).join(',');});
  var b=new Blob([[hdr].concat(rows).join('\n')],{type:'text/csv'});
  var a=document.createElement('a');a.href=URL.createObjectURL(b);a.download='hhp_tasks.csv';a.click();
}

// ── Dropdowns ─────────────────────────────────────────────────────────────────
function rebuildSiteOpts(){
  var sOpts=SITES.map(function(s){return'<option value="'+s+'">'+s+'</option>';}).join('');
  document.getElementById('f-sn').innerHTML='<option value="">— Select Site —</option>'+sOpts;
  document.getElementById('f-asite').innerHTML='<option value="">— Select Site (optional) —</option>'+sOpts;
}
function rebuildDropdowns(){
  var mOpts=MANAGERS.map(function(m){return'<option value="'+m.name+'">'+m.name+(m.dept?' ('+m.dept+')':'')+'</option>';}).join('');
  ['f-mby','f-mto'].forEach(function(id){document.getElementById(id).innerHTML='<option value="">— Select Manager —</option>'+mOpts;});
  document.getElementById('f-tto').innerHTML='<option value="">— None —</option>'+mOpts;
  document.getElementById('f-en').innerHTML='<option value="">— Select Employee —</option>'+EMPLOYEES.map(function(e){return'<option value="'+e.name+'">'+e.name+' (ext '+e.ext+')</option>';}).join('');
  rebuildSiteOpts();
  var depts=[...new Set(MANAGERS.map(function(m){return m.dept;}).filter(Boolean))].sort();
  var sel=document.getElementById('mdept');
  sel.innerHTML='<option value="all">All Departments</option>';
  depts.forEach(function(d){var o=document.createElement('option');o.value=d;o.textContent=d;sel.appendChild(o);});
  var msel=document.getElementById('tf-mgr');
  msel.innerHTML='<option value="all">All Managers</option>'+MANAGERS.map(function(m){return'<option value="'+m.name+'">'+m.name+'</option>';}).join('');
  // Populate Assigned To filter from MANAGERS list (same source as All Managers dropdown)
  var asel=document.getElementById('tf-assigned');
  if(asel){
    var mgrNames=MANAGERS.map(function(m){return m.name;}).slice().sort();
    asel.innerHTML='<option value="all">Currently Assigned To</option>'+mgrNames.map(function(n){return'<option value="'+n+'">'+n+'</option>';}).join('');
  }
}

// ── Boot ──────────────────────────────────────────────────────────────────────
// Advance a YYYY-MM-DD date string by one follow-up interval
function advanceByInterval(dateStr, interval){
  var d=new Date(dateStr+'T12:00:00'); // noon to avoid DST edge cases
  var t=interval.toLowerCase().replace(/\s+/g,'');
  if(t==='daily')             d.setDate(d.getDate()+1);
  else if(t==='weekly')       d.setDate(d.getDate()+7);
  else if(t==='biweekly'||t==='bi-weekly') d.setDate(d.getDate()+14);
  else if(t==='monthly')      d.setMonth(d.getMonth()+1);
  else if(t==='3months')      d.setMonth(d.getMonth()+3);
  else if(t==='6months')      d.setMonth(d.getMonth()+6);
  else if(t==='yearly')       d.setFullYear(d.getFullYear()+1);
  else d.setDate(d.getDate()+7); // default weekly
  return d.toLocaleDateString('en-CA',{timeZone:'America/Los_Angeles'});
}

function normaliseTaskData(taskData){
  var todayPST=new Date().toLocaleDateString('en-CA',{timeZone:'America/Los_Angeles'}); // YYYY-MM-DD
  taskData.forEach(function(t){
    if(!t.history)t.history=[];
    if(!t.transferHistory)t.transferHistory=[];
    if(!t.attachments)t.attachments=[];
    if(!t.links)t.links=[];
    // Sheet column header is "followUp-Date"; map to t.followUpDate for use in the app
    if(!t.followUpDate) t.followUpDate = t['followUp-Date'] || '';
    if(!t.followUpStartDate) t.followUpStartDate = '';
    if(!t.nextFollowUpDue) t.nextFollowUpDue = '';
    if(!t.otherProcessType) t.otherProcessType = '';
    // Handle any legacy pipe-encoded values: "Weekly|2026-07-01" → split back out
    if(t.followUp && t.followUp.indexOf('|') > -1){
      var parts = t.followUp.split('|');
      t.followUp = parts[0];
      if(!t.followUpDate) t.followUpDate = parts[1] || '';
    }
    try{ if(typeof t.history==='string'&&t.history) t.history=JSON.parse(t.history); }catch(e){}
    try{ if(typeof t.attachments==='string'&&t.attachments) t.attachments=JSON.parse(t.attachments); }catch(e){}
    try{ if(typeof t.links==='string'&&t.links) t.links=JSON.parse(t.links); }catch(e){}
    if(!t.currentlyAssignedTo) t.currentlyAssignedTo=t.transferTo||t.mgrTo||'';
    if(!t.followupRequired) t.followupRequired=t.followUp?'Yes':'No';
    if(t.attachments&&t.attachments.length){
      t.attachments.forEach(function(a){
        var exists=(t.history||[]).some(function(h){return h&&h.type==='Attachment'&&h.text===a.name;});
        if(!exists)(t.history||(t.history=[])).push({ts:t.date||nowPST(),actor:t.mgrBy||'',type:'Attachment',text:a.name,url:a.url,previewUrl:a.previewUrl});
      });
    }

    // ── Recurring Follow-Up Scheduler ──────────────────────────────────────────
    // Runs on every load. For tasks with a followUp type + followUpDate (end date):
    // Compute the next scheduled occurrence. If it's today or past (and ≤ end date)
    // and hasn't been recorded yet → add one history entry and advance nextFollowUpDue
    // by one interval. Stops automatically once nextFollowUpDue > followUpDate.
    if(t.followUp && t.followUpDate && t.followupRequired==='Yes'){
      var endDate=t.followUpDate; // YYYY-MM-DD
      // nextFollowUpDue: the next date a follow-up entry should be created
      // Initialise from followUpStartDate (or task creation date) if not yet set
      if(!t.nextFollowUpDue){
        t.nextFollowUpDue = t.followUpStartDate || t.date || todayPST;
      }
      // Only process if next due is on or before today AND on or before end date
      if(t.nextFollowUpDue <= todayPST && t.nextFollowUpDue <= endDate){
        var dueDateForEntry = t.nextFollowUpDue;
        // Check not already recorded for this exact due date
        var alreadyFired=(t.history||[]).some(function(h){
          return h.type==='Follow-Up' && h.followUpDue===dueDateForEntry;
        });
        if(!alreadyFired){
          t.history.push({
            ts:nowPST(),
            actor:'System',
            type:'Follow-Up',
            text:'Follow-up due: '+t.followUp+' ('+dueDateForEntry+')',
            followUpDue:dueDateForEntry
          });
          // Advance nextFollowUpDue by one interval
          t.nextFollowUpDue = advanceByInterval(dueDateForEntry, t.followUp);
          // Persist history + updated nextFollowUpDue to sheet
          var _tid2=t.id, _hist2=JSON.stringify(t.history||[]), _next=t.nextFollowUpDue;
          api('updateTaskHistory',{taskId:_tid2,historyJson:_hist2}).catch(function(){});
          api('updateTaskField',{taskId:_tid2,fieldName:'nextFollowUpDue',value:_next}).catch(function(){});
        }
      }
    }
    // ───────────────────────────────────────────────────────────────────────────
  });
  return taskData;
}

function loadTasksAfterCustomData(){
  api('getTasks',{}).then(function(taskData){
    tasks=normaliseTaskData(taskData||[]);
    setSyncing(false,'✅ Ready — '+tasks.length+' tasks');
    renderTasks();renderMgr();renderFollowUp();
  }).catch(function(e){
    setSyncing(false,'⚠ Task load error: '+str(e));
    toast('Task load error: '+e,false);
  });
}

function boot(){
  rebuildDropdowns();
  renderEmp();renderSites();renderMgr();
  var fFupEl=document.getElementById('f-fup');
  if(fFupEl){ fFupEl.addEventListener('change',function(){ document.getElementById('f-followup-required').value=this.value?'Yes':'No'; }); }
  initForm();
  setSyncing(true,'Loading…');
  api('getCustomData',{}).then(function(data){
    if(data.employees&&data.employees.length){
      data.employees.forEach(function(e){EMPLOYEES.push(e);});
      EMPLOYEES.sort(function(a,b){return a.name.localeCompare(b.name);});
    }
    if(data.sites&&data.sites.length){
      data.sites.forEach(function(s){SITES.push(s);});
      SITES.sort();
    }
    if(data.managers&&data.managers.length){
      data.managers.forEach(function(m){MANAGERS.push(m);});
      MANAGERS.sort(function(a,b){return a.name.localeCompare(b.name);});
    }
    rebuildDropdowns();renderEmp();renderSites();renderMgr();
    loadTasksAfterCustomData();
  }).catch(function(e){
    setSyncing(false,'⚠ Load error: '+e);
    toast('Load error: '+e,false);
    loadTasksAfterCustomData();
  });
}
boot();
</script>
</body>
</html>
