<?php
error_reporting(E_ALL);
ini_set('display_errors', 1);

require '../config.php';

// Prevent duplicate session initialization errors
if (session_status() === PHP_SESSION_NONE && !headers_sent()) {
    session_start();
    session_write_close();
}

if (!isset($_SESSION['user_id'])) {
    header("Location: ../login.php");
    exit;
}

$userId = intval($_SESSION['user_id']);
$userRole = strtolower($_SESSION['role'] ?? '');

/*
|--------------------------------------------------------------------------
| 1. RESOLVE INITIAL SESSION CONTEXT
|--------------------------------------------------------------------------
*/
$currentEmployeeId = 0;
$currentEmployeeDept = 0;

$stmt = $conn->prepare("
    SELECT id, department_id 
    FROM employees 
    WHERE user_id = ? 
    LIMIT 1
");
$stmt->bind_param("i", $userId);
$stmt->execute();
$res = $stmt->get_result();

if ($row = $res->fetch_assoc()) {
    $currentEmployeeId = intval($row['id']);
    $currentEmployeeDept = intval($row['department_id']); 
}
$stmt->close();

// Load leave type structures
$leaveTypes = [];
$res = $conn->query("SELECT * FROM leave_types ORDER BY name");
if ($res) {
    while ($row = $res->fetch_assoc()) {
        $leaveTypes[$row['id']] = $row;
    }
}

/*
|--------------------------------------------------------------------------
| 2. INTERCEPT DATA PROCESSORS (POST Routing Layer)
|--------------------------------------------------------------------------
*/
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['action']) && $_POST['action'] === 'submit_leave') {

    // HR/Admin Overriding check: Check if administrative roles are filing on behalf of another employee
    $isAdminPrivileged = in_array($userRole, ['hr', 'admin', 'superadmin']);
    $targetEmployeeId = ($isAdminPrivileged && !empty($_POST['override_employee_id'])) ? intval($_POST['override_employee_id']) : $currentEmployeeId;

    if ($targetEmployeeId <= 0) {
        header("Location: index.php?err=" . urlencode("Context Error: Your user account is not linked to an entry in the employees profile table."));
        exit;
    }

    $leaveTypeId = intval($_POST['leave_type_id']);
    $startDate   = $_POST['start_date'];
    $endDate     = $_POST['end_date'];
    $reason      = trim($_POST['reason']);

    // Mathematical calculations for day differences
    $startTs = strtotime($startDate);
    $endTs = strtotime($endDate);

    if (!$startTs || !$endTs) {
        header("Location: index.php?err=" . urlencode("Invalid dates provided."));
        exit;
    }

    if ($endTs < $startTs) {
        header("Location: index.php?err=" . urlencode("Timeline Error: End date cannot be before start date."));
        exit;
    }

    // Safety measure: block submission of historical timelines by normal staff members
    if (!$isAdminPrivileged && $endTs < strtotime(date('Y-m-d'))) {
        header("Location: index.php?err=" . urlencode("Timeline Error: You cannot submit a leave request that has already passed."));
        exit;
    }

    // Calculate inclusive timeline days
    $days = max(1, round(($endTs - $startTs) / 86400) + 1);

    // Dynamic Database Column Insertion Safety Layer
    $allTableColumns = [];
    $columnQuery = $conn->query("SHOW COLUMNS FROM leave_requests");
    if ($columnQuery) {
        while ($cRow = $columnQuery->fetch_assoc()) {
            $allTableColumns[] = strtolower($cRow['Field']);
        }
    }

    // Base query structure elements
    $insertFields = ['employee_id', 'leave_type_id', 'start_date', 'end_date', 'total_days', 'reason'];
    $bindTypes = "iissis";
    $bindValues = [$targetEmployeeId, $leaveTypeId, $startDate, $endDate, $days, $reason];

    // Dynamic stage approval mapping columns safety check
    $statusTrackerFields = ['status', 'manager_status', 'hr_status', 'opm_status', 'gm_status', 'director_status'];
    foreach ($statusTrackerFields as $stf) {
        if (in_array($stf, $allTableColumns)) {
            $insertFields[] = "`$stf`";
            $bindTypes .= "s";
            $bindValues[] = 'Pending';
        }
    }

    $fieldList = implode(', ', $insertFields);
    $placeholders = implode(', ', array_fill(0, count($insertFields), '?'));
    $sql = "INSERT INTO leave_requests ({$fieldList}) VALUES ({$placeholders})";

    $stmt = $conn->prepare($sql);
    if (!$stmt) {
        header("Location: index.php?err=" . urlencode("Preparation Error: " . $conn->error));
        exit;
    }

    // Bind parameters dynamically using references to keep strict compatibility with call_user_func_array
    $bindParams = array_merge([$bindTypes], $bindValues);
    $refs = [];
    foreach ($bindParams as $key => $value) {
        $refs[$key] = &$bindParams[$key];
    }
    call_user_func_array([$stmt, 'bind_param'], $refs);

    if ($stmt->execute()) {
        $stmt->close();
        header("Location: index.php?success=" . urlencode("Leave application successfully committed to system log records."));
        exit;
    } else {
        $errorMsg = $stmt->error;
        $stmt->close();
        header("Location: index.php?err=" . urlencode("Execution Failure: " . $errorMsg));
        exit;
    }
}

/*
|--------------------------------------------------------------------------
| 3. GLOBAL DIRECTORIES (For dropdown selectors in Admin/HR mode)
|--------------------------------------------------------------------------
*/
$globalEmployees = [];
if (in_array($userRole, ['hr', 'admin', 'superadmin'])) {
    $empRes = $conn->query("SELECT id, name FROM employees ORDER BY name ASC");
    while ($empRes && $row = $empRes->fetch_assoc()) {
        $globalEmployees[] = $row;
    }
}

/*
|--------------------------------------------------------------------------
| 4. DATA COMPILATION PIPELINE
|--------------------------------------------------------------------------
*/
$requests = [];

// Superadmin, Admin, and HR possess global scope over all records
if (in_array($userRole, ['superadmin', 'admin', 'hr'])) {
    $stmt = $conn->prepare("
        SELECT lr.*, lt.name AS leave_type, e.name AS employee_name, e.email
        FROM leave_requests lr
        LEFT JOIN leave_types lt ON lt.id = lr.leave_type_id
        LEFT JOIN employees e ON e.id = lr.employee_id
        ORDER BY lr.start_date ASC
    ");
} elseif ($userRole === 'manager') {
    $stmt = $conn->prepare("
        SELECT lr.*, lt.name AS leave_type, e.name AS employee_name, e.email
        FROM leave_requests lr
        LEFT JOIN leave_types lt ON lt.id = lr.leave_type_id
        LEFT JOIN employees e ON e.id = lr.employee_id
        WHERE e.department_id = ?
        ORDER BY lr.start_date ASC
    ");
    if ($stmt) { $stmt->bind_param("i", $currentEmployeeDept); }
} else {
    // Default fallback to standard Staff role
    $stmt = $conn->prepare("
        SELECT lr.*, lt.name AS leave_type, e.name AS employee_name, e.email
        FROM leave_requests lr
        LEFT JOIN leave_types lt ON lt.id = lr.leave_type_id
        LEFT JOIN employees e ON e.id = lr.employee_id
        WHERE lr.employee_id = ?
        ORDER BY lr.start_date ASC
    ");
    if ($stmt) { $stmt->bind_param("i", $currentEmployeeId); }
}

if ($stmt) {
    $stmt->execute();
    $res = $stmt->get_result();
    while ($row = $res->fetch_assoc()) {
        $requests[] = $row;
    }
    $stmt->close();
}

/*
|--------------------------------------------------------------------------
| 5. LOGIC MOVED FROM DASHBOARD (Calendar & Configuration Logic)
|--------------------------------------------------------------------------
*/
$currentMonth = isset($_GET['month']) ? intval($_GET['month']) : intval(date('m'));
$currentYear = isset($_GET['year']) ? intval($_GET['year']) : intval(date('Y'));
$startDay = isset($_GET['start_day']) ? intval($_GET['start_day']) : 1;

$baseTimestamp = mktime(0, 0, 0, $currentMonth, $startDay, $currentYear);
$monthLabel = date('F Y', $baseTimestamp);

$timelineDates = [];
for ($i = 0; $i < 7; $i++) {
    $loopTime = strtotime("+$i days", $baseTimestamp);
    $timelineDates[] = [
        'date_string' => date('Y-m-d', $loopTime),
        'day_num'      => date('d', $loopTime),
        'day_name'     => date('D', $loopTime),
        'is_today'     => (date('Y-m-d', $loopTime) === date('Y-m-d'))
    ];
}

$prevWeekTimestamp = strtotime("-7 days", $baseTimestamp);
$nextWeekTimestamp = strtotime("+7 days", $baseTimestamp);

$prevQuery = sprintf("month=%d&year=%d&start_day=%d", date('m', $prevWeekTimestamp), date('Y', $prevWeekTimestamp), date('d', $prevWeekTimestamp));
$nextQuery = sprintf("month=%d&year=%d&start_day=%d", date('m', $nextWeekTimestamp), date('Y', $nextWeekTimestamp), date('d', $nextWeekTimestamp));

// Leave Type Color Schemes Matrix
$colorMap = [
    'annual leave'      => ['bg' => 'bg-emerald-50 border-emerald-300 text-emerald-900', 'dot' => 'bg-emerald-500'],
    'annual'            => ['bg' => 'bg-emerald-50 border-emerald-300 text-emerald-900', 'dot' => 'bg-emerald-500'],
    'sick leave'        => ['bg' => 'bg-rose-50 border-rose-300 text-rose-900', 'dot' => 'bg-rose-500'],
    'sick'              => ['bg' => 'bg-rose-50 border-rose-300 text-rose-900', 'dot' => 'bg-rose-500'],
    'emergency leave'   => ['bg' => 'bg-amber-50 border-amber-300 text-amber-900', 'dot' => 'bg-amber-500'],
    'emergency'         => ['bg' => 'bg-amber-50 border-amber-300 text-amber-900', 'dot' => 'bg-amber-500'],
    'compensatory leave'=> ['bg' => 'bg-cyan-50 border-cyan-300 text-cyan-900', 'dot' => 'bg-cyan-500'],
    'compensatory'      => ['bg' => 'bg-cyan-50 border-cyan-300 text-cyan-900', 'dot' => 'bg-cyan-500'],
    'personal leave'    => ['bg' => 'bg-lime-50 border-lime-300 text-lime-900', 'dot' => 'bg-lime-500'],
    'personal'          => ['bg' => 'bg-lime-50 border-lime-300 text-lime-900', 'dot' => 'bg-lime-500'],
    'marriage leave'    => ['bg' => 'bg-orange-50 border-orange-300 text-orange-900', 'dot' => 'bg-orange-500'],
    'marriage'          => ['bg' => 'bg-orange-50 border-orange-300 text-orange-900', 'dot' => 'bg-orange-500'],
    'maternity leave'   => ['bg' => 'bg-pink-50 border-pink-300 text-pink-900', 'dot' => 'bg-pink-500'],
    'maternity'         => ['bg' => 'bg-pink-50 border-pink-300 text-pink-900', 'dot' => 'bg-pink-500'],
    'paternity leave'   => ['bg' => 'bg-blue-50 border-blue-300 text-blue-900', 'dot' => 'bg-blue-500'],
    'paternity'         => ['bg' => 'bg-blue-50 border-blue-300 text-blue-900', 'dot' => 'bg-blue-500'],
    'bereavement leave' => ['bg' => 'bg-slate-100 border-slate-300 text-slate-900', 'dot' => 'bg-slate-500'],
    'bereavement'       => ['bg' => 'bg-slate-100 border-slate-300 text-slate-900', 'dot' => 'bg-slate-500'],
    'study leave'       => ['bg' => 'bg-purple-50 border-purple-300 text-purple-900', 'dot' => 'bg-purple-500'],
    'study'             => ['bg' => 'bg-purple-50 border-purple-300 text-purple-900', 'dot' => 'bg-purple-500'],
];
$defaultColor = ['bg' => 'bg-indigo-50 border-indigo-200 text-indigo-950', 'dot' => 'bg-indigo-500'];

// Resolve Active Approval Workflow Stages
$activeWorkflowStages = [];
$stageRes = $conn->query("SELECT DISTINCT checking_column, stage_name FROM leave_approval_stages ORDER BY stage_order ASC");
if ($stageRes) {
    while ($sRow = $stageRes->fetch_assoc()) {
        $activeWorkflowStages[$sRow['checking_column']] = $sRow['stage_name'];
    }
}
if (empty($activeWorkflowStages)) {
    $activeWorkflowStages = ['manager_status' => 'Manager', 'hr_status' => 'HR'];
}

// Group Requests by Employee
$groupedRequests = [];
foreach ($requests as $req) {
    $empName = $req['employee_name'] ?? 'Unknown Employee';
    if (!isset($groupedRequests[$empName])) {
        $groupedRequests[$empName] = [];
    }
    $groupedRequests[$empName][] = $req;
}

$username = $_SESSION['username'] ?? 'Staff User';
$role = $_SESSION['role'] ?? 'Staff';

if (empty($groupedRequests) && isset($_SESSION['user_id'])) {
    $currentName = $_SESSION['name'] ?? $username;
    $groupedRequests[$currentName] = [];
}