<?php
/**
 * Authentication and authorization functions
 */

// Define TONSUI_LOADED constant to prevent direct access to session_init.php
if (!defined('TONSUI_LOADED')) {
    define('TONSUI_LOADED', true);
}

// Include centralized session initialization
require_once __DIR__ . '/session_init.php';

// Note: Do not emit CORS headers or handle OPTIONS here. Endpoints should manage CORS.

// Global variables
$config = null;
$pdo = null;

// Load configuration if not already loaded
if ($config === null) {
    $config = require __DIR__ . '/config.php';
}

// Session is initialized in session_init.php; avoid duplicate/contradictory settings here.

/**
 * Check if a user is logged in
 * 
 * @return bool True if user is logged in, false otherwise
 */
function isLoggedIn() {
    return isset($_SESSION['user_id']) ? true : false;
}

/**
 * Check if the current user is an admin
 * 
 * @param int $userId The user ID to check
 * @return bool True if user is an admin, false otherwise
 */
function isAdmin($userId) {
    global $pdo;
    
    // If no database connection, return false
    if (!$pdo) {
        return false;
    }
    
    try {
        // Check if the user is in the admins table with is_admin=1
        $stmt = $pdo->prepare('SELECT is_admin FROM admins WHERE id = ? AND is_admin = 1');
        $stmt->execute([$userId]);
        $admin = $stmt->fetch(PDO::FETCH_ASSOC);
        
        // Return true if found in admins table with is_admin=1
        return ($admin !== false);
    } catch (PDOException $e) {
        error_log('Database error in isAdmin: ' . $e->getMessage());
        return false;
    }
}

/**
 * Get the current user's ID
 * 
 * @return int|null The user ID if logged in, null otherwise
 */
function getCurrentUserId() {
    return isset($_SESSION['user_id']) ? $_SESSION['user_id'] : null;
}

/**
 * Require admin access
 * 
 * If the current user is not an admin, this function will send a 403 Forbidden
 * response and terminate execution.
 */
// NOTE: requireAdmin() is defined centrally in `session_init.php` and should not
// be redefined here to avoid redeclaration errors. Use the version from
// `session_init.php` which relies on session flags set during login.

// Initialize database connection
function initAuth() {
    global $pdo, $config;
    
    // Load config if not already loaded
    if ($config === null) {
        $configPath = __DIR__ . '/config.php';
        if (!file_exists($configPath)) {
            error_log('Config file not found at: ' . $configPath);
            http_response_code(500);
            echo json_encode(['success' => false, 'error' => 'Configuration file not found']);
            exit;
        }
        
        $config = require $configPath;
        
        if (!is_array($config)) {
            error_log('Config file does not return an array');
            http_response_code(500);
            echo json_encode(['success' => false, 'error' => 'Invalid configuration format']);
            exit;
        }
        
        // Check for required database config parameters
        $requiredParams = ['db_host', 'db_name', 'db_user'];
        foreach ($requiredParams as $param) {
            if (!isset($config[$param])) {
                error_log('Missing required config parameter: ' . $param);
                http_response_code(500);
                echo json_encode(['success' => false, 'error' => 'Missing required configuration: ' . $param]);
                exit;
            }
        }
        
        // Default db_pass to empty string if not provided
        if (!isset($config['db_pass'])) {
            $config['db_pass'] = '';
        }
    }
    
    if ($pdo === null) {
        try {
            // Log connection attempt
            error_log("Attempting to connect to database: host={$config['db_host']}, name={$config['db_name']}, user={$config['db_user']}");
            
            // First test connection without database name (optional; avoid SHOW DATABASES on shared hosts)
            $testDsn = "mysql:host={$config['db_host']}";
            if (isset($config['db_port'])) {
                $testDsn .= ";port={$config['db_port']}";
            }
            try {
                $testPdo = new PDO(
                    $testDsn,
                    $config['db_user'],
                    $config['db_pass'],
                    [
                        PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
                        PDO::ATTR_TIMEOUT => 5,
                    ]
                );
                error_log("Basic database connection successful");
            } catch (PDOException $e) {
                // Non-fatal: proceed to attempt direct DB connection
                error_log("Database server connection warning: " . $e->getMessage());
            }
            
            // Now connect with the database name included
            $dsn = "mysql:host={$config['db_host']}";
            if (isset($config['db_port'])) {
                $dsn .= ";port={$config['db_port']}";
            }
            $dsn .= ";dbname={$config['db_name']};charset=utf8mb4";
            
            $pdo = new PDO(
                $dsn,
                $config['db_user'],
                $config['db_pass'],
                [
                    PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
                    PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
                    PDO::ATTR_EMULATE_PREPARES => false,
                ]
            );
            
            // Ensure core users table exists (required for user endpoints)
            try {
                $pdo->query("SELECT 1 FROM users LIMIT 1");
                error_log("Users table exists and is accessible");
            } catch (PDOException $e) {
                error_log("Users table check failed: " . $e->getMessage());
                http_response_code(500);
                echo json_encode(['success' => false, 'error' => 'Database schema incomplete. Please complete installation.']);
                exit;
            }

            // Admins table is recommended but not fatal for user endpoints
            try {
                $pdo->query("SELECT 1 FROM admins LIMIT 1");
                error_log("Admins table exists and is accessible");
            } catch (PDOException $e) {
                error_log("Admins table check failed (non-fatal): " . $e->getMessage());
            }
            
            return $pdo;
        } catch (PDOException $e) {
            error_log('Database connection error: ' . $e->getMessage());
            http_response_code(500);
            echo json_encode(['success' => false, 'error' => 'Database connection failed: ' . $e->getMessage()]);
            exit;
        }
    }
    
    return $pdo;
}

// Initialize the database connection when this file is included
initAuth();
