<?php
require_once __DIR__ . '/vendor/autoload.php';
require_once __DIR__ . '/config/database.php';

// CORS Headers
header("Access-Control-Allow-Origin: *");
header("Content-Type: application/json; charset=UTF-8");
header("Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS");
header("Access-Control-Max-Age: 3600");
header("Access-Control-Allow-Headers: Content-Type, Access-Control-Allow-Headers, Authorization, X-Requested-With");

// Load the .env file from the current directory (__DIR__)
$dotenv = Dotenv\Dotenv::createImmutable(__DIR__);
$dotenv->load();

// Now this works!
// $dbHost = $_ENV['DB_HOST']; // Recommended over getenv()

// error_log("TEST console");

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

// Simple Router
$uri = parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH);
$method = $_SERVER['REQUEST_METHOD'];

// Remove base path if needed (e.g., if hosted in subdir)
// For now assume root or consistent relative path handling
// Clean URI for matching
// $basePath = '/api'; // If your calls start with /api

// New Line (Dynamic - Recommended):
$basePath = dirname($_SERVER['SCRIPT_NAME']);
$path = str_replace($basePath, '', $uri);

// Database Connection
$database = new Database();
$pdo = $database->connect();

// Autoload Classes manually for simplicity or use Composer's if I mapped them
require_once __DIR__ . '/src/Auth.php';
require_once __DIR__ . '/src/User.php';
require_once __DIR__ . '/src/Post.php';
require_once __DIR__ . '/src/Comment.php';

$auth = new Auth($pdo);
$user = new User($pdo);
$post = new Post($pdo);
$comment = new Comment($pdo);

// Serve static files from uploads (URL says /uploads/, but we look in /storage/)
if (strpos($uri, '/uploads/') !== false) {
    
    // 1. Always Send CORS Headers (Crucial for Flutter Web)
    header("Access-Control-Allow-Origin: *");
    header("Access-Control-Allow-Methods: GET, OPTIONS");
    header("Access-Control-Allow-Headers: Content-Type, Authorization");

    // Handle "Pre-flight" OPTIONS request immediately
    if ($_SERVER['REQUEST_METHOD'] === 'OPTIONS') {
        http_response_code(200);
        exit;
    }

    // 2. Check Authentication
    $auth->authenticate();
    
    // 3. Extract the Filename safely
    // Input: /backends/uploads/my_image.jpg  => Output: "my_image.jpg"
    $filename = basename(parse_url($uri, PHP_URL_PATH));
    
    // 4. Build the physical path to the STORAGE folder
    // This assumes "storage" is inside "backends" (same level as index.php)
    $file = __DIR__ . '/storage/' . $filename;

    // 5. Security & Existence Check
    $realPath = realpath($file);
    $storageDir = realpath(__DIR__ . '/storage');

    // Ensure the file exists AND is truly inside the storage folder (prevent hacks)
    if ($realPath && $storageDir && strpos($realPath, $storageDir) === 0 && file_exists($realPath)) {
        
        // 6. Serve the file
        $mime = mime_content_type($realPath) ?: 'application/octet-stream';
        header('Content-Type: ' . $mime);
        header('Content-Length: ' . filesize($realPath));
        readfile($realPath);
        exit;
        
    } else {
        // 7. Debugging 404 (Check your error_log if this happens)
        error_log("404 Failed: URI says '$filename', but not found in '$file'");
        
        http_response_code(404);
        echo json_encode([
            "msg" => "File not found", 
            "debug_file" => $filename, 
            "server_path" => $file
        ]);
        exit;
    }
}

// Helper for params
function getJsonInput() {
    return json_decode(file_get_contents("php://input"), true) ?? [];
}

// Route Matching
try {
    // AUTH
    if ($path === '/auth/register' && $method === 'POST') {
        echo json_encode($auth->register(getJsonInput()));
    }
    elseif ($path === '/auth/login' && $method === 'POST') {
        echo json_encode($auth->login(getJsonInput()));
    }
    elseif ($path === '/auth/salt' && $method === 'GET') {
      // deprecated use /auth/user or /auth/profile
        error_log("Received request for /auth/salt with query: " . print_r($_GET, true)); // Debugging line
        $id = $_GET['id'] ?? null;
        $username = $_GET['username'] ?? null;
        error_log("Fetching salt and private key for user ID: " . $id); // Debugging line
        echo json_encode($auth->getSaltAndPrivateKey($username, $id));
    }
    elseif ($path === '/auth/user' && $method === 'GET') { // unused
        $userId = $auth->authenticate();
        echo json_encode($auth->getUser($userId));
    }
    elseif ($path === '/auth/profile' && $method === 'GET') {
        $userId = $auth->authenticate();
        echo json_encode($auth->getUser($userId));
    }
    elseif ($path === '/auth/profile' && $method === 'POST') {
        $userId = $auth->authenticate();
        echo json_encode($auth->updateProfile($userId));
    }
    elseif ($path === '/auth/change-password' && $method === 'POST') {
        // $userId = $auth->authenticate();
        echo json_encode($auth->changePassword($userId, getJsonInput()));
    }
    elseif ($path === '/auth/verify-otp' && $method === 'POST') {
        echo json_encode($auth->verifyOTP(getJsonInput()));
    }
    elseif ($path === '/auth/resend-otp' && $method === 'POST') {
        echo json_encode($auth->resendOTP(getJsonInput()));
    }
    elseif ($path === '/auth/forgot-password' && $method === 'POST') {
        echo json_encode($auth->requestPasswordReset(getJsonInput()));
    }
    elseif ($path === '/auth/reset-password' && $method === 'POST') {
        echo json_encode($auth->resetPassword(getJsonInput()));
    }
    
    // USERS
    elseif ($path === '/users' && $method === 'GET') {
        $userId = $auth->authenticate();
        $query = $_GET['search'] ?? '';
        echo json_encode($user->search($userId, $query));
    }
    elseif ($path === '/users/add' && $method === 'POST') {
        $userId = $auth->authenticate();
        echo json_encode($user->sendFriendRequest($userId, getJsonInput()));
    }
    elseif ($path === '/users/accept' && $method === 'POST') {
        $userId = $auth->authenticate();
        echo json_encode($user->acceptFriendRequest($userId, getJsonInput()));
    }
    elseif ($path === '/users/remove' && $method === 'POST') {
        $userId = $auth->authenticate();
        echo json_encode($user->removeFriend($userId, getJsonInput()));
    }
    elseif ($path === '/users/friends' && $method === 'GET') {
        $userId = $auth->authenticate();
        echo json_encode($user->getFriends($userId));
    }
    elseif ($path === '/users/requests' && $method === 'GET') {
        $userId = $auth->authenticate();
        echo json_encode($user->getPendingRequests($userId));
    }
    elseif ($path === '/users/sent-requests' && $method === 'GET') {
        $userId = $auth->authenticate();
        echo json_encode($user->getSentRequests($userId));
    }
    elseif ($path === '/users/cancel' && $method === 'POST') {
        $userId = $auth->authenticate();
        echo json_encode($user->cancelFriendRequest($userId, getJsonInput()));
    }
    elseif ($path === '/users/friendsPublicKeys'&& $method === 'GET'){
        $userId = $auth->authenticate();
        echo json_encode($user->getFriendsPublicKeys($userId), JSON_FORCE_OBJECT);
    }

    // POSTS
    elseif ($path === '/posts' && $method === 'POST') {
        $userId = $auth->authenticate();
        echo json_encode($post->create($userId, getJsonInput()));
    }
    elseif ($path === '/posts/feed' && $method === 'GET') {
        $userId = $auth->authenticate();
        echo json_encode($post->getFeed($userId));
    }
    elseif ($path === '/posts/latest' && $method === 'GET') {
        $userId = $auth->authenticate();
        echo json_encode($post->getLatest($userId));
    }
    elseif ($path === '/posts/remaining' && $method === 'GET') {
        $userId = $auth->authenticate();
        echo json_encode($post->getRemainingPosts($userId));
    }
    elseif (preg_match('#^/posts/friend/(\d+)/latest$#', $path, $matches) && $method === 'GET') {
        $userId = $auth->authenticate();
        echo json_encode($post->getLatestFromFriend($userId, $matches[1]));
    }
    elseif (preg_match('#^/posts/(\d+)$#', $path, $matches) && $method === 'DELETE') {
        $userId = $auth->authenticate();
        echo json_encode($post->delete($userId, $matches[1]));
    }
    elseif (preg_match('#^/posts/(\d+)$#', $path, $matches) && ($method === 'PUT' || $method === 'POST')) {
        $userId = $auth->authenticate();
        echo json_encode($post->update($userId, $matches[1]));
    }
    // Match /posts/{postId}/keys?userId={userId}
    elseif (preg_match('#^/posts/(\d+)/keys$#', $path, $matches) && $method === 'GET' && isset($_GET['userId'])) {
      $userId = $auth->authenticate();
      $requestedUserId = $_GET['userId'];
      echo json_encode($post->getPostKey($userId, $matches[1]));
    }
    
    // COMMENTS
    elseif (preg_match('#^/posts/(\d+)/comments$#', $path, $matches) && $method === 'GET') {
        $userId = $auth->authenticate();
        echo json_encode($comment->getAll($matches[1]));
    }
    elseif (preg_match('#^/posts/(\d+)/comments$#', $path, $matches) && $method === 'POST') {
        $userId = $auth->authenticate();
        echo json_encode($comment->add($userId, $matches[1], getJsonInput()));
    }

    // LIKES
    elseif (preg_match('#^/posts/(\d+)/like$#', $path, $matches) && $method === 'POST') {
        $userId = $auth->authenticate();
        echo json_encode($post->toggleLike($userId, $matches[1]));
    }
    
    else {
        http_response_code(404);
        echo json_encode(["msg" => "Endpoint not found: " . $path]);
        error_log("Endpoint not found: " . $path); // Log for debugging
    }

} catch (Exception $e) {
    $errorCode = (int)$e->getCode() ?: 500;
    http_response_code($errorCode);
    echo json_encode(["msg" => $e->getMessage()]);
}
