<?php
require_once '../includes/auth.php';
require_once '../includes/db.php';

header('Content-Type: application/json');

if (!isLoggedIn()) {
    echo json_encode(['success' => false, 'message' => 'Unauthorized']);
    exit;
}

if (!isModuleEnabled('attendance')) {
    echo json_encode(['success' => false, 'message' => 'Attendance module is disabled']);
    exit;
}

$data = json_decode(file_get_contents('php://input'), true);
$action = $_POST['action'] ?? $data['action'] ?? $_GET['action'] ?? '';

$company_id = $_SESSION['company_id'];
$user_id = $_SESSION['user_id'];

// Helper to get employee ID from user ID
function getEmployeeId($userId, $companyId) {
    $emp = fetch("SELECT id FROM employees WHERE user_id = ? AND company_id = ?", [$userId, $companyId]);
    return $emp ? $emp['id'] : null;
}

switch ($action) {
    case 'status':
        $empId = getEmployeeId($user_id, $company_id);
        if (!$empId) {
            echo json_encode(['success' => false, 'message' => 'Employee profile not found']);
            exit;
        }

        // Fetch active clock-in
        $active = fetch("SELECT id, clock_in FROM attendance WHERE employee_id = ? AND company_id = ? AND clock_out IS NULL", [$empId, $company_id]);
        
        // Fetch today's total hours
        $todayLogs = fetchAll("SELECT clock_in, clock_out FROM attendance WHERE employee_id = ? AND company_id = ? AND date = CURRENT_DATE() AND clock_out IS NOT NULL", [$empId, $company_id]);
        $totalSeconds = 0;
        foreach ($todayLogs as $log) {
            $totalSeconds += strtotime($log['clock_out']) - strtotime($log['clock_in']);
        }
        $todayHours = round($totalSeconds / 3600, 2);

        echo json_encode([
            'success' => true,
            'is_clocked_in' => !empty($active),
            'clock_in_time' => $active ? date('H:i:s', strtotime($active['clock_in'])) : null,
            'clock_in_date' => $active ? date('Y-m-d', strtotime($active['clock_in'])) : null,
            'today_hours' => $todayHours
        ]);
        break;

    case 'my_logs':
        $empId = getEmployeeId($user_id, $company_id);
        if (!$empId) {
            echo json_encode(['success' => false, 'message' => 'Employee profile not found']);
            exit;
        }

        $startDate = $_POST['start_date'] ?? $data['start_date'] ?? $_GET['start_date'] ?? null;
        $endDate = $_POST['end_date'] ?? $data['end_date'] ?? $_GET['end_date'] ?? null;

        $query = "
            SELECT a.*, s.start_time as shift_start_time 
            FROM attendance a
            LEFT JOIN employees e ON a.employee_id = e.id
            LEFT JOIN shifts s ON e.shift_id = s.id
            WHERE a.employee_id = ? AND a.company_id = ?
        ";
        $params = [$empId, $company_id];

        if ($startDate) {
            $query .= " AND a.date >= ?";
            $params[] = $startDate;
        }
        if ($endDate) {
            $query .= " AND a.date <= ?";
            $params[] = $endDate;
        }

        $query .= " ORDER BY a.date DESC, a.clock_in DESC";
        $logs = fetchAll($query, $params);

        // Process logs to calculate is_late dynamically based on the first clock-in of the day
        $first_clock_ins = [];
        foreach ($logs as $log) {
            $eId = $log['employee_id'];
            $dt = $log['date'];
            $key = $eId . '_' . $dt;
            $timePart = date('H:i:s', strtotime($log['clock_in']));
            if (!isset($first_clock_ins[$key]) || $timePart < $first_clock_ins[$key]) {
                $first_clock_ins[$key] = $timePart;
            }
        }

        foreach ($logs as &$log) {
            $eId = $log['employee_id'];
            $dt = $log['date'];
            $key = $eId . '_' . $dt;
            $firstIn = $first_clock_ins[$key];
            
            $log['is_late'] = false;
            if (!empty($log['shift_start_time'])) {
                if ($firstIn > $log['shift_start_time']) {
                    $log['is_late'] = true;
                }
            }
            if ($log['status'] === 'present' || $log['status'] === 'late') {
                $log['status'] = 'present';
            }
        }
        unset($log);

        echo json_encode([
            'success' => true,
            'logs' => $logs
        ]);
        break;

    case 'all_logs':
        if (!hasRole(['owner', 'manager'])) {
            echo json_encode(['success' => false, 'message' => 'Unauthorized']);
            exit;
        }

        $startDate = $_POST['start_date'] ?? $data['start_date'] ?? $_GET['start_date'] ?? null;
        $endDate = $_POST['end_date'] ?? $data['end_date'] ?? $_GET['end_date'] ?? null;

        $query = "
            SELECT a.*, e.name as employee_name, s.start_time as shift_start_time 
            FROM attendance a
            JOIN employees e ON a.employee_id = e.id
            LEFT JOIN shifts s ON e.shift_id = s.id
            WHERE a.company_id = ?
        ";
        $params = [$company_id];

        if ($startDate) {
            $query .= " AND a.date >= ?";
            $params[] = $startDate;
        }
        if ($endDate) {
            $query .= " AND a.date <= ?";
            $params[] = $endDate;
        }

        $query .= " ORDER BY e.name ASC, a.date DESC, a.clock_in DESC";
        $logs = fetchAll($query, $params);

        // Process logs to calculate is_late dynamically based on the first clock-in of the day
        $first_clock_ins = [];
        foreach ($logs as $log) {
            $eId = $log['employee_id'];
            $dt = $log['date'];
            $key = $eId . '_' . $dt;
            $timePart = date('H:i:s', strtotime($log['clock_in']));
            if (!isset($first_clock_ins[$key]) || $timePart < $first_clock_ins[$key]) {
                $first_clock_ins[$key] = $timePart;
            }
        }

        foreach ($logs as &$log) {
            $eId = $log['employee_id'];
            $dt = $log['date'];
            $key = $eId . '_' . $dt;
            $firstIn = $first_clock_ins[$key];
            
            $log['is_late'] = false;
            if (!empty($log['shift_start_time'])) {
                if ($firstIn > $log['shift_start_time']) {
                    $log['is_late'] = true;
                }
            }
            if ($log['status'] === 'present' || $log['status'] === 'late') {
                $log['status'] = 'present';
            }
        }
        unset($log);

        echo json_encode([
            'success' => true,
            'logs' => $logs
        ]);
        break;

    case 'clock_in':
        $empId = getEmployeeId($user_id, $company_id);
        if (!$empId) {
            echo json_encode(['success' => false, 'message' => 'Employee profile not found']);
            exit;
        }

        // Check active clock-in
        $active = fetch("SELECT id FROM attendance WHERE employee_id = ? AND company_id = ? AND clock_out IS NULL", [$empId, $company_id]);
        if ($active) {
            echo json_encode(['success' => false, 'message' => 'You are already clocked in']);
            exit;
        }

        // Log Clock In
        try {
            $now = date('Y-m-d H:i:s');
            $date = date('Y-m-d');
            
            $status = 'present';

            query(
                "INSERT INTO attendance (employee_id, company_id, date, clock_in, status, source) VALUES (?, ?, ?, ?, ?, 'web_portal')",
                [$empId, $company_id, $date, $now, $status]
            );

            logAudit('Attendance Clock In', "Employee ID $empId clocked in at $now. Status: $status.");
            echo json_encode(['success' => true, 'message' => 'Clocked in successfully at ' . date('H:i:s')]);
        } catch (Exception $e) {
            echo json_encode(['success' => false, 'message' => 'Error: ' . $e->getMessage()]);
        }
        break;

    case 'clock_out':
        $empId = getEmployeeId($user_id, $company_id);
        if (!$empId) {
            echo json_encode(['success' => false, 'message' => 'Employee profile not found']);
            exit;
        }

        // Get active clock-in
        $active = fetch("SELECT id, clock_in FROM attendance WHERE employee_id = ? AND company_id = ? AND clock_out IS NULL", [$empId, $company_id]);
        if (!$active) {
            echo json_encode(['success' => false, 'message' => 'You are not clocked in']);
            exit;
        }

        try {
            $now = date('Y-m-d H:i:s');
            query(
                "UPDATE attendance SET clock_out = ? WHERE id = ?",
                [$now, $active['id']]
            );

            $date = date('Y-m-d');
            processDailyOvertime($empId, $company_id, $date);

            logAudit('Attendance Clock Out', "Employee ID $empId clocked out at $now.");
            echo json_encode(['success' => true, 'message' => 'Clocked out successfully at ' . date('H:i:s')]);
        } catch (Exception $e) {
            echo json_encode(['success' => false, 'message' => 'Error: ' . $e->getMessage()]);
        }
        break;

    case 'manual_log':
        if (!hasRole(['owner', 'manager'])) {
            echo json_encode(['success' => false, 'message' => 'Unauthorized']);
            exit;
        }

        $empId = $_POST['employee_id'] ?? $data['employee_id'] ?? null;
        $date = $_POST['date'] ?? $data['date'] ?? null;
        $clockIn = $_POST['clock_in'] ?? $data['clock_in'] ?? null;
        $clockOut = $_POST['clock_out'] ?? $data['clock_out'] ?? null;
        $status = $_POST['status'] ?? $data['status'] ?? 'present';
        if ($status === 'late') {
            $status = 'present';
        }
        $logId = $_POST['id'] ?? $data['id'] ?? null;

        $myEmpId = getEmployeeId($user_id, $company_id);
        if ($logId) {
            $existingLog = fetch("SELECT employee_id FROM attendance WHERE id = ? AND company_id = ?", [$logId, $company_id]);
            if ($existingLog && $existingLog['employee_id'] == $myEmpId) {
                echo json_encode(['success' => false, 'message' => 'You cannot edit your own attendance records']);
                exit;
            }
        } else {
            if ($empId == $myEmpId) {
                echo json_encode(['success' => false, 'message' => 'You cannot create manual attendance records for yourself']);
                exit;
            }
        }

        if (!$empId || !$date || !$clockIn) {
            echo json_encode(['success' => false, 'message' => 'Missing required fields']);
            exit;
        }

        try {
            // Join date and time
            $inDateTime = $date . ' ' . $clockIn;
            $outDateTime = $clockOut ? ($date . ' ' . $clockOut) : null;

            if ($logId) {
                // Update existing
                query(
                    "UPDATE attendance SET date = ?, clock_in = ?, clock_out = ?, status = ?, source = 'manual' WHERE id = ? AND company_id = ?",
                    [$date, $inDateTime, $outDateTime, $status, $logId, $company_id]
                );
                logAudit('Manual Attendance Edit', "Updated attendance record $logId for employee $empId");
            } else {
                // Create manual log
                query(
                    "INSERT INTO attendance (employee_id, company_id, date, clock_in, clock_out, status, source) VALUES (?, ?, ?, ?, ?, ?, 'manual')",
                    [$empId, $company_id, $date, $inDateTime, $outDateTime, $status]
                );
                logAudit('Manual Attendance Created', "Created manual attendance for employee $empId on $date");
            }

            processDailyOvertime($empId, $company_id, $date);

            echo json_encode(['success' => true, 'message' => 'Attendance log saved successfully']);
        } catch (Exception $e) {
            echo json_encode(['success' => false, 'message' => 'Error: ' . $e->getMessage()]);
        }
        break;

    case 'delete_log':
        if (!hasRole(['owner', 'manager'])) {
            echo json_encode(['success' => false, 'message' => 'Unauthorized']);
            exit;
        }

        $logId = $_POST['id'] ?? $data['id'] ?? null;
        if (!$logId) {
            echo json_encode(['success' => false, 'message' => 'Missing log ID']);
            exit;
        }

        try {
            $myEmpId = getEmployeeId($user_id, $company_id);
            $existingLog = fetch("SELECT employee_id, date FROM attendance WHERE id = ? AND company_id = ?", [$logId, $company_id]);
            if ($existingLog && $existingLog['employee_id'] == $myEmpId) {
                echo json_encode(['success' => false, 'message' => 'You cannot delete your own attendance records']);
                exit;
            }

            query("DELETE FROM attendance WHERE id = ? AND company_id = ?", [$logId, $company_id]);
            logAudit('Attendance Log Deleted', "Deleted attendance record $logId");
            
            if ($existingLog) {
                processDailyOvertime($existingLog['employee_id'], $company_id, $existingLog['date']);
            }

            echo json_encode(['success' => true, 'message' => 'Attendance log deleted successfully']);
        } catch (Exception $e) {
            echo json_encode(['success' => false, 'message' => 'Error: ' . $e->getMessage()]);
        }
        break;

    case 'kiosk_scan':
        $code = trim($data['employee_code'] ?? '');
        if (!$code) {
            echo json_encode(['success' => false, 'message' => 'No QR code scanned']);
            exit;
        }

        // Find employee by employee_code with role
        $emp = fetch("SELECT e.id, e.name, e.employee_code, e.profile_picture, r.name as role_name FROM employees e LEFT JOIN roles r ON e.role_id = r.id WHERE e.employee_code = ? AND e.company_id = ?", [$code, $company_id]);
        if (!$emp) {
            // Fallback: try stripping non-digits to find by numeric id or formatted code
            $numericId = preg_replace('/\D/', '', $code);
            if ($numericId) {
                $emp = fetch("SELECT e.id, e.name, e.employee_code, e.profile_picture, r.name as role_name FROM employees e LEFT JOIN roles r ON e.role_id = r.id WHERE (e.id = ? OR e.employee_code = ?) AND e.company_id = ?", [$numericId, $code, $company_id]);
            }
        }

        if (!$emp) {
            echo json_encode(['success' => false, 'message' => "Invalid Employee Code: $code"]);
            exit;
        }

        $empId = $emp['id'];

        // Get active clock-in
        $active = fetch("SELECT id, clock_in FROM attendance WHERE employee_id = ? AND company_id = ? AND clock_out IS NULL", [$empId, $company_id]);

        // Process Base64 photo snapshot upload
        $photoData = $data['photo'] ?? '';
        $photoPath = null;
        if ($photoData && preg_match('/^data:image\/(\w+);base64,/', $photoData, $type)) {
            $photoData = substr($photoData, strpos($photoData, ',') + 1);
            $photoData = base64_decode($photoData);
            if ($photoData) {
                $dir = '../uploads/attendance_photos';
                if (!file_exists($dir)) {
                    mkdir($dir, 0777, true);
                }
                $filename = ($active ? 'checkout_' : 'checkin_') . $empId . '_' . time() . '.jpg';
                $filepath = $dir . '/' . $filename;
                file_put_contents($filepath, $photoData);
                $photoPath = 'uploads/attendance_photos/' . $filename;
            }
        }

        try {
            $now = date('Y-m-d H:i:s');
            $date = date('Y-m-d');

            if ($active) {
                // Clock Out
                query(
                    "UPDATE attendance SET clock_out = ?, clock_out_photo = ? WHERE id = ?",
                    [$now, $photoPath, $active['id']]
                );
                processDailyOvertime($empId, $company_id, $date);
                logAudit('Attendance Clock Out', "Employee ID $empId clocked out via QR Kiosk. Photo: $photoPath");
                
                echo json_encode([
                    'success' => true,
                    'type' => 'clock_out',
                    'employee_name' => $emp['name'],
                    'employee_code' => $emp['employee_code'] ?: 'EMP-' . str_pad($empId, 5, '0', STR_PAD_LEFT),
                    'role_name' => $emp['role_name'] ?: 'Staff',
                    'profile_picture' => $emp['profile_picture'] ?: '',
                    'time_formatted' => date('h:i A', strtotime($now)),
                    'photo_url' => $photoPath
                ]);
            } else {
                // Clock In
                $status = 'present';

                query(
                    "INSERT INTO attendance (employee_id, company_id, date, clock_in, status, source, clock_in_photo) VALUES (?, ?, ?, ?, ?, 'kiosk', ?)",
                    [$empId, $company_id, $date, $now, $status, $photoPath]
                );
                logAudit('Attendance Clock In', "Employee ID $empId clocked in via QR Kiosk. Photo: $photoPath");

                echo json_encode([
                    'success' => true,
                    'type' => 'clock_in',
                    'employee_name' => $emp['name'],
                    'employee_code' => $emp['employee_code'] ?: 'EMP-' . str_pad($empId, 5, '0', STR_PAD_LEFT),
                    'role_name' => $emp['role_name'] ?: 'Staff',
                    'profile_picture' => $emp['profile_picture'] ?: '',
                    'time_formatted' => date('h:i A', strtotime($now)),
                    'photo_url' => $photoPath
                ]);
            }
        } catch (Exception $e) {
            echo json_encode(['success' => false, 'message' => 'Error: ' . $e->getMessage()]);
        }
        break;

    // REST Biometric endpoint
    case 'biometric_push':
        // Biometric log can be posted from device via standard header
        // Simple auth check via key in request
        $apiKey = $_POST['api_key'] ?? $data['api_key'] ?? '';
        $expectedKey = md5($company_id . 'nexcore_biometric_salt'); // Simple deterministic API Key

        if ($apiKey !== $expectedKey) {
            echo json_encode(['success' => false, 'message' => 'Invalid API Key']);
            exit;
        }

        $deviceLogId = $_POST['device_log_id'] ?? $data['device_log_id'] ?? null;
        $nic = $_POST['employee_nic'] ?? $data['employee_nic'] ?? null;
        $timestamp = $_POST['timestamp'] ?? $data['timestamp'] ?? null;
        $direction = $_POST['direction'] ?? $data['direction'] ?? 'IN'; // IN or OUT

        if (!$nic || !$timestamp) {
            echo json_encode(['success' => false, 'message' => 'Missing parameters']);
            exit;
        }

        // Fetch employee
        $emp = fetch("SELECT id FROM employees WHERE nic = ? AND company_id = ?", [$nic, $company_id]);
        if (!$emp) {
            echo json_encode(['success' => false, 'message' => 'Employee with NIC not found']);
            exit;
        }
        $empId = $emp['id'];
        $date = date('Y-m-d', strtotime($timestamp));

        try {
            if ($direction === 'IN') {
                $status = 'present';
                query(
                    "INSERT INTO attendance (employee_id, company_id, date, clock_in, status, source, device_log_id) VALUES (?, ?, ?, ?, ?, 'fingerprint_api', ?)",
                    [$empId, $company_id, $date, $timestamp, $status, $deviceLogId]
                );
            } else {
                // Find latest active clock_in today
                $active = fetch("SELECT id FROM attendance WHERE employee_id = ? AND date = ? AND clock_out IS NULL ORDER BY clock_in DESC LIMIT 1", [$empId, $date]);
                if ($active) {
                    query("UPDATE attendance SET clock_out = ?, device_log_id = ? WHERE id = ?", [$timestamp, $deviceLogId, $active['id']]);
                } else {
                    // Create clock out without clock in (anomalous present status)
                    query(
                        "INSERT INTO attendance (employee_id, company_id, date, clock_in, clock_out, status, source, device_log_id) VALUES (?, ?, ?, ?, ?, 'present', 'fingerprint_api', ?)",
                        [$empId, $company_id, $date, $timestamp, $timestamp, $deviceLogId]
                    );
                }
            }

            processDailyOvertime($empId, $company_id, $date);

            echo json_encode(['success' => true, 'message' => 'Biometric log recorded']);
        } catch (Exception $e) {
            echo json_encode(['success' => false, 'message' => 'Error: ' . $e->getMessage()]);
        }
        break;

    default:
        echo json_encode(['success' => false, 'message' => 'Invalid action']);
        break;
}
