<?php

declare(strict_types=1);

require_once __DIR__ . '/../../includes/bootstrap.php';

auth_start_session();
auth_require_role(['staff']);

function json_response(int $statusCode, array $payload): void
{
    http_response_code($statusCode);
    header('Content-Type: application/json');
    echo json_encode($payload);
    exit;
}

if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
    json_response(405, ['ok' => false, 'error' => 'Method Not Allowed']);
}

$user = auth_user();
$staffId = (int)($user['user_id'] ?? 0);

$action = (string)($_POST['action'] ?? 'update');

$latRaw = (string)($_POST['lat'] ?? '');
$lngRaw = (string)($_POST['lng'] ?? '');
$accRaw = (string)($_POST['acc'] ?? '');

$lat = (float)$latRaw;
$lng = (float)$lngRaw;
$acc = null;
if ($accRaw !== '' && is_numeric($accRaw)) {
    $acc = (int)round((float)$accRaw);
}

if ($staffId <= 0) {
    json_response(401, ['ok' => false, 'error' => 'Unauthorized']);
}

if ($latRaw === '' || $lngRaw === '' || $lat < -90 || $lat > 90 || $lng < -180 || $lng > 180) {
    json_response(400, ['ok' => false, 'error' => 'Invalid coordinates']);
}

try {
    $pdo = Database::pdo();

    $pdo->beginTransaction();

    if ($action === 'start_day') {
        $sessionId = StaffLocationService::startSession($pdo, $staffId, $lat, $lng);
        StaffLocationService::logPoint($pdo, $sessionId, $staffId, $lat, $lng, $acc);

        $stmt = $pdo->prepare(
            'UPDATE staff_details
             SET current_latitude = :lat,
                 current_longitude = :lng,
                 last_location_update = CURRENT_TIMESTAMP,
                 is_available = 1
             WHERE user_id = :uid'
        );
        $stmt->execute([
            'lat' => $lat,
            'lng' => $lng,
            'uid' => $staffId,
        ]);

        $stmtName = $pdo->prepare('SELECT full_name FROM users WHERE user_id = :id LIMIT 1');
        $stmtName->execute(['id' => $staffId]);
        $staffName = (string)($stmtName->fetchColumn() ?: 'Staff');

        $stmtAdmins = $pdo->query("SELECT user_id FROM users WHERE user_type = 'admin' AND is_active = 1");
        $adminIds = $stmtAdmins->fetchAll(PDO::FETCH_COLUMN);

        if ($adminIds) {
            $stmtNotif = $pdo->prepare(
                "INSERT INTO notifications (user_id, title, message, type, related_id)
                 VALUES (:user_id, :title, :message, 'system', :related_id)"
            );

            foreach ($adminIds as $adminId) {
                $stmtNotif->execute([
                    'user_id' => (int)$adminId,
                    'title' => 'Staff Check-in',
                    'message' => $staffName . ' started the day and updated their location.',
                    'related_id' => $staffId,
                ]);
            }
        }
    } elseif ($action === 'end_day') {
        $activeId = StaffLocationService::getActiveSessionId($pdo, $staffId);
        if ($activeId !== null) {
            StaffLocationService::logPoint($pdo, $activeId, $staffId, $lat, $lng, $acc);
            StaffLocationService::endSession($pdo, $staffId, $lat, $lng);
        }

        $stmt = $pdo->prepare(
            'UPDATE staff_details
             SET current_latitude = :lat,
                 current_longitude = :lng,
                 last_location_update = CURRENT_TIMESTAMP,
                 is_available = 0
             WHERE user_id = :uid'
        );
        $stmt->execute([
            'lat' => $lat,
            'lng' => $lng,
            'uid' => $staffId,
        ]);
    } else {
        $activeId = StaffLocationService::getActiveSessionId($pdo, $staffId);
        if ($activeId === null) {
            $activeId = StaffLocationService::startSession($pdo, $staffId, $lat, $lng);
        }
        StaffLocationService::logPoint($pdo, (int)$activeId, $staffId, $lat, $lng, $acc);

        $stmt = $pdo->prepare(
            'UPDATE staff_details
             SET current_latitude = :lat,
                 current_longitude = :lng,
                 last_location_update = CURRENT_TIMESTAMP
             WHERE user_id = :uid'
        );
        $stmt->execute([
            'lat' => $lat,
            'lng' => $lng,
            'uid' => $staffId,
        ]);
    }

    $pdo->commit();

    json_response(200, ['ok' => true]);
} catch (Throwable $e) {
    if (isset($pdo) && $pdo instanceof PDO && $pdo->inTransaction()) {
        $pdo->rollBack();
    }
    json_response(500, ['ok' => false, 'error' => $e->getMessage()]);
}
