<?php
/**
 * Zen Zone Spa API Entry Point - SECURE VERSION
 * Main router for all API endpoints with comprehensive security
 */

// Load security configuration first
require_once 'config/security.php';

// Security headers and environment setup
SecurityConfig::setSecurityHeaders();

// Rate limiting
SecurityConfig::checkRateLimit();

// Set timezone
date_default_timezone_set('Africa/Kigali');

// Environment-based error reporting
if (SecurityConfig::env('DEBUG_MODE', false)) {
    error_reporting(E_ALL);
    ini_set('display_errors', 1);
} else {
    error_reporting(0);
    ini_set('display_errors', 0);
    ini_set('log_errors', 1);
}

// Include required files
require_once 'utils/Response.php';
require_once 'controllers/AuthController.php';
require_once 'controllers/ContactController.php';
require_once 'controllers/MassageController.php';
require_once 'controllers/ExpenseController.php';
require_once 'controllers/ReportController.php';

// Log API access
SecurityConfig::logSecurityEvent('api_access', [
    'endpoint' => $_SERVER['REQUEST_URI'] ?? '',
    'method' => $_SERVER['REQUEST_METHOD'] ?? '',
    'user_agent' => substr($_SERVER['HTTP_USER_AGENT'] ?? '', 0, 200)
]);

// Handle CORS preflight requests
Response::handleCORS();

// Validate origin for additional security
SecurityConfig::validateOrigin();

// Get request information
$request_method = $_SERVER['REQUEST_METHOD'];
$request_uri = $_SERVER['REQUEST_URI'];

// Remove query string and decode URL
$uri_parts = explode('?', $request_uri);
$path = urldecode($uri_parts[0]);

// Remove base path if API is in subdirectory
$base_path = '/backend'; // Adjust based on your cPanel directory structure
if (strpos($path, $base_path) === 0) {
    $path = substr($path, strlen($base_path));
}

// Remove leading and trailing slashes
$path = trim($path, '/');

// Split path into segments
$path_segments = $path ? explode('/', $path) : [];

// Input validation and sanitization
$input = [];
try {
    if ($request_method === 'POST' || $request_method === 'PUT') {
        $raw_input = file_get_contents('php://input');
        $input = json_decode($raw_input, true);
        
        if (json_last_error() !== JSON_ERROR_NONE) {
            SecurityConfig::logSecurityEvent('invalid_json', [
                'error' => json_last_error_msg()
            ]);
            Response::error('Invalid JSON format', 400);
        }
        
        // Sanitize input data - skip null values to prevent PHP deprecation warnings
        if ($input && is_array($input)) {
            $input = SecurityConfig::sanitizeInput($input);
        }
    }
} catch (Exception $e) {
    SecurityConfig::logSecurityEvent('input_processing_error', [
        'error' => $e->getMessage()
    ]);
    Response::error('Invalid request format', 400);
}

try {
    // Route requests
    if (empty($path_segments)) {
        // API root - return API information
        Response::success([
            'name' => 'Zen Zone Spa API',
            'version' => SecurityConfig::env('API_VERSION', '1.0.0'),
            'description' => 'Secure RESTful API for Zen Zone Spa Management System',
            'environment' => SecurityConfig::env('API_ENVIRONMENT', 'production'),
            'security' => [
                'https_enforced' => SecurityConfig::isHTTPS(),
                'rate_limiting' => true,
                'input_validation' => true,
                'sql_injection_protection' => true
            ],
            'endpoints' => [
                'auth' => [
                    'POST /auth/login' => 'User authentication',
                    'POST /auth/register' => 'User registration',
                    'POST /auth/logout' => 'User logout',
                    'GET /auth/profile' => 'Get user profile',
                    'POST /auth/validate' => 'Validate token',
                    'POST /auth/change-password' => 'Change password'
                ],
                'massages' => [
                    'GET /massages' => 'Get all massages',
                    'POST /massages' => 'Create new massage session',
                    'GET /massages/{id}' => 'Get specific massage',
                    'PUT /massages/{id}' => 'Update massage',
                    'DELETE /massages/{id}' => 'Delete massage'
                ],
                'expenses' => [
                    'GET /expenses' => 'Get all expenses',
                    'POST /expenses' => 'Create new expense',
                    'GET /expenses/{id}' => 'Get specific expense',
                    'PUT /expenses/{id}' => 'Update expense',
                    'DELETE /expenses/{id}' => 'Delete expense'
                ],
                'reports' => [
                    'GET /reports/dashboard' => 'Get dashboard data',
                    'GET /reports/revenue' => 'Get revenue reports',
                    'GET /reports/expenses' => 'Get expense reports',
                    'GET /reports/therapists' => 'Get therapist performance'
                ],
                'contact' => [
                    'POST /contact' => 'Submit contact inquiry',
                    'GET /contact/inquiries' => 'Get all contact inquiries',
                    'GET /contact/inquiries/{id}' => 'Get specific inquiry',
                    'PUT /contact/inquiries/{id}' => 'Update inquiry status',
                    'GET /contact/stats' => 'Get contact statistics'
                ]
            ],
            'documentation' => SecurityConfig::env('DOCS_URL', '/backend/docs.html')
        ], 'Zen Zone Spa API v' . SecurityConfig::env('API_VERSION', '1.0.0'));
    }
    
    $endpoint = $path_segments[0];
    $action = $path_segments[1] ?? null;
    $id = $path_segments[2] ?? null;
    
    // Validate endpoint names
    $valid_endpoints = ['auth', 'massages', 'expenses', 'reports', 'contact', 'test', 'health'];
    if (!in_array($endpoint, $valid_endpoints)) {
        SecurityConfig::logSecurityEvent('invalid_endpoint', [
            'endpoint' => $endpoint
        ]);
        Response::notFound('Endpoint not found');
    }
    
    switch ($endpoint) {
        case 'auth':
            handleAuthRoutes($action, $request_method, $input);
            break;
            
        case 'massages':
            handleMassageRoutes($action, $id, $request_method, $input);
            break;
            
        case 'expenses':
            handleExpenseRoutes($action, $id, $request_method, $input);
            break;
            
        case 'reports':
            handleReportRoutes($action, $request_method);
            break;
            
        case 'contact':
            handleContactRoutes($action, $id, $request_method, $input);
            break;
            
        case 'test':
            // Secure test endpoint
            if (SecurityConfig::env('API_ENVIRONMENT') === 'production') {
                Response::notFound('Endpoint not available in production');
            }
            handleTestEndpoint();
            break;
            
        case 'health':
            // Health check endpoint
            handleHealthCheck();
            break;
            
        default:
            Response::notFound('Endpoint not found');
    }
    
} catch (Exception $e) {
    // Log error without exposing sensitive information
    SecurityConfig::logSecurityEvent('api_error', [
        'error_code' => $e->getCode(),
        'endpoint' => $endpoint ?? 'unknown'
    ]);
    
    error_log("API Error: " . $e->getMessage());
    Response::serverError('Internal server error occurred');
}

/**
 * Handle authentication routes with enhanced security
 */
function handleAuthRoutes($action, $method, $input) {
    $controller = new AuthController();
    
    // Rate limiting for auth endpoints
    if (in_array($action, ['login', 'register', 'change-password'])) {
        SecurityConfig::checkRateLimit('auth_' . SecurityConfig::getClientIP());
    }
    
    switch ($action) {
        case 'login':
            if ($method !== 'POST') {
                Response::error('Method not allowed', 405);
            }
            $controller->login($input);
            break;
            
        case 'register':
            if ($method !== 'POST') {
                Response::error('Method not allowed', 405);
            }
            $controller->register($input);
            break;
            
        case 'logout':
            if ($method !== 'POST') {
                Response::error('Method not allowed', 405);
            }
            $controller->logout();
            break;
            
        case 'profile':
            if ($method !== 'GET') {
                Response::error('Method not allowed', 405);
            }
            $controller->profile();
            break;
            
        case 'validate':
            if ($method !== 'POST') {
                Response::error('Method not allowed', 405);
            }
            $controller->validateToken();
            break;
            
        case 'change-password':
            if ($method !== 'POST') {
                Response::error('Method not allowed', 405);
            }
            $controller->changePassword($input);
            break;
            
        default:
            Response::notFound('Auth endpoint not found');
    }
}

/**
 * Handle massage routes (placeholder for future implementation)
 */
function handleMassageRoutes($action, $id, $method, $input) {
    // Require authentication for all massage endpoints
    $user = AuthController::requireAuth();
    
    $controller = new MassageController();
    
    switch ($action) {
        case null:
            // /massages endpoint - CRUD operations based on method
            switch ($method) {
                case 'GET':
                    $controller->getAllMassages();
                    break;
                case 'POST':
                    $controller->createMassage($input);
                    break;
                default:
                    Response::error('Method not allowed', 405);
            }
            break;
            
        case 'types':
            // /massages/types - Get massage types
            if ($method === 'GET') {
                $controller->getMassageTypes();
            } else {
                Response::error('Method not allowed', 405);
            }
            break;
            
        case 'therapists':
            // /massages/therapists - Get therapists
            if ($method === 'GET') {
                $controller->getTherapists();
            } else {
                Response::error('Method not allowed', 405);
            }
            break;
            
        case 'pending-momo-payments':
            // /massages/pending-momo-payments - Get pending MoMo payments (Admin only)
            if ($method === 'GET') {
                $controller->getPendingMomoPayments();
            } else {
                Response::error('Method not allowed', 405);
            }
            break;
            
        default:
            // /massages/{id} - Single massage operations
            // or /massages/{id}/verify-payment - Verify payment
            if (is_numeric($action)) {
                $massageId = $action;
                
                // Check if there's a sub-action (like verify-payment)
                if ($id === 'verify-payment') {
                    // /massages/{id}/verify-payment
                    if ($method === 'PUT' || $method === 'POST') {
                        $controller->verifyMomoPayment($massageId, $input);
                    } else {
                        Response::error('Method not allowed. Use PUT or POST', 405);
                    }
                } else {
                    // Regular massage CRUD operations
                    switch ($method) {
                        case 'GET':
                            $controller->getMassage($massageId);
                            break;
                        case 'PUT':
                            $controller->updateMassage($massageId, $input);
                            break;
                        case 'DELETE':
                            $controller->deleteMassage($massageId);
                            break;
                        default:
                            Response::error('Method not allowed', 405);
                    }
                }
            } else {
                Response::notFound('Massage endpoint not found');
            }
    }
}

/**
 * Handle expense routes (placeholder for future implementation)  
 */
function handleExpenseRoutes($action, $id, $method, $input) {
    // Require authentication for all expense endpoints
    $user = AuthController::requireAuth();
    
    $controller = new ExpenseController();
    
    switch ($action) {
        case null:
            // /expenses endpoint - CRUD operations based on method
            switch ($method) {
                case 'GET':
                    $controller->getAllExpenses();
                    break;
                case 'POST':
                    $controller->createExpense($input);
                    break;
                default:
                    Response::error('Method not allowed', 405);
            }
            break;
            
        case 'categories':
            // /expenses/categories - Get expense categories
            if ($method === 'GET') {
                $controller->getExpenseCategories();
            } else {
                Response::error('Method not allowed', 405);
            }
            break;
            
        case 'stats':
            // /expenses/stats - Get expense statistics
            if ($method === 'GET') {
                $controller->getExpenseStats();
            } else {
                Response::error('Method not allowed', 405);
            }
            break;
            
        default:
            // /expenses/{id} - Single expense operations
            if (is_numeric($action)) {
                $expenseId = $action;
                switch ($method) {
                    case 'GET':
                        $controller->getExpense($expenseId);
                        break;
                    case 'PUT':
                        $controller->updateExpense($expenseId, $input);
                        break;
                    case 'DELETE':
                        $controller->deleteExpense($expenseId);
                        break;
                    default:
                        Response::error('Method not allowed', 405);
                }
            } else {
                Response::notFound('Expense endpoint not found');
            }
    }
}

/**
 * Handle report routes
 */
function handleReportRoutes($action, $method) {
    // Require authentication for all report endpoints
    AuthController::requireAuth();
    
    // Only allow GET requests for reports
    if ($method !== 'GET') {
        Response::error('Method not allowed', 405);
    }
    
    $controller = new ReportController();
    
    switch ($action) {
        case null:
        case 'dashboard':
            // /reports or /reports/dashboard - Dashboard summary
            $controller->getDashboard();
            break;
            
        case 'revenue':
            // /reports/revenue - Revenue reports
            $controller->getRevenue();
            break;
            
        case 'expenses':
            // /reports/expenses - Expense reports
            $controller->getExpenses();
            break;
            
        case 'therapists':
            // /reports/therapists - Therapist performance
            $controller->getTherapists();
            break;
            
        case 'analytics':
            // /reports/analytics - Business analytics
            $controller->getAnalytics();
            break;
            
        default:
            Response::notFound('Report endpoint not found');
    }
}

/**
 * Handle contact routes
 */
function handleContactRoutes($action, $id, $method, $input) {
    $controller = new ContactController();
    
    // Public endpoint for form submission - no auth required
    if ($action === null && $method === 'POST') {
        $controller->submitContact();
        return;
    }
    
    // All other endpoints require authentication
    AuthController::requireAuth();
    
    switch ($action) {
        case 'inquiries':
            if ($id) {
                // Single inquiry operations
                switch ($method) {
                    case 'GET':
                        $controller->getInquiry($id);
                        break;
                    case 'PUT':
                        $controller->updateInquiry($id);
                        break;
                    default:
                        Response::error('Method not allowed', 405);
                }
            } else {
                // All inquiries
                if ($method === 'GET') {
                    $controller->getInquiries();
                } else {
                    Response::error('Method not allowed', 405);
                }
            }
            break;
            
        case 'stats':
            if ($method === 'GET') {
                $controller->getContactStats();
            } else {
                Response::error('Method not allowed', 405);
            }
            break;
            
        default:
            Response::notFound('Contact endpoint not found');
    }
}

/**
 * Handle test endpoint (development only)
 */
function handleTestEndpoint() {
    Response::success([
        'status' => 'API is working',
        'method' => $_SERVER['REQUEST_METHOD'],
        'timestamp' => date('Y-m-d H:i:s'),
        'environment' => SecurityConfig::env('API_ENVIRONMENT'),
        'security_check' => [
            'https' => SecurityConfig::isHTTPS(),
            'headers_set' => true,
            'rate_limiting' => true
        ],
        'server_info' => [
            'php_version' => PHP_VERSION,
            'server_software' => $_SERVER['SERVER_SOFTWARE'] ?? 'Unknown'
        ]
    ], 'Test successful');
}

/**
 * Handle health check endpoint
 */
function handleHealthCheck() {
    $health = [
        'status' => 'healthy',
        'timestamp' => date('Y-m-d H:i:s'),
        'checks' => [
            'database' => DatabaseConfig::testConnection(),
            'filesystem' => is_writable(__DIR__ . '/logs'),
            'memory_usage' => round(memory_get_usage(true) / 1024 / 1024, 2) . ' MB'
        ]
    ];
    
    $overall_status = array_reduce($health['checks'], function($carry, $check) {
        return $carry && $check;
    }, true);
    
    $health['status'] = $overall_status ? 'healthy' : 'degraded';
    
    Response::success($health, 'Health check complete');
}

// Cleanup on script end
register_shutdown_function(function() {
    SecurityConfig::cleanup();
}); 