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

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

    if ($action === 'apply') {
        $empId  = hasRole('employee') ? $user['emp_id'] : postInt('employee_id');
        // FIX (07 Jul 2026): confirm the target employee belongs to the
        // current org before letting a manager/HR apply leave on their behalf.
        if (!hasRole('employee')) {
            $target = $db->fetchOne("SELECT company_id FROM employees WHERE id=?", [$empId]);
            if (!$target || !in_array($target['company_id'], orgCompanyIds($db))) {
                setFlash('error', 'Employee not found.');
                header('Location: index.php'); exit;
            }
        }
        $ltId   = postInt('leave_type_id');
        $from   = post('from_date');
        $to     = post('to_date');
        $isHalf = isset($_POST['is_half_day']) ? 1 : 0;
        // FIX: same start/end date (1-day leave) was counting as 2 days —
        // the +1 (inclusive range) must happen before the max(1,...) floor.
        $days   = $isHalf ? 0.5 : max(1, ((strtotime($to) - strtotime($from)) / 86400) + 1);
        $reason = post('reason');

        // Check balance
        $bal = $db->fetchOne(
            "SELECT * FROM employee_leave_balance WHERE employee_id=? AND leave_type_id=? AND year=?",
            [$empId, $ltId, date('Y')]
        );
        $available = ($bal['allocated'] ?? 0) + ($bal['carry_forward'] ?? 0) - ($bal['used'] ?? 0);
        if ($available < $days) {
            setFlash('error', "Insufficient leave balance. Available: $available days.");
        } else {
            $id = $db->insertRow('leave_applications', [
                'employee_id'   => $empId,
                'leave_type_id' => $ltId,
                'from_date'     => $from,
                'to_date'       => $to,
                'days'          => $days,
                'is_half_day'   => $isHalf,
                'reason'        => $reason,
                'status'        => 'pending',
            ]);
            auditLog('INSERT', 'leave_applications', $id);
            $applicantName = $db->fetchValue("SELECT CONCAT(first_name,' ',last_name) FROM employees WHERE id=?", [$empId]);
            notifyReportingHead($db, $empId, 'Leave Request', "$applicantName applied for $days day(s) leave.", 'leave', $id);
            notifyAllSuperadmins($db, $empId, 'Leave Request', "$applicantName applied for $days day(s) leave.", 'leave', $id);
            setFlash('success', "Leave application submitted for $days day(s).");
        }
    }

    if ($action === 'approve' || $action === 'reject') {
        requireRole('superadmin', 'admin', 'hr', 'manager', 'supervisor', 'hod', 'management');
        $appId   = postInt('app_id');
        $status  = $action === 'approve' ? 'approved' : 'rejected';
        $remarks = post('remarks');
        // FIX (07 Jul 2026): confirm this application belongs to an
        // employee in the current organization before approving/rejecting
        // it — otherwise a manager could act on another org's leave
        // applications just by guessing an id.
        $orgCompanies = orgCompanyIds($db);
        $app = $db->fetchOne(
            "SELECT la.* FROM leave_applications la JOIN employees e ON e.id=la.employee_id WHERE la.id=? AND e.company_id IN (" . implode(',', array_fill(0,count($orgCompanies),'?')) . ")",
            array_merge([$appId], $orgCompanies)
        );

        if ($app) {
            $db->execute(
                "UPDATE leave_applications SET status=?,approved_by=?,approved_at=NOW(),remarks=? WHERE id=?",
                [$status, $user['id'], $remarks, $appId]
            );
            if ($status === 'approved') {
                // Deduct from balance
                $db->execute(
                    "INSERT INTO employee_leave_balance (employee_id,leave_type_id,year,allocated,used)
                     VALUES (?,?,?,0,?) ON DUPLICATE KEY UPDATE used=used+?",
                    [$app['employee_id'], $app['leave_type_id'], date('Y'), $app['days'], $app['days']]
                );
                // Update muster
                $cur = new DateTime($app['from_date']);
                $end = new DateTime($app['to_date']);
                while ($cur <= $end) {
                    $d = $cur->format('Y-m-d');
                    $isWO = $db->fetchValue("SELECT 1 FROM muster WHERE employee_id=? AND muster_date=? AND status='WO'", [$app['employee_id'],$d]);
                    $isPH = $db->fetchValue("SELECT 1 FROM holiday_calendar WHERE holiday_date=? AND is_active=1", [$d]);
                    if (!$isWO && !$isPH) {
                        $existing = $db->fetchValue("SELECT id FROM muster WHERE employee_id=? AND muster_date=?", [$app['employee_id'],$d]);
                        $mStatus  = $app['is_half_day'] ? 'H' : 'L';
                        if ($existing) {
                            $db->execute("UPDATE muster SET status=?,leave_type_id=? WHERE employee_id=? AND muster_date=?",
                                [$mStatus, $app['leave_type_id'], $app['employee_id'], $d]);
                        } else {
                            $db->insertRow('muster', ['employee_id'=>$app['employee_id'],'muster_date'=>$d,'status'=>$mStatus,'leave_type_id'=>$app['leave_type_id']]);
                        }
                    }
                    $cur->modify('+1 day');
                }
            }
            notify($db, (int)$app['employee_id'], 'Leave ' . ucfirst($status),
                "Your leave request (" . $app['from_date'] . " to " . $app['to_date'] . ") was $status." . ($remarks ? " Remarks: $remarks" : ''),
                'leave', $appId);
            notifyAllSuperadmins($db, (int)$app['employee_id'], 'Leave ' . ucfirst($status),
                "Leave request (" . $app['from_date'] . " to " . $app['to_date'] . ") for employee #" . $app['employee_id'] . " was $status.",
                'leave', $appId);
            setFlash('success', "Leave application $status successfully.");
        }
    }

    if ($action === 'allocate') {
        requireRole('superadmin', 'admin', 'hr', 'management');
        $empId  = postInt('employee_id');
        // FIX (07 Jul 2026): confirm target employee belongs to current org.
        $target = $db->fetchOne("SELECT company_id FROM employees WHERE id=?", [$empId]);
        if (!$target || !in_array($target['company_id'], orgCompanyIds($db))) {
            setFlash('error', 'Employee not found.');
            header('Location: index.php'); exit;
        }
        $ltId   = postInt('leave_type_id');
        $alloc  = cleanFloat($_POST['allocated'] ?? 0);
        $year   = postInt('year') ?: date('Y');
        $db->execute(
            "INSERT INTO employee_leave_balance (employee_id,leave_type_id,year,allocated,used,carry_forward)
             VALUES (?,?,?,?,0,0) ON DUPLICATE KEY UPDATE allocated=?",
            [$empId,$ltId,$year,$alloc,$alloc]
        );
        setFlash('success', 'Leave balance allocated.');
    }

    header('Location: index.php'); exit;
}

// Filters
$tab    = get('tab') ?: 'pending';
$empF   = cleanInt($_GET['emp'] ?? 0);
$ltF    = cleanInt($_GET['lt']  ?? 0);
$month  = cleanInt($_GET['month'] ?? 0);

// FIX (07 Jul 2026): scope to current org — this used to show every
// organization's leave applications to any HR/manager with no filter
// at all, which is exactly the "can Org A see Org B" problem.
[$orgClause, $orgParams] = orgScopeClause($db, 'e.company_id');
$where  = [$orgClause];
$params = $orgParams;
if ($tab !== 'all') { $where[] = 'la.status=?'; $params[] = $tab === 'pending' ? 'pending' : ($tab === 'approved' ? 'approved' : 'rejected'); }
if ($empF) { $where[] = 'la.employee_id=?'; $params[] = $empF; }
if ($ltF)  { $where[] = 'la.leave_type_id=?'; $params[] = $ltF; }
if (hasRole('employee')) { $where[] = 'la.employee_id=?'; $params[] = $user['emp_id']; }
if ($month) { $where[] = 'MONTH(la.from_date)=?'; $params[] = $month; }

$applications = $db->fetchAll(
    "SELECT la.*, e.first_name, e.last_name, e.employee_id AS emp_code,
            lt.name AS leave_type_name, lt.code AS lt_code,
            CONCAT(ap.first_name,' ',ap.last_name) AS approved_by_name
       FROM leave_applications la
       JOIN employees e ON e.id=la.employee_id
       JOIN leave_types lt ON lt.id=la.leave_type_id
  LEFT JOIN employees ap ON ap.id=la.approved_by
      WHERE " . implode(' AND ', $where) . "
      ORDER BY la.created_at DESC LIMIT 100",
    $params
);

$leaveTypes = $db->fetchAll("SELECT * FROM leave_types WHERE is_active=1 ORDER BY name");
[$empOrgClause, $empOrgParams] = orgScopeClause($db, 'company_id');
$employees  = hasRole('employee') ? [] : $db->fetchAll("SELECT id,employee_id,first_name,last_name FROM employees WHERE status='active' AND $empOrgClause ORDER BY first_name", $empOrgParams);
[$cntOrgClause, $cntOrgParams] = orgScopeClause($db, 'e.company_id');
$counts = hasRole('employee')
    ? $db->fetchAll("SELECT la.status, COUNT(*) AS cnt FROM leave_applications la JOIN employees e ON e.id=la.employee_id WHERE la.employee_id=? AND $cntOrgClause GROUP BY la.status", array_merge([$user['emp_id']], $cntOrgParams))
    : $db->fetchAll("SELECT la.status, COUNT(*) AS cnt FROM leave_applications la JOIN employees e ON e.id=la.employee_id WHERE $cntOrgClause GROUP BY la.status", $cntOrgParams);
$cntMap     = array_column($counts, 'cnt', 'status');

// Leave balance for current employee or all
$balances = $db->fetchAll(
    "SELECT lb.*, lt.name AS lt_name, lt.code AS lt_code
       FROM employee_leave_balance lb
       JOIN leave_types lt ON lt.id=lb.leave_type_id
      WHERE lb.employee_id=? AND lb.year=?
      ORDER BY lt.name",
    [$user['emp_id'] ?? 0, date('Y')]
);

$headerActions = '<button class="btn btn-pc btn-sm" data-bs-toggle="modal" data-bs-target="#applyModal">
  <i class="ti ti-plus me-1"></i>Apply Leave
</button>';
if (hasRole('superadmin','admin','hr','management')) {
    $headerActions .= ' <button class="btn btn-sm btn-outline-secondary" data-bs-toggle="modal" data-bs-target="#allocateModal">
      <i class="ti ti-calendar-plus me-1"></i>Allocate Balance
    </button>
    <a href="' . BASE_URL . '/modules/leave/bulk_balance.php" class="btn btn-sm btn-outline-secondary">
      <i class="ti ti-file-upload me-1"></i>Bulk Upload Balance
    </a>';
}
include __DIR__ . '/../../includes/header.php';
?>

<!-- Leave Balance Cards -->
<?php if ($balances): ?>
<div class="row g-2 mb-3">
  <?php foreach ($balances as $b):
    $avail = $b['allocated'] + $b['carry_forward'] - $b['used'];
    $pct   = $b['allocated'] > 0 ? round($avail / $b['allocated'] * 100) : 0;
  ?>
  <div class="col-md-2 col-sm-4">
    <div class="pc-card text-center py-3">
      <div class="fw-bold text-uppercase small text-muted mb-1"><?= clean($b['lt_code']) ?></div>
      <div style="font-size:28px;font-weight:700;color:var(--pc-brand)"><?= $avail ?></div>
      <div class="small text-muted">of <?= $b['allocated'] ?></div>
      <div class="pc-progress mt-2"><div class="pc-progress-fill" style="width:<?= $pct ?>%"></div></div>
      <div style="font-size:10px;color:var(--pc-text2);margin-top:4px"><?= clean($b['lt_name']) ?></div>
    </div>
  </div>
  <?php endforeach; ?>
</div>
<?php endif; ?>

<!-- Tabs -->
<div class="d-flex gap-0 border-bottom mb-3">
  <?php foreach (['pending'=>'Pending','approved'=>'Approved','rejected'=>'Rejected','all'=>'All'] as $k=>$lbl): ?>
  <a href="?tab=<?= $k ?>" class="pc-tab <?= $tab===$k?'active':'' ?>">
    <?= $lbl ?>
    <?php if (isset($cntMap[$k])): ?><span class="badge bg-<?= $k==='pending'?'warning':($k==='approved'?'success':'secondary') ?> ms-1 text-dark"><?= $cntMap[$k] ?></span><?php endif; ?>
  </a>
  <?php endforeach; ?>
</div>

<!-- Filters -->
<?php if (!hasRole('employee')): ?>
<div class="pc-card mb-3">
  <form method="GET" class="pc-filters">
    <input type="hidden" name="tab" value="<?= $tab ?>">
    <select name="emp" class="form-select form-select-sm" style="width:200px">
      <option value="">All Employees</option>
      <?php foreach ($employees as $e): ?>
      <option value="<?= $e['id'] ?>" <?= $empF==$e['id']?'selected':'' ?>><?= clean($e['first_name'].' '.$e['last_name']) ?> (<?= $e['employee_id'] ?>)</option>
      <?php endforeach; ?>
    </select>
    <select name="lt" class="form-select form-select-sm" style="width:160px">
      <option value="">All Leave Types</option>
      <?php foreach ($leaveTypes as $lt): ?>
      <option value="<?= $lt['id'] ?>" <?= $ltF==$lt['id']?'selected':'' ?>><?= clean($lt['name']) ?></option>
      <?php endforeach; ?>
    </select>
    <select name="month" class="form-select form-select-sm" style="width:130px">
      <option value="">All Months</option>
      <?php for ($m=1;$m<=12;$m++): ?>
      <option value="<?= $m ?>" <?= $month==$m?'selected':'' ?>><?= monthName($m) ?></option>
      <?php endfor; ?>
    </select>
    <button class="btn btn-pc btn-sm">Filter</button>
    <a href="?tab=<?= $tab ?>" class="btn btn-sm btn-outline-secondary">Reset</a>
  </form>
</div>
<?php endif; ?>

<!-- Applications Table -->
<div class="pc-card">
  <div class="pc-table-wrap">
    <table class="pc-table">
      <thead>
        <tr>
          <th>Employee</th><th>Leave Type</th><th>From</th><th>To</th>
          <th>Days</th><th>Reason</th><th>Applied On</th><th>Status</th>
          <?php if (hasRole('superadmin','admin','hr','manager','supervisor','hod','management')): ?><th>Actions</th><?php endif; ?>
        </tr>
      </thead>
      <tbody>
      <?php foreach ($applications as $a): ?>
      <tr>
        <td>
          <div class="fw-semibold"><?= clean($a['first_name'].' '.$a['last_name']) ?></div>
          <div style="font-size:10px;color:var(--pc-text2)"><?= clean($a['emp_code']) ?></div>
        </td>
        <td><span class="badge bg-info"><?= clean($a['lt_code']) ?></span><br><small><?= clean($a['leave_type_name']) ?></small></td>
        <td><?= fmtDate($a['from_date']) ?></td>
        <td><?= fmtDate($a['to_date']) ?></td>
        <td class="fw-semibold"><?= $a['days'] ?><?= $a['is_half_day']?' (Half)':'' ?></td>
        <td style="max-width:150px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap"><?= clean($a['reason']) ?></td>
        <td><?= fmtDate($a['created_at']) ?></td>
        <td><?= statusBadge($a['status']) ?>
          <?php if ($a['approved_by_name']): ?>
          <div style="font-size:10px;color:var(--pc-text2)">by <?= clean($a['approved_by_name']) ?></div>
          <?php endif; ?>
        </td>
        <?php if (hasRole('superadmin','admin','hr','manager','supervisor','hod','management')): ?>
        <td>
          <?php if ($a['status'] === 'pending'): ?>
          <button class="btn btn-sm btn-success" onclick="approveLeave(<?= $a['id'] ?>,'approve')" title="Approve"><i class="ti ti-check"></i></button>
          <button class="btn btn-sm btn-danger"  onclick="approveLeave(<?= $a['id'] ?>,'reject')"  title="Reject"><i class="ti ti-x"></i></button>
          <?php else: ?>
          <span class="small text-muted"><?= ucfirst($a['status']) ?></span>
          <?php endif; ?>
        </td>
        <?php endif; ?>
      </tr>
      <?php endforeach; ?>
      <?php if (!$applications): ?>
      <tr><td colspan="9" class="text-center py-4 text-muted">No leave applications found</td></tr>
      <?php endif; ?>
      </tbody>
    </table>
  </div>
</div>

<!-- Apply Leave Modal -->
<div class="modal fade" id="applyModal" tabindex="-1">
  <div class="modal-dialog">
    <div class="modal-content">
      <div class="modal-header"><h6 class="modal-title">Apply Leave</h6><button type="button" class="btn-close" data-bs-dismiss="modal"></button></div>
      <form method="POST">
        <?= csrfField() ?>
        <input type="hidden" name="action" value="apply">
        <div class="modal-body row g-3">
          <?php if (!hasRole('employee')): ?>
          <div class="col-12">
            <label class="pc-label">Employee *</label>
            <select name="employee_id" class="form-select form-select-sm" required>
              <option value="">Select Employee</option>
              <?php foreach ($employees as $e): ?>
              <option value="<?= $e['id'] ?>"><?= clean($e['first_name'].' '.$e['last_name'].' ('.$e['employee_id'].')') ?></option>
              <?php endforeach; ?>
            </select>
          </div>
          <?php endif; ?>
          <div class="col-12">
            <label class="pc-label">Leave Type *</label>
            <select name="leave_type_id" class="form-select form-select-sm" required>
              <option value="">Select</option>
              <?php foreach ($leaveTypes as $lt): ?>
              <option value="<?= $lt['id'] ?>"><?= clean($lt['name']) ?> (<?= $lt['code'] ?>)</option>
              <?php endforeach; ?>
            </select>
          </div>
          <div class="col-6">
            <label class="pc-label">From Date *</label>
            <input type="date" name="from_date" class="form-control form-control-sm" required>
          </div>
          <div class="col-6">
            <label class="pc-label">To Date *</label>
            <input type="date" name="to_date" class="form-control form-control-sm" required>
          </div>
          <div class="col-12">
            <div class="form-check">
              <input class="form-check-input" type="checkbox" name="is_half_day" id="halfDay">
              <label class="form-check-label small" for="halfDay">Half Day</label>
            </div>
          </div>
          <div class="col-12">
            <label class="pc-label">Reason *</label>
            <textarea name="reason" class="form-control form-control-sm" rows="3" required></textarea>
          </div>
        </div>
        <div class="modal-footer">
          <button type="button" class="btn btn-sm btn-secondary" data-bs-dismiss="modal">Cancel</button>
          <button type="submit" class="btn btn-pc btn-sm">Submit Application</button>
        </div>
      </form>
    </div>
  </div>
</div>

<!-- Approve/Reject Modal -->
<div class="modal fade" id="actionModal" tabindex="-1">
  <div class="modal-dialog modal-sm">
    <div class="modal-content">
      <div class="modal-header"><h6 class="modal-title" id="actionModalTitle">Action</h6><button type="button" class="btn-close" data-bs-dismiss="modal"></button></div>
      <form method="POST">
        <?= csrfField() ?>
        <input type="hidden" name="action" id="actionType">
        <input type="hidden" name="app_id" id="actionAppId">
        <div class="modal-body">
          <label class="pc-label">Remarks</label>
          <textarea name="remarks" class="form-control form-control-sm" rows="3" placeholder="Optional remarks..."></textarea>
        </div>
        <div class="modal-footer">
          <button type="button" class="btn btn-sm btn-secondary" data-bs-dismiss="modal">Cancel</button>
          <button type="submit" class="btn btn-sm" id="actionSubmitBtn">Confirm</button>
        </div>
      </form>
    </div>
  </div>
</div>

<!-- Allocate Balance Modal -->
<?php if (hasRole('superadmin','admin','hr','management')): ?>
<div class="modal fade" id="allocateModal" tabindex="-1">
  <div class="modal-dialog">
    <div class="modal-content">
      <div class="modal-header"><h6 class="modal-title">Allocate Leave Balance</h6><button type="button" class="btn-close" data-bs-dismiss="modal"></button></div>
      <form method="POST">
        <?= csrfField() ?>
        <input type="hidden" name="action" value="allocate">
        <div class="modal-body row g-3">
          <div class="col-12">
            <label class="pc-label">Employee *</label>
            <select name="employee_id" class="form-select form-select-sm" required>
              <option value="">Select Employee</option>
              <?php foreach ($employees as $e): ?>
              <option value="<?= $e['id'] ?>"><?= clean($e['first_name'].' '.$e['last_name'].' ('.$e['employee_id'].')') ?></option>
              <?php endforeach; ?>
            </select>
          </div>
          <div class="col-6">
            <label class="pc-label">Leave Type *</label>
            <select name="leave_type_id" class="form-select form-select-sm" required>
              <?php foreach ($leaveTypes as $lt): ?>
              <option value="<?= $lt['id'] ?>"><?= clean($lt['name']) ?></option>
              <?php endforeach; ?>
            </select>
          </div>
          <div class="col-3">
            <label class="pc-label">Days *</label>
            <input type="number" name="allocated" class="form-control form-control-sm" min="0" step="0.5" required>
          </div>
          <div class="col-3">
            <label class="pc-label">Year</label>
            <input type="number" name="year" class="form-control form-control-sm" value="<?= date('Y') ?>">
          </div>
        </div>
        <div class="modal-footer">
          <button type="button" class="btn btn-sm btn-secondary" data-bs-dismiss="modal">Cancel</button>
          <button type="submit" class="btn btn-pc btn-sm">Allocate</button>
        </div>
      </form>
    </div>
  </div>
</div>
<?php endif; ?>

<?php $extraJs = "<script>
function approveLeave(id, action) {
  document.getElementById('actionType').value   = action;
  document.getElementById('actionAppId').value  = id;
  document.getElementById('actionModalTitle').textContent = action === 'approve' ? 'Approve Leave' : 'Reject Leave';
  const btn = document.getElementById('actionSubmitBtn');
  btn.textContent = action === 'approve' ? 'Approve' : 'Reject';
  btn.className = 'btn btn-sm ' + (action === 'approve' ? 'btn-success' : 'btn-danger');
  new bootstrap.Modal(document.getElementById('actionModal')).show();
}
</script>"; ?>
<?php include __DIR__ . '/../../includes/footer.php'; ?>