<?php
/**
 * BaseController
 * ----------------------------------------------------------------------
 * Acts as a parent controller class providing:
 * - Database connection handling
 * - Session management and access control
 * - Centralized error handling and logging
 * - Standardized response rendering
 * - Utility functions for derived controllers
 *
 * All other controllers (e.g., AppointmentController, PatientController)
 * should extend this class.
 * ----------------------------------------------------------------------
 */

require_once __DIR__ . '/../includes/db_connect.php';  // global database connection
require_once __DIR__ . '/../includes/functions.php';   // reusable helper functions

class BaseController
{
    /** @var mysqli */
    protected $conn;

    /** @var array */
    protected $errors = [];

    /** @var string */
    protected $viewPath = __DIR__ . '/../views/';

    /**
     * Constructor
     * Initializes database connection and session management
     */
    public function __construct()
    {
        // Inject global database connection
        $this->conn = $GLOBALS['conn'] ?? null;

        // Ensure connection availability
        if (!$this->conn) {
            $this->addError("Database connection not available");
        }

        // Initialize secure session
        $this->startSecureSession();

        // Validate session
        $this->validateSession();
    }

    /**
     * Starts a secure session with strict cookie parameters
     */
    protected function startSecureSession(): void
    {
        if (session_status() === PHP_SESSION_NONE) {
            session_set_cookie_params([
                'lifetime' => 0,
                'path' => '/',
                'secure' => isset($_SERVER['HTTPS']),
                'httponly' => true,
                'samesite' => 'Strict'
            ]);
            session_start();
        }
    }

    /**
     * Validates that a user is logged in and session is active
     */
    protected function validateSession(): void
    {
        // You can adjust this condition depending on your auth structure
        if (!isset($_SESSION['user_id'])) {
            $this->redirectToLogin();
        }

        // Optional: Implement session timeout
        $timeout = 1800; // 30 minutes
        if (isset($_SESSION['LAST_ACTIVITY']) && (time() - $_SESSION['LAST_ACTIVITY'] > $timeout)) {
            session_unset();
            session_destroy();
            $this->redirectToLogin();
        }
        $_SESSION['LAST_ACTIVITY'] = time();
    }

    /**
     * Redirects to login page if session invalid
     */
    protected function redirectToLogin(): void
    {
        header("Location: /dripdental/login.php");
        exit();
    }

    /**
     * Logs errors internally and optionally displays them in development
     */
    protected function addError(string $message): void
    {
        $this->errors[] = $message;
        error_log("[DripDental] " . $message);

        // Optionally display in development mode
        if ($this->isDevelopment()) {
            echo "<pre style='color:red;'>Error: {$message}</pre>";
        }
    }

    /**
     * Determines whether the environment is development
     */
    protected function isDevelopment(): bool
    {
        return ($_SERVER['SERVER_NAME'] === 'localhost' || strpos($_SERVER['SERVER_NAME'], '127.0.0.1') !== false);
    }

    /**
     * Renders a view with data variables passed as associative array
     * Automatically includes header, sidebar, and footer
     */
    protected function render(string $viewFile, array $data = []): void
    {
        $viewFullPath = $this->viewPath . $viewFile;

        if (!file_exists($viewFullPath)) {
            $this->addError("View file not found: " . $viewFullPath);
            return;
        }

        // Extract data into local variables for use in view
        extract($data);

        // Include shared layout components
        include __DIR__ . '/../../dripend/statpages/header.php';
        include __DIR__ . '/../../dripend/statpages/sidebar.php';

        include $viewFullPath;

        include __DIR__ . '/../../dripend/statpages/footer.php';
    }

    /**
     * Simple JSON response for API-like endpoints
     */
    protected function jsonResponse(array $data, int $statusCode = 200): void
    {
        http_response_code($statusCode);
        header('Content-Type: application/json');
        echo json_encode($data);
        exit();
    }

    /**
     * Gracefully terminates controller with unified error response
     */
    protected function handleException(Throwable $e): void
    {
        $this->addError("Exception: " . $e->getMessage());
        if ($this->isDevelopment()) {
            echo "<pre>Exception Trace:\n" . $e->getTraceAsString() . "</pre>";
        } else {
            $this->jsonResponse([
                'status' => 'error',
                'message' => 'An internal server error occurred. Please try again later.'
            ], 500);
        }
    }

    /**
     * Sanitizes inputs for security
     */
    protected function sanitize(string $input): string
    {
        return htmlspecialchars(trim($input), ENT_QUOTES, 'UTF-8');
    }
}
?>
