<?php
require_once __DIR__ . "/../../config/config.php";
require_once __DIR__ . "/../../includes/functions.php";
startSession(); requireLogin();
$db = Database::getInstance();
$page = "My Leaves";
$user = currentUser();
$empId = $user["emp_id"];

if ($_SERVER["REQUEST_METHOD"] === "POST") {
    verifyCsrf();
    $action = $_POST["action"] ?? "";
    if ($action === "apply") {
        $ltId = postInt("leave_type_id");
        $from = post("from_date"); $to = post("to_date");
        $days = (strtotime($to) - strtotime($from)) / 86400 + 1;
        // Check balance — no longer BLOCKS the application if it's short;
        // the days beyond balance simply become LOP once a manager
        // approves it (see applyLeaveApprovalDeduction() in functions.php).
        // This matters for monthly-lapsing leave types where an
        // employee's real balance legitimately varies month to month.
        $bal = $db->fetchOne("SELECT * FROM employee_leave_balance WHERE employee_id=? AND leave_type_id=? AND year=YEAR(NOW())",[$empId,$ltId]);
        $avail = ($bal["allocated"]??0) - ($bal["used"]??0) + ($bal["carry_forward"]??0);
        $db->execute("INSERT INTO leave_applications (employee_id,leave_type_id,from_date,to_date,days,reason,status) VALUES (?,?,?,?,?,?,'pending')",
            [$empId,$ltId,$from,$to,$days,post("reason")]);
        if ($days > $avail) {
            setFlash("success","Leave application submitted for $days day(s). Note: only $avail day(s) are in your balance — " . ($days-$avail) . " day(s) beyond that will be marked LOP if approved.");
        } else {
            setFlash("success","Leave application submitted for $days day(s).");
        }
    } elseif ($action === "cancel") {
        $db->execute("UPDATE leave_applications SET status='cancelled' WHERE id=? AND employee_id=? AND status='pending'",[postInt("id"),$empId]);
        setFlash("success","Leave cancelled.");
    } elseif ($action === "approve") {
        // FIX (07 Jul 2026): this action had NO role check at all — any
        // logged-in employee could approve/reject ANY leave application,
        // for anyone, in any organization, just by knowing this endpoint.
        requireRole('superadmin','admin','hr','manager','supervisor','hod','management');
        $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([postInt("id")], $orgCompanies)
        );
        if($app) {
            $db->execute("UPDATE leave_applications SET status='approved',approved_by=? WHERE id=?",[currentUser()["id"],$app["id"]]);
            $result = applyLeaveApprovalDeduction($db, $app["employee_id"], $app["leave_type_id"], (float)$app["days"], $app["to_date"]);
            $msg = "Leave approved.";
            if ($result['lop'] > 0) $msg .= " ({$result['deducted']} day(s) from balance, {$result['lop']} day(s) marked LOP.)";
            setFlash("success",$msg);
        } else {
            setFlash("error","Application not found.");
        }
    } elseif ($action === "reject") {
        // FIX: same missing role/org check as approve, above.
        requireRole('superadmin','admin','hr','manager','supervisor','hod','management');
        $orgCompanies = orgCompanyIds($db);
        $app = $db->fetchOne(
            "SELECT la.id 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([postInt("id")], $orgCompanies)
        );
        if ($app) {
            $db->execute("UPDATE leave_applications SET status='rejected',rejection_reason=? WHERE id=?",[post("reason"),postInt("id")]);
            setFlash("success","Leave rejected.");
        } else {
            setFlash("error","Application not found.");
        }
    }
    header("Location: ".BASE_URL."/modules/leave/my_leaves.php"); exit;
}

$year      = intval($_GET["year"] ?? date("Y"));
try {
    $leaveTypes = $db->fetchAll(
        "SELECT lt.*, lb.allocated, lb.used, lb.carry_forward,
                clp.accrual_period, clp.carry_forward AS policy_carry_forward, clp.encashable AS policy_encashable
           FROM leave_types lt
           LEFT JOIN employee_leave_balance lb ON lb.leave_type_id=lt.id AND lb.employee_id=? AND lb.year=?
           LEFT JOIN company_leave_policy clp ON clp.leave_type_id=lt.id AND clp.company_id=? AND clp.is_active=1
          WHERE lt.is_active=1",
        [$empId?:0, $year, companyId()]
    );
} catch (Throwable $e) {
    // migration_company_leave_policy.sql not run yet — fall back to the
    // plain query (every type just shows as a normal yearly balance).
    $leaveTypes = $db->fetchAll("SELECT lt.*,lb.allocated,lb.used,lb.carry_forward FROM leave_types lt LEFT JOIN employee_leave_balance lb ON lb.leave_type_id=lt.id AND lb.employee_id=? AND lb.year=? WHERE lt.is_active=1",[$empId?:0,$year]);
}
// FIX (07 Jul 2026): scope to current org — this used to list every
// organization's leave applications to anyone who loaded this page.
[$orgClause, $orgParams] = orgScopeClause($db, 'e.company_id');
$allApps   = $db->fetchAll("SELECT la.*,lt.name AS leave_name,lt.code,CONCAT(e.first_name,' ',e.last_name) AS emp_name,e.employee_id AS emp_code FROM leave_applications la JOIN leave_types lt ON lt.id=la.leave_type_id JOIN employees e ON e.id=la.employee_id WHERE $orgClause ORDER BY la.created_at DESC LIMIT 50", $orgParams);
$myApps    = $empId ? array_filter($allApps, fn($a)=>$a["employee_id"]==$empId) : [];
[$empOrgClause, $empOrgParams] = orgScopeClause($db, 'company_id');
$employees = $db->fetchAll("SELECT id,CONCAT(employee_id,' - ',first_name,' ',last_name) AS label FROM employees WHERE status='active' AND $empOrgClause ORDER BY first_name", $empOrgParams);

include __DIR__ . "/../../includes/header.php";
?>
<!-- Leave balance cards -->
<div class="row g-3 mb-3">
  <?php foreach($leaveTypes as $lt):
    $bal = ($lt["allocated"]??0) - ($lt["used"]??0) + ($lt["carry_forward"]??0);
    $pct = ($lt["allocated"]??0) > 0 ? round(($bal/($lt["allocated"]??1))*100) : 0;
  ?>
  <div class="col-md-3 col-6">
    <div class="pc-stat">
      <div class="d-flex justify-content-between mb-1">
        <span class="fw-bold" style="font-size:12.5px"><?=clean($lt["name"])?></span>
        <code style="font-size:10px"><?=clean($lt["code"])?></code>
      </div>
      <?php if (($lt['accrual_period'] ?? 'yearly') === 'monthly'):
        if ($lt['policy_carry_forward'] ?? false) {
            $tagText = 'THIS MONTH — unused carries forward'; $tagClass = 'bg-info-subtle text-info-emphasis';
        } elseif ($lt['policy_encashable'] ?? false) {
            $tagText = 'THIS MONTH — unused is encashed'; $tagClass = 'bg-success-subtle text-success-emphasis';
        } else {
            $tagText = 'THIS MONTH ONLY — unused lapses'; $tagClass = 'bg-warning-subtle text-warning-emphasis';
        }
      ?>
        <span class="badge <?=$tagClass?>" style="font-size:9px"><?=$tagText?></span>
      <?php endif; ?>
      <div class="pc-stat-val" style="font-size:22px"><?=$bal?></div>
      <div class="pc-stat-label">Available / <?=$lt["allocated"]?> allocated</div>
      <div class="pc-progress mt-2"><div class="pc-progress-fill" style="width:<?=$pct?>%"></div></div>
      <div class="d-flex justify-content-between mt-1" style="font-size:10px;color:var(--pc-text3)"><span>Used: <?=$lt["used"]??0?></span><span>CF: <?=$lt["carry_forward"]??0?></span></div>
    </div>
  </div>
  <?php endforeach; ?>
</div>

<div class="row g-3">
  <div class="col-md-4">
    <div class="pc-card">
      <div class="pc-card-title"><i class="ti ti-beach me-2"></i>Apply for Leave</div>
      <form method="POST">
        <?=csrfField()?><input type="hidden" name="action" value="apply">
        <?php if(!$empId): ?><div class="mb-2"><label class="pc-label">Employee</label><input type="hidden" name="employee_id" value="0"></div><?php endif; ?>
        <div class="mb-2"><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):
              $avail=($lt["allocated"]??0)-($lt["used"]??0)+($lt["carry_forward"]??0); ?>
            <option value="<?=$lt["id"]?>" <?=$avail<=0?"disabled":""?>><?=clean($lt["name"])?> (<?=$avail?> days left)</option>
            <?php endforeach; ?>
          </select></div>
        <div class="row g-2 mb-2">
          <div class="col"><label class="pc-label">From Date</label><input type="date" name="from_date" class="form-control form-control-sm" required></div>
          <div class="col"><label class="pc-label">To Date</label><input type="date" name="to_date" class="form-control form-control-sm" required></div>
        </div>
        <div class="mb-3"><label class="pc-label">Reason</label><textarea name="reason" class="form-control form-control-sm" rows="2" required></textarea></div>
        <button class="btn btn-pc btn-sm w-100"><i class="ti ti-send me-1"></i>Submit Application</button>
      </form>
    </div>
  </div>
  <div class="col-md-8">
    <div class="pc-card">
      <div class="pc-card-title"><i class="ti ti-list me-2"></i>All Leave Applications</div>
      <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>Status</th><th>Action</th></tr></thead>
          <tbody>
          <?php foreach($allApps as $a): ?>
          <tr>
            <td><div class="fw-semibold"><?=clean($a["emp_name"])?></div><small class="text-muted"><?=clean($a["emp_code"])?></small></td>
            <td><span class="badge" style="background:var(--pc-brand-light);color:var(--pc-brand)"><?=clean($a["code"])?></span></td>
            <td><?=fmtDate($a["from_date"])?></td>
            <td><?=fmtDate($a["to_date"])?></td>
            <td class="fw-bold"><?=$a["days"]?></td>
            <td><?=clean(substr($a["reason"],0,30))?><?=strlen($a["reason"])>30?"...":""?></td>
            <td><?=statusBadge($a["status"])?></td>
            <td>
              <?php if($a["status"]==="pending"): ?>
              <form method="POST" class="d-inline"><?=csrfField()?><input type="hidden" name="action" value="approve"><input type="hidden" name="id" value="<?=$a["id"]?>"><button class="btn btn-xs btn-success py-0 px-1">Approve</button></form>
              <form method="POST" class="d-inline"><?=csrfField()?><input type="hidden" name="action" value="reject"><input type="hidden" name="id" value="<?=$a["id"]?>"><input type="hidden" name="reason" value="Rejected by HR"><button class="btn btn-xs btn-danger py-0 px-1">Reject</button></form>
              <?php if($a["employee_id"]==$empId): ?>
              <form method="POST" class="d-inline"><?=csrfField()?><input type="hidden" name="action" value="cancel"><input type="hidden" name="id" value="<?=$a["id"]?>"><button class="btn btn-xs btn-outline-secondary py-0 px-1">Cancel</button></form>
              <?php endif; ?>
              <?php else: ?>—<?php endif; ?>
            </td>
          </tr>
          <?php endforeach; if(!$allApps): ?><tr><td colspan="8" class="text-center text-muted py-3">No applications</td></tr><?php endif; ?>
          </tbody>
        </table>
      </div>
    </div>
  </div>
</div>
<?php include __DIR__ . "/../../includes/footer.php"; ?>