<?php
// ============================================================
// modules/attendance/muster.php – Muster Management
// ============================================================
require_once __DIR__ . '/../../config/config.php';
require_once __DIR__ . '/../../includes/functions.php';
startSession(); requireLogin();
$db   = Database::getInstance();
$page = 'Muster Management';
$user = currentUser();

$month  = cleanInt($_GET['month'] ?? date('n'));
$year   = cleanInt($_GET['year']  ?? date('Y'));
$dept   = cleanInt($_GET['dept']  ?? 0);
$empId  = cleanInt($_GET['emp']   ?? 0);

$daysInMonth = cal_days_in_month(CAL_GREGORIAN, $month, $year);

// POST handlers
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    verifyCsrf();
    $action = post('action');

    if ($action === 'update_day') {
        requireRole('superadmin','admin','hr','management');
        $eId    = postInt('employee_id');
        // FIX (07 Jul 2026): confirm this employee belongs to the current org.
        $target = $db->fetchOne("SELECT company_id FROM employees WHERE id=?", [$eId]);
        if (!$target || !in_array($target['company_id'], orgCompanyIds($db))) {
            jsonResponse(false, 'Employee not found.');
        }
        $date   = post('muster_date');
        $status = post('status');
        $inT    = post('in_time') ?: null;
        $outT   = post('out_time') ?: null;
        $remarks= post('remarks');
        $wh     = ($inT && $outT) ? round((strtotime("$date $outT") - strtotime("$date $inT")) / 3600, 2) : 0;

        $existing = $db->fetchValue("SELECT id FROM muster WHERE employee_id=? AND muster_date=?", [$eId,$date]);
        if ($existing) {
            $db->execute("UPDATE muster SET status=?,in_time=?,out_time=?,work_hours=?,remarks=?,modified_by=?,is_locked=0 WHERE employee_id=? AND muster_date=?",
                [$status,$inT,$outT,$wh,$remarks,$user['id'],$eId,$date]);
        } else {
            $db->insertRow('muster',['employee_id'=>$eId,'muster_date'=>$date,'status'=>$status,'in_time'=>$inT,'out_time'=>$outT,'work_hours'=>$wh,'remarks'=>$remarks]);
        }
        auditLog('UPDATE','muster',0,[],$_POST);
        jsonResponse(true,'Muster updated');
    }

    if ($action === 'lock_muster') {
        requireRole('superadmin','admin','hr','management');
        $eId   = postInt('employee_id');
        // FIX (07 Jul 2026): confirm this employee belongs to the current org.
        $target = $db->fetchOne("SELECT company_id FROM employees WHERE id=?", [$eId]);
        if (!$target || !in_array($target['company_id'], orgCompanyIds($db))) {
            jsonResponse(false, 'Employee not found.');
        }
        $m     = postInt('month');
        $y     = postInt('year');
        $db->execute("UPDATE muster SET is_locked=1 WHERE employee_id=? AND MONTH(muster_date)=? AND YEAR(muster_date)=?", [$eId,$m,$y]);

        // Rebuild summary
        $summary = $db->fetchOne(
            "SELECT
               SUM(CASE WHEN status='P' THEN 1 WHEN status='OD' THEN 1 WHEN status='H' THEN 0.5 ELSE 0 END) AS present_days,
               SUM(CASE WHEN status='A' THEN 1 ELSE 0 END) AS absent_days,
               SUM(CASE WHEN status='H' THEN 0.5 ELSE 0 END) AS half_days,
               SUM(CASE WHEN status='L' THEN 1 ELSE 0 END) AS leave_days,
               SUM(CASE WHEN status='WO' THEN 1 ELSE 0 END) AS week_off_days,
               SUM(CASE WHEN status='PH' THEN 1 ELSE 0 END) AS holidays,
               SUM(CASE WHEN status='LOP' THEN 1 ELSE 0 END) AS lop_days,
               SUM(CASE WHEN status='OD' THEN 1 ELSE 0 END) AS od_days,
               COALESCE(SUM(ot_hours),0) AS ot_hours,
               SUM(CASE WHEN is_late=1 THEN 1 ELSE 0 END) AS late_count
             FROM muster WHERE employee_id=? AND MONTH(muster_date)=? AND YEAR(muster_date)=?",
            [$eId,$m,$y]
        );
        $db->execute(
            "INSERT INTO muster_summary (employee_id,month,year,present_days,absent_days,half_days,leave_days,week_off_days,holidays,lop_days,od_days,ot_hours,late_count,is_locked)
             VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,1)
             ON DUPLICATE KEY UPDATE present_days=VALUES(present_days),absent_days=VALUES(absent_days),half_days=VALUES(half_days),leave_days=VALUES(leave_days),week_off_days=VALUES(week_off_days),holidays=VALUES(holidays),lop_days=VALUES(lop_days),od_days=VALUES(od_days),ot_hours=VALUES(ot_hours),late_count=VALUES(late_count),is_locked=1",
            [$eId,$m,$y,$summary['present_days']??0,$summary['absent_days']??0,$summary['half_days']??0,$summary['leave_days']??0,$summary['week_off_days']??0,$summary['holidays']??0,$summary['lop_days']??0,$summary['od_days']??0,$summary['ot_hours']??0,$summary['late_count']??0]
        );
        jsonResponse(true,'Muster locked and summary updated');
    }

    if ($action === 'bulk_lock') {
        requireRole('superadmin','admin','hr','management');
        $m = postInt('month'); $y = postInt('year');
        // FIX (07 Jul 2026): scope to current org — this used to lock
        // muster for every organization's employees at once.
        [$bulkClause, $bulkParams] = orgScopeClause($db, 'company_id');
        $employees = $db->fetchAll("SELECT id FROM employees WHERE status='active' AND $bulkClause", $bulkParams);
        foreach ($employees as $e) {
            $summary = $db->fetchOne(
                "SELECT SUM(CASE WHEN status IN('P','OD') THEN 1 WHEN status='H' THEN 0.5 ELSE 0 END) AS pd,
                        SUM(CASE WHEN status='A' THEN 1 ELSE 0 END) AS ad,
                        SUM(CASE WHEN status='LOP' THEN 1 ELSE 0 END) AS lop,
                        SUM(CASE WHEN status='OD' THEN 1 ELSE 0 END) AS od
                   FROM muster WHERE employee_id=? AND MONTH(muster_date)=? AND YEAR(muster_date)=?",
                [$e['id'],$m,$y]
            );
            $db->execute(
                "INSERT INTO muster_summary (employee_id,month,year,present_days,absent_days,lop_days,od_days,is_locked)
                 VALUES (?,?,?,?,?,?,?,1) ON DUPLICATE KEY UPDATE present_days=VALUES(present_days),absent_days=VALUES(absent_days),lop_days=VALUES(lop_days),od_days=VALUES(od_days),is_locked=1",
                [$e['id'],$m,$y,$summary['pd']??0,$summary['ad']??0,$summary['lop']??0,$summary['od']??0]
            );
            $db->execute("UPDATE muster SET is_locked=1 WHERE employee_id=? AND MONTH(muster_date)=? AND YEAR(muster_date)=?",[$e['id'],$m,$y]);
        }
        setFlash('success', 'Muster locked for all employees for '.monthName($m).' '.$y);
        header("Location: muster.php?month=$m&year=$y"); exit;
    }
}

// Employees list
// FIX (07 Jul 2026): scope to current org.
[$orgClauseM, $orgParamsM] = orgScopeClause($db, 'e.company_id');
$whereEmp  = "e.status='active' AND $orgClauseM";
$paramsEmp = $orgParamsM;
if ($dept)  { $whereEmp .= ' AND e.department_id=?'; $paramsEmp[] = $dept; }
if ($empId) { $whereEmp .= ' AND e.id=?';             $paramsEmp[] = $empId; }

$employees = $db->fetchAll(
    "SELECT e.id, e.employee_id, e.first_name, e.last_name, d.name AS dept
       FROM employees e
  LEFT JOIN departments d ON d.id=e.department_id
      WHERE $whereEmp ORDER BY e.first_name LIMIT 50",
    $paramsEmp
);

$empIds = array_column($employees, 'id');

// Muster data for period
$musterData = [];
if ($empIds) {
    $ph = implode(',', array_fill(0, count($empIds), '?'));
    $rows = $db->fetchAll(
        "SELECT employee_id, muster_date, status, in_time, out_time, work_hours, is_locked, remarks
           FROM muster WHERE employee_id IN ($ph) AND MONTH(muster_date)=? AND YEAR(muster_date)=?",
        array_merge($empIds, [$month, $year])
    );
    foreach ($rows as $r) {
        $d = $r['muster_date'];
        $musterData[$r['employee_id']][$d] = $r;
    }
}

// Holidays
$holidays = $db->fetchAll(
    "SELECT holiday_date FROM holiday_calendar WHERE MONTH(holiday_date)=? AND YEAR(holiday_date)=? AND is_active=1",
    [$month, $year]
);
$holidayDates = array_column($holidays, 'holiday_date');

$departments = $db->fetchAll("SELECT id,name FROM departments WHERE is_active=1 ORDER BY name");
[$allEmpsClause, $allEmpsParams] = orgScopeClause($db, 'company_id');
$allEmps     = $db->fetchAll("SELECT id,employee_id,first_name,last_name FROM employees WHERE status='active' AND $allEmpsClause ORDER BY first_name", $allEmpsParams);
$leaveTypes  = $db->fetchAll("SELECT id,code FROM leave_types WHERE is_active=1");

$headerActions = '
<form method="POST" class="d-inline" onsubmit="return confirm(\'Lock muster for ALL employees for '.monthName($month).' '.$year.'?\')">
  '.csrfField().'
  <input type="hidden" name="action" value="bulk_lock">
  <input type="hidden" name="month" value="'.$month.'">
  <input type="hidden" name="year"  value="'.$year.'">
  <button class="btn btn-warning btn-sm text-dark"><i class="ti ti-lock me-1"></i>Lock All Muster</button>
</form>
<a href="muster_report.php?month='.$month.'&year='.$year.'" class="btn btn-sm btn-outline-secondary ms-1">
  <i class="ti ti-download me-1"></i>Export</a>';

include __DIR__ . '/../../includes/header.php';
?>

<!-- Filters -->
<div class="pc-card mb-3">
  <form method="GET" class="pc-filters">
    <div><label class="pc-label">Month</label>
      <select name="month" class="form-select form-select-sm">
        <?php for ($m=1;$m<=12;$m++): ?>
        <option value="<?= $m ?>" <?= $m===$month?'selected':'' ?>><?= monthName($m) ?></option>
        <?php endfor; ?>
      </select></div>
    <div><label class="pc-label">Year</label>
      <select name="year" class="form-select form-select-sm">
        <?php for ($y=date('Y')-1;$y<=date('Y')+1;$y++): ?>
        <option value="<?= $y ?>" <?= $y===$year?'selected':'' ?>><?= $y ?></option>
        <?php endfor; ?>
      </select></div>
    <div><label class="pc-label">Department</label>
      <select name="dept" class="form-select form-select-sm" style="width:160px">
        <option value="">All</option>
        <?php foreach ($departments as $d): ?>
        <option value="<?= $d['id'] ?>" <?= $dept==$d['id']?'selected':'' ?>><?= clean($d['name']) ?></option>
        <?php endforeach; ?>
      </select></div>
    <div><label class="pc-label">Employee</label>
      <select name="emp" class="form-select form-select-sm" style="width:180px">
        <option value="">All</option>
        <?php foreach ($allEmps as $e): ?>
        <option value="<?= $e['id'] ?>" <?= $empId==$e['id']?'selected':'' ?>><?= clean($e['first_name'].' '.$e['last_name']) ?></option>
        <?php endforeach; ?>
      </select></div>
    <div style="margin-top:auto"><button class="btn btn-pc btn-sm">View</button></div>
  </form>
</div>

<!-- Legend -->
<div class="d-flex gap-3 mb-3 flex-wrap">
  <?php foreach ([['P','Present','success'],['A','Absent','danger'],['H','Half Day','warning'],['L','Leave','info'],['WO','Week Off','secondary'],['PH','Holiday','primary'],['LOP','LOP','dark'],['OD','On Duty','od']] as [$c,$l,$bs]): ?>
  <div class="d-flex align-items-center gap-1" style="font-size:11px">
    <?php if ($bs === 'od'): ?>
    <span class="badge" style="background:#7c3aed;color:#fff"><?= $c ?></span><?= $l ?>
    <?php else: ?>
    <span class="badge bg-<?= $bs ?>"><?= $c ?></span><?= $l ?>
    <?php endif; ?>
  </div>
  <?php endforeach; ?>
</div>

<!-- Muster Grid -->
<div class="pc-card" style="overflow-x:auto">
  <table style="border-collapse:collapse;min-width:<?= 200 + $daysInMonth*34 ?>px;font-size:11px">
    <thead>
      <tr>
        <th style="position:sticky;left:0;background:#fafbfc;z-index:2;padding:6px 10px;border-bottom:2px solid var(--pc-border);min-width:180px">Employee</th>
        <?php for ($d=1;$d<=$daysInMonth;$d++):
          $dateStr = sprintf('%04d-%02d-%02d',$year,$month,$d);
          $dow     = date('N', strtotime($dateStr)); // 1=Mon..7=Sun
          $isWknd  = ($dow == 6 || $dow == 7);
          $isHol   = in_array($dateStr, $holidayDates);
          $dayName = date('D', strtotime($dateStr));
        ?>
        <th style="text-align:center;padding:4px 2px;border-bottom:2px solid var(--pc-border);min-width:30px;background:<?= $isHol?'#dbeafe':($isWknd?'#f3f4f6':'#fafbfc') ?>">
          <div style="font-weight:700"><?= $d ?></div>
          <div style="font-size:9px;color:<?= $isHol?'#1d4ed8':($isWknd?'#9ca3af':'#6b7280') ?>"><?= substr($dayName,0,2) ?></div>
        </th>
        <?php endfor; ?>
        <th style="padding:4px 8px;border-bottom:2px solid var(--pc-border);text-align:center;background:#fafbfc" title="Present (includes On Duty days)">P</th>
        <th style="padding:4px 8px;border-bottom:2px solid var(--pc-border);text-align:center;background:#fafbfc">A</th>
        <th style="padding:4px 8px;border-bottom:2px solid var(--pc-border);text-align:center;background:#fafbfc">LOP</th>
        <th style="padding:4px 8px;border-bottom:2px solid var(--pc-border);text-align:center;background:#fafbfc" title="Of the Present total, how many were On Duty">OD</th>
        <th style="padding:4px 8px;border-bottom:2px solid var(--pc-border);text-align:center;background:#fafbfc">Action</th>
      </tr>
    </thead>
    <tbody>
    <?php foreach ($employees as $emp):
      $eId     = $emp['id'];
      $empData = $musterData[$eId] ?? [];
      $presentDays = 0; $absentDays = 0; $lopDays = 0; $onDutyDays = 0;
    ?>
    <tr>
      <td style="position:sticky;left:0;background:#fff;z-index:1;padding:6px 10px;border-bottom:1px solid var(--pc-border)">
        <div class="fw-semibold"><?= clean($emp['first_name'].' '.$emp['last_name']) ?></div>
        <div style="font-size:9px;color:var(--pc-text2)"><?= clean($emp['employee_id']) ?></div>
      </td>
      <?php for ($d=1;$d<=$daysInMonth;$d++):
        $dateStr  = sprintf('%04d-%02d-%02d',$year,$month,$d);
        $dow      = date('N', strtotime($dateStr));
        $isWknd   = ($dow == 6 || $dow == 7);
        $isHol    = in_array($dateStr, $holidayDates);
        $rec      = $empData[$dateStr] ?? null;
        $status   = $rec['status'] ?? ($isHol ? 'PH' : ($isWknd ? 'WO' : ''));
        $locked   = $rec['is_locked'] ?? 0;
        $badgeCls = match($status) {
          'P','A','H','L','WO','PH','LOP' => ['P'=>'success','A'=>'danger','H'=>'warning','L'=>'info','WO'=>'secondary','PH'=>'primary','LOP'=>'dark'][$status],
          'OD' => 'od',
          default => 'light'
        };
        if ($status==='P') $presentDays++;
        elseif ($status==='A') $absentDays++;
        elseif ($status==='LOP') $lopDays++;
        elseif ($status==='H') $presentDays += 0.5;
        elseif ($status==='OD') { $presentDays++; $onDutyDays++; }
      ?>
      <td style="text-align:center;padding:2px;border-bottom:1px solid var(--pc-border);background:<?= $isHol?'#eff6ff':($isWknd?'#f9fafb':'') ?>">
        <?php if ($status): ?>
        <span class="badge <?= $badgeCls==='od' ? '' : 'bg-'.$badgeCls ?> <?= $locked?'':'muster-cell' ?>"
          style="font-size:9px;cursor:<?= $locked?'default':'pointer' ?>;padding:2px 4px<?= $badgeCls==='od' ? ';background:#7c3aed;color:#fff' : '' ?>"
          <?php if (!$locked): ?>
          onclick="openMusterEdit(<?= $eId ?>, '<?= $dateStr ?>', '<?= $status ?>', '<?= $rec['in_time']??'' ?>', '<?= $rec['out_time']??'' ?>', '<?= addslashes($rec['remarks']??'') ?>')"
          title="<?= $rec['in_time']??'' ?> – <?= $rec['out_time']??'' ?>"
          <?php endif; ?>
        ><?= $status ?></span>
        <?php else: ?>
        <span class="badge bg-light text-dark muster-cell" style="font-size:9px;cursor:pointer"
          onclick="openMusterEdit(<?= $eId ?>, '<?= $dateStr ?>', 'P', '', '', '')">+</span>
        <?php endif; ?>
      </td>
      <?php endfor; ?>
      <td style="text-align:center;font-weight:700;color:#16a34a;border-bottom:1px solid var(--pc-border);padding:4px 8px"><?= $presentDays ?></td>
      <td style="text-align:center;font-weight:700;color:#dc2626;border-bottom:1px solid var(--pc-border);padding:4px 8px"><?= $absentDays ?></td>
      <td style="text-align:center;font-weight:700;color:#d97706;border-bottom:1px solid var(--pc-border);padding:4px 8px"><?= $lopDays ?></td>
      <td style="text-align:center;font-weight:700;color:#7c3aed;border-bottom:1px solid var(--pc-border);padding:4px 8px"><?= $onDutyDays ?></td>
      <td style="border-bottom:1px solid var(--pc-border);padding:4px 8px">
        <button class="btn btn-sm btn-outline-warning" style="font-size:10px;padding:2px 6px"
          onclick="lockEmployee(<?= $eId ?>,<?= $month ?>,<?= $year ?>)" title="Lock this employee's muster">
          <i class="ti ti-lock" style="font-size:12px"></i>
        </button>
      </td>
    </tr>
    <?php endforeach; ?>
    </tbody>
  </table>
</div>

<!-- Edit Modal -->
<div class="modal fade" id="musterEditModal" tabindex="-1">
  <div class="modal-dialog modal-sm">
    <div class="modal-content">
      <div class="modal-header py-2"><h6 class="modal-title" id="musterEditTitle">Edit Muster</h6>
        <button type="button" class="btn-close" data-bs-dismiss="modal"></button></div>
      <div class="modal-body">
        <div class="mb-2">
          <label class="pc-label">Status</label>
          <select id="editStatus" class="form-select form-select-sm">
            <?php foreach (['P'=>'Present','A'=>'Absent','H'=>'Half Day','L'=>'Leave','WO'=>'Week Off','PH'=>'Holiday','LOP'=>'Loss of Pay','CO'=>'Comp Off','OD'=>'On Duty'] as $v=>$l): ?>
            <option value="<?= $v ?>"><?= $l ?></option>
            <?php endforeach; ?>
          </select>
        </div>
        <div class="row g-2 mb-2">
          <div class="col-6"><label class="pc-label">In Time</label>
            <input type="time" id="editInTime" class="form-control form-control-sm"></div>
          <div class="col-6"><label class="pc-label">Out Time</label>
            <input type="time" id="editOutTime" class="form-control form-control-sm"></div>
        </div>
        <div class="mb-2"><label class="pc-label">Remarks</label>
          <input type="text" id="editRemarks" class="form-control form-control-sm" placeholder="Optional"></div>
      </div>
      <div class="modal-footer py-2">
        <button type="button" class="btn btn-sm btn-secondary" data-bs-dismiss="modal">Cancel</button>
        <button type="button" class="btn btn-pc btn-sm" onclick="saveMuster()">Save</button>
      </div>
    </div>
  </div>
</div>

<?php $extraJs = "<script>
let editEmpId='', editDate='';
function openMusterEdit(empId, date, status, inTime, outTime, remarks) {
  editEmpId = empId; editDate = date;
  document.getElementById('musterEditTitle').textContent = 'Edit: ' + date;
  document.getElementById('editStatus').value   = status;
  document.getElementById('editInTime').value   = inTime;
  document.getElementById('editOutTime').value  = outTime;
  document.getElementById('editRemarks').value  = remarks;
  new bootstrap.Modal(document.getElementById('musterEditModal')).show();
}
function saveMuster() {
  pcAjax('muster.php', {
    action: 'update_day',
    employee_id: editEmpId,
    muster_date: editDate,
    status: document.getElementById('editStatus').value,
    in_time: document.getElementById('editInTime').value,
    out_time: document.getElementById('editOutTime').value,
    remarks: document.getElementById('editRemarks').value,
  }, function(res) {
    bootstrap.Modal.getInstance(document.getElementById('musterEditModal')).hide();
    showToast('Muster updated successfully', 'success');
    setTimeout(() => location.reload(), 1000);
  });
}
function lockEmployee(empId, month, year) {
  if (!confirm('Lock muster for this employee for this month?')) return;
  pcAjax('muster.php', {
    action: 'lock_muster', employee_id: empId, month: month, year: year
  }, function(res) {
    showToast('Muster locked and summary updated', 'success');
    setTimeout(() => location.reload(), 1000);
  });
}
</script>"; ?>
<?php include __DIR__ . '/../../includes/footer.php'; ?>