<?php
/**
 * Authentication API Endpoint
 * Handles login, logout, token refresh, and user verification
 */

header('Content-Type: application/json');
header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Methods: POST, GET, OPTIONS');
header('Access-Control-Allow-Headers: Content-Type, Authorization');

// Handle preflight requests
if ($_SERVER['REQUEST_METHOD'] === 'OPTIONS') {
    http_response_code(200);
    exit;
}

define('APP_RUNNING', true);
require_once '../db_connect.php';
require_once '../includes/auth.php';

// Initialize session for web-based auth
initSecureSession();

$response = ['success' => false, 'message' => '', 'data' => null];

// Get request method and action
$method = $_SERVER['REQUEST_METHOD'];
$action = $_GET['action'] ?? $_POST['action'] ?? '';

// Handle different actions
switch ($action) {
    case 'login':
        handleLogin($conn, $response);
        break;

    case 'logout':
        handleLogout($conn, $response);
        break;

    case 'refresh':
        handleTokenRefresh($conn, $response);
        break;

    case 'verify':
        handleVerifyToken($response);
        break;

    case 'me':
        handleGetCurrentUser($conn, $response);
        break;

    case 'change-password':
        handleChangePassword($conn, $response);
        break;

    default:
        $response['message'] = 'Invalid action';
        http_response_code(400);
}

echo json_encode($response);
exit;

/**
 * Handle login request
 */
function handleLogin($conn, &$response) {
    if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
        $response['message'] = 'Method not allowed';
        http_response_code(405);
        return;
    }

    // Get input
    $input = json_decode(file_get_contents('php://input'), true);
    if (!$input) {
        $input = $_POST;
    }

    $username = sanitizeInput($input['username'] ?? '');
    $password = $input['password'] ?? '';

    if (empty($username) || empty($password)) {
        $response['message'] = 'Username and password are required';
        http_response_code(400);
        return;
    }

    // Rate limiting
    $ip = getClientIP();
    if (!checkRateLimit("login_$ip")) {
        $response['message'] = 'Too many login attempts. Please try again later.';
        http_response_code(429);
        return;
    }

    // Find user
    $username = mysqli_real_escape_string($conn, $username);
    $result = mysqli_query($conn, "SELECT * FROM users WHERE username = '$username' OR email = '$username'");

    if (mysqli_num_rows($result) === 0) {
        $response['message'] = 'Invalid credentials';
        http_response_code(401);
        return;
    }

    $user = mysqli_fetch_assoc($result);

    // Verify password
    if (!password_verify($password, $user['password'])) {
        // Log failed attempt
        mysqli_query($conn, "INSERT INTO activity_logs (user_id, action, description, ip_address)
                             VALUES ({$user['id']}, 'login_failed', 'Failed login attempt', '$ip')");

        $response['message'] = 'Invalid credentials';
        http_response_code(401);
        return;
    }

    // Check user status
    if ($user['status'] !== 'approved') {
        $response['message'] = 'Your account is not approved. Status: ' . $user['status'];
        http_response_code(403);
        return;
    }

    // Generate tokens
    $jwt_token = generateJWT($user['id'], $user['role']);
    $auth_token = loginUser($conn, $user);

    $response['success'] = true;
    $response['message'] = 'Login successful';
    $response['data'] = [
        'user' => [
            'id' => $user['id'],
            'username' => $user['username'],
            'email' => $user['email'],
            'full_name' => $user['full_name'],
            'role' => $user['role']
        ],
        'token' => $jwt_token,
        'session_token' => $auth_token,
        'expires_in' => JWT_EXPIRY
    ];
}

/**
 * Handle logout request
 */
function handleLogout($conn, &$response) {
    logoutUser($conn);

    $response['success'] = true;
    $response['message'] = 'Logged out successfully';
}

/**
 * Handle token refresh
 */
function handleTokenRefresh($conn, &$response) {
    $token = getBearerToken();

    if (!$token) {
        $response['message'] = 'No token provided';
        http_response_code(401);
        return;
    }

    $payload = verifyJWT($token);

    if (!$payload) {
        $response['message'] = 'Invalid or expired token';
        http_response_code(401);
        return;
    }

    // Get fresh user data
    $user_id = $payload['user_id'];
    $result = mysqli_query($conn, "SELECT * FROM users WHERE id = $user_id AND status = 'approved'");

    if (mysqli_num_rows($result) === 0) {
        $response['message'] = 'User not found or not approved';
        http_response_code(401);
        return;
    }

    $user = mysqli_fetch_assoc($result);

    // Generate new token
    $new_token = generateJWT($user['id'], $user['role']);

    $response['success'] = true;
    $response['data'] = [
        'token' => $new_token,
        'expires_in' => JWT_EXPIRY
    ];
}

/**
 * Handle token verification
 */
function handleVerifyToken(&$response) {
    $token = getBearerToken();

    if (!$token) {
        $response['message'] = 'No token provided';
        http_response_code(401);
        return;
    }

    $payload = verifyJWT($token);

    if (!$payload) {
        $response['message'] = 'Invalid or expired token';
        http_response_code(401);
        return;
    }

    $response['success'] = true;
    $response['data'] = [
        'valid' => true,
        'user_id' => $payload['user_id'],
        'role' => $payload['role'],
        'expires_at' => date('Y-m-d H:i:s', $payload['exp'])
    ];
}

/**
 * Get current authenticated user
 */
function handleGetCurrentUser($conn, &$response) {
    // Try JWT token first
    $token = getBearerToken();

    if ($token) {
        $payload = verifyJWT($token);
        if ($payload) {
            $user_id = $payload['user_id'];
            $result = mysqli_query($conn, "SELECT id, username, email, full_name, phone, role, created_at FROM users WHERE id = $user_id");

            if ($user = mysqli_fetch_assoc($result)) {
                $response['success'] = true;
                $response['data'] = $user;
                return;
            }
        }
    }

    // Try session
    if (isAuthenticated() && validateSession()) {
        $user_id = $_SESSION['user_id'];
        $result = mysqli_query($conn, "SELECT id, username, email, full_name, phone, role, created_at FROM users WHERE id = $user_id");

        if ($user = mysqli_fetch_assoc($result)) {
            $response['success'] = true;
            $response['data'] = $user;
            return;
        }
    }

    $response['message'] = 'Not authenticated';
    http_response_code(401);
}

/**
 * Handle password change
 */
function handleChangePassword($conn, &$response) {
    if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
        $response['message'] = 'Method not allowed';
        http_response_code(405);
        return;
    }

    // Verify authentication
    $user_id = null;
    $token = getBearerToken();

    if ($token) {
        $payload = verifyJWT($token);
        if ($payload) {
            $user_id = $payload['user_id'];
        }
    } elseif (isAuthenticated()) {
        $user_id = $_SESSION['user_id'];
    }

    if (!$user_id) {
        $response['message'] = 'Not authenticated';
        http_response_code(401);
        return;
    }

    // Get input
    $input = json_decode(file_get_contents('php://input'), true) ?: $_POST;

    $current_password = $input['current_password'] ?? '';
    $new_password = $input['new_password'] ?? '';
    $confirm_password = $input['confirm_password'] ?? '';

    if (empty($current_password) || empty($new_password)) {
        $response['message'] = 'Current password and new password are required';
        http_response_code(400);
        return;
    }

    if ($new_password !== $confirm_password) {
        $response['message'] = 'New passwords do not match';
        http_response_code(400);
        return;
    }

    // Validate password strength
    $strength_errors = validatePasswordStrength($new_password);
    if (!empty($strength_errors)) {
        $response['message'] = implode('. ', $strength_errors);
        http_response_code(400);
        return;
    }

    // Verify current password
    $result = mysqli_query($conn, "SELECT password FROM users WHERE id = $user_id");
    $user = mysqli_fetch_assoc($result);

    if (!password_verify($current_password, $user['password'])) {
        $response['message'] = 'Current password is incorrect';
        http_response_code(400);
        return;
    }

    // Update password
    $new_hash = hashPassword($new_password);
    $new_hash = mysqli_real_escape_string($conn, $new_hash);

    if (mysqli_query($conn, "UPDATE users SET password = '$new_hash' WHERE id = $user_id")) {
        // Log the change
        $ip = mysqli_real_escape_string($conn, getClientIP());
        mysqli_query($conn, "INSERT INTO activity_logs (user_id, action, description, ip_address)
                             VALUES ($user_id, 'password_change', 'Password changed', '$ip')");

        $response['success'] = true;
        $response['message'] = 'Password changed successfully';
    } else {
        $response['message'] = 'Failed to change password';
        http_response_code(500);
    }
}

/**
 * Get Bearer token from Authorization header
 */
function getBearerToken() {
    $headers = getallheaders();
    $auth_header = $headers['Authorization'] ?? $headers['authorization'] ?? '';

    if (preg_match('/Bearer\s+(.*)$/i', $auth_header, $matches)) {
        return $matches[1];
    }

    return null;
}
?>
