<?php
header('Content-Type: application/json; charset=utf-8');
header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Methods: GET, POST, OPTIONS');
header('Access-Control-Allow-Headers: Content-Type, Authorization, X-API-Key, User-Agent');

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

require_once 'config.php';

// API Security Configuration
define('API_KEY', 'ensi_app_2025_secure_key_v1'); // Change this to a secure random key
define('ALLOWED_USER_AGENTS', [
    'Dart/', // Flutter/Dart HTTP client
    'ensi-flutter-app', // Custom user agent for your app
]);

// Helper: Validate API access
function validateApiAccess() {
    // Check API Key
    $apiKey = $_SERVER['HTTP_X_API_KEY'] ?? $_GET['api_key'] ?? '';
    if ($apiKey !== API_KEY) {
        http_response_code(403);
        echo json_encode([
            'success' => false,
            'message' => 'Unauthorized access. Invalid API key.',
            'status_code' => 403
        ]);
        exit;
    }
    
    // Check User Agent
    $userAgent = $_SERVER['HTTP_USER_AGENT'] ?? '';
    $isValidUserAgent = false;
    
    foreach (ALLOWED_USER_AGENTS as $allowedAgent) {
        if (strpos($userAgent, $allowedAgent) !== false) {
            $isValidUserAgent = true;
            break;
        }
    }
    
    if (!$isValidUserAgent) {
        http_response_code(403);
        echo json_encode([
            'success' => false,
            'message' => 'Unauthorized access. Invalid client.',
            'status_code' => 403
        ]);
        exit;
    }
    
    // Optional: Log access attempts for monitoring
    error_log("API Access: " . $userAgent . " from " . ($_SERVER['REMOTE_ADDR'] ?? 'unknown'));
}

// Validate API access before processing any requests
validateApiAccess();

// Helper: get user_level from session token
function getUserLevelFromToken($conn, $token) {
    if (!$token) return 'guest';
    
    try {
        // Query user_sessions table and join with users to get user_level
        $stmt = $conn->prepare('
            SELECT u.user_level 
            FROM user_sessions s 
            JOIN users u ON s.user_id = u.id 
            WHERE s.token = ? AND s.expires_at > NOW()
        ');
        $stmt->execute([$token]);
        $row = $stmt->fetch(PDO::FETCH_ASSOC);
        return $row ? $row['user_level'] : 'guest';
    } catch (PDOException $e) {
        // Log the error but don't fail - return guest level as fallback
        error_log("Token validation error: " . $e->getMessage());
        return 'guest';
    }
}

// Helper: check if user_level can access lesson_access_level
// Supports both single role (e.g., 'pro') and multiple roles (e.g., 'guest,registered,pro')
function canAccess($userLevel, $lessonAccessLevel) {
    // If no access level set or empty, default to guest (accessible to all)
    if (empty($lessonAccessLevel)) {
        return true;
    }
    
    // Split comma-separated roles
    $allowedRoles = array_map('trim', explode(',', $lessonAccessLevel));
    
    // Check if user's level is in the allowed roles
    return in_array($userLevel, $allowedRoles);
}

try {
    $conn = getDBConnection();
    
    if (!$conn) {
        sendResponse(false, 'Database connection failed');
    }
    $action = $_GET['action'] ?? 'list';
    
    switch ($action) {
        case 'list':
            // Get all lessons grouped by level, with access control
            $token = $_GET['token'] ?? '';
            $userLevel = getUserLevelFromToken($conn, $token);
            $stmt = $conn->prepare("
                SELECT * FROM lessons 
                WHERE is_active = 1 
                ORDER BY level ASC, order_index ASC
            ");
            $stmt->execute();
            $lessons = $stmt->fetchAll(PDO::FETCH_ASSOC);
            // Group by level
            $groupedLessons = [];
            foreach ($lessons as $lesson) {
                // Default to 'guest' if not set
                $accessLevel = $lesson['access_level'] ?? 'guest';
                if (!canAccess($userLevel, $accessLevel)) continue;
                $level = $lesson['level'];
                if (!isset($groupedLessons[$level])) {
                    $groupedLessons[$level] = [];
                }
                // Decode JSON fields
                $lesson['pronunciation_phrases'] = json_decode($lesson['pronunciation_phrases'] ?? '[]');
                $lesson['listen_write_phrases'] = json_decode($lesson['listen_write_phrases'] ?? '[]');
                // Convert flags to boolean
                $lesson['has_video'] = (bool)$lesson['has_video'];
                $lesson['has_audio'] = (bool)$lesson['has_audio'];
                $lesson['has_reading'] = (bool)$lesson['has_reading'];
                $lesson['has_pronunciation'] = (bool)$lesson['has_pronunciation'];
                $lesson['has_listen_write'] = (bool)$lesson['has_listen_write'];
                $lesson['has_comments'] = (bool)$lesson['has_comments'];
                $groupedLessons[$level][] = $lesson;
            }
            
            // Ensure groupedLessons is always an object, not an array
            if (empty($groupedLessons)) {
                $groupedLessons = new stdClass();
            }
            
            sendResponse(true, 'Lessons retrieved successfully', [
                'levels' => array_keys($groupedLessons),
                'lessons' => $groupedLessons
            ]);
            break;
            
        case 'get':
            // Get single lesson
            $lessonId = $_GET['lesson_id'] ?? 0;
            $token = $_GET['token'] ?? '';
            if (!$lessonId) {
                sendResponse(false, 'Lesson ID is required');
            }
            $stmt = $conn->prepare("SELECT * FROM lessons WHERE id = ? AND is_active = 1");
            $stmt->execute([$lessonId]);
            $lesson = $stmt->fetch(PDO::FETCH_ASSOC);
            if (!$lesson) {
                sendResponse(false, 'Lesson not found');
            }
            $userLevel = getUserLevelFromToken($conn, $token);
            $accessLevel = $lesson['access_level'] ?? 'guest';
            if (!canAccess($userLevel, $accessLevel)) {
                sendResponse(false, 'Access denied: upgrade required', null, 403);
            }
            // Decode JSON fields
            $lesson['pronunciation_phrases'] = json_decode($lesson['pronunciation_phrases'] ?? '[]');
            $lesson['listen_write_phrases'] = json_decode($lesson['listen_write_phrases'] ?? '[]');
            // Convert flags to boolean
            $lesson['has_video'] = (bool)$lesson['has_video'];
            $lesson['has_audio'] = (bool)$lesson['has_audio'];
            $lesson['has_reading'] = (bool)$lesson['has_reading'];
            $lesson['has_pronunciation'] = (bool)$lesson['has_pronunciation'];
            $lesson['has_listen_write'] = (bool)$lesson['has_listen_write'];
            $lesson['has_comments'] = (bool)$lesson['has_comments'];
            sendResponse(true, 'Lesson retrieved successfully', $lesson);
            break;
            
        case 'by_level':
            // Get lessons by level with access control
            $level = $_GET['level'] ?? 0;
            $token = $_GET['token'] ?? '';
            
            if (!$level) {
                sendResponse(false, 'Level is required');
            }
            
            $userLevel = getUserLevelFromToken($conn, $token);
            
            $stmt = $conn->prepare("
                SELECT * FROM lessons 
                WHERE level = ? AND is_active = 1 
                ORDER BY order_index ASC
            ");
            $stmt->execute([$level]);
            $lessons = $stmt->fetchAll(PDO::FETCH_ASSOC);
            
            $accessibleLessons = [];
            foreach ($lessons as $lesson) {
                $accessLevel = $lesson['access_level'] ?? 'guest';
                $hasAccess = canAccess($userLevel, $accessLevel);
                
                // Add is_locked and required_level fields
                $lesson['is_locked'] = !$hasAccess;
                $lesson['required_level'] = $accessLevel;
                
                // If locked, limit content to preview only
                if (!$hasAccess) {
                    $lesson['content'] = substr($lesson['content'] ?? '', 0, 100) . '...';
                    $lesson['video_url'] = null; // Remove video access
                }
                
                $lesson['pronunciation_phrases'] = json_decode($lesson['pronunciation_phrases'] ?? '[]');
                $lesson['listen_write_phrases'] = json_decode($lesson['listen_write_phrases'] ?? '[]');
                
                $lesson['has_video'] = (bool)$lesson['has_video'];
                $lesson['has_audio'] = (bool)$lesson['has_audio'];
                $lesson['has_reading'] = (bool)$lesson['has_reading'];
                $lesson['has_pronunciation'] = (bool)$lesson['has_pronunciation'];
                $lesson['has_listen_write'] = (bool)$lesson['has_listen_write'];
                $lesson['has_comments'] = (bool)$lesson['has_comments'];
                
                $accessibleLessons[] = $lesson;
            }
            
            sendResponse(true, 'Lessons retrieved successfully', [
                'level' => $level,
                'lessons' => $accessibleLessons
            ]);
            break;
            
        case 'paginated':
            // Get lessons with pagination based on level range with access control
            $startLevel = (int)($_GET['start_level'] ?? 1);
            $endLevel = (int)($_GET['end_level'] ?? 1);
            $token = $_GET['token'] ?? '';
            
            if ($startLevel < 1 || $endLevel < $startLevel) {
                sendResponse(false, 'Invalid level range');
            }
            
            $userLevel = getUserLevelFromToken($conn, $token);
            
            // Get lessons in the specified level range
            $stmt = $conn->prepare("
                SELECT * FROM lessons 
                WHERE level BETWEEN ? AND ? AND is_active = 1 
                ORDER BY level ASC, order_index ASC
            ");
            $stmt->execute([$startLevel, $endLevel]);
            $lessons = $stmt->fetchAll(PDO::FETCH_ASSOC);
            
            // Group by level and format data with access control
            $groupedLessons = [];
            $levels = [];
            
            foreach ($lessons as $lesson) {
                $accessLevel = $lesson['access_level'] ?? 'guest';
                $hasAccess = canAccess($userLevel, $accessLevel);
                
                // Add is_locked and required_level fields
                $lesson['is_locked'] = !$hasAccess;
                $lesson['required_level'] = $accessLevel;
                
                // If locked, limit content to preview only
                if (!$hasAccess) {
                    $lesson['content'] = substr($lesson['content'] ?? '', 0, 100) . '...';
                    $lesson['video_url'] = null; // Remove video access
                }
                
                $level = $lesson['level'];
                if (!in_array($level, $levels)) {
                    $levels[] = $level;
                }
                
                if (!isset($groupedLessons[$level])) {
                    $groupedLessons[$level] = [];
                }
                
                // Decode JSON fields and convert flags
                $lesson['pronunciation_phrases'] = json_decode($lesson['pronunciation_phrases'] ?? '[]');
                $lesson['listen_write_phrases'] = json_decode($lesson['listen_write_phrases'] ?? '[]');
                
                $lesson['has_video'] = (bool)$lesson['has_video'];
                $lesson['has_audio'] = (bool)$lesson['has_audio'];
                $lesson['has_reading'] = (bool)$lesson['has_reading'];
                $lesson['has_pronunciation'] = (bool)$lesson['has_pronunciation'];
                $lesson['has_listen_write'] = (bool)$lesson['has_listen_write'];
                $lesson['has_comments'] = (bool)$lesson['has_comments'];
                
                $groupedLessons[$level][] = $lesson;
            }
            
            // Get max level available
            $stmt = $conn->prepare("SELECT MAX(level) as max_level FROM lessons WHERE is_active = 1");
            $stmt->execute();
            $maxLevelData = $stmt->fetch(PDO::FETCH_ASSOC);
            $maxLevel = $maxLevelData['max_level'] ?? 1;
            
            // Ensure groupedLessons is always an object, not an array
            if (empty($groupedLessons)) {
                $groupedLessons = new stdClass();
            }
            
            sendResponse(true, 'Paginated lessons retrieved successfully', [
                'start_level' => $startLevel,
                'end_level' => $endLevel,
                'max_level' => $maxLevel,
                'has_more_before' => $startLevel > 1,
                'has_more_after' => $endLevel < $maxLevel,
                'levels' => $levels,
                'lessons' => $groupedLessons
            ]);
            break;
            
        case 'search':
            // Search lessons by level number or content (title/description) with access control
            $query = $_GET['query'] ?? '';
            $token = $_GET['token'] ?? '';
            
            if (empty($query)) {
                sendResponse(false, 'Search query is required');
            }
            
            $query = trim($query);
            $userLevel = getUserLevelFromToken($conn, $token);
            
            // Check if query is a number (level search)
            if (is_numeric($query)) {
                $level = (int)$query;
                $stmt = $conn->prepare("
                    SELECT * FROM lessons 
                    WHERE level = ? AND is_active = 1 
                    ORDER BY order_index ASC
                ");
                $stmt->execute([$level]);
            } else {
                // Text search in title and description
                $searchTerm = '%' . $query . '%';
                $stmt = $conn->prepare("
                    SELECT * FROM lessons 
                    WHERE (title LIKE ? OR description LIKE ?) AND is_active = 1 
                    ORDER BY level ASC, order_index ASC
                ");
                $stmt->execute([$searchTerm, $searchTerm]);
            }
            
            $lessons = $stmt->fetchAll(PDO::FETCH_ASSOC);
            
            // Group by level and format data with access control
            $groupedLessons = [];
            $levels = [];
            
            foreach ($lessons as $lesson) {
                $accessLevel = $lesson['access_level'] ?? 'guest';
                $hasAccess = canAccess($userLevel, $accessLevel);
                
                // Add is_locked and required_level fields
                $lesson['is_locked'] = !$hasAccess;
                $lesson['required_level'] = $accessLevel;
                
                // If locked, limit content to preview only
                if (!$hasAccess) {
                    $lesson['content'] = substr($lesson['content'] ?? '', 0, 100) . '...';
                    $lesson['video_url'] = null; // Remove video access
                }
                
                $level = $lesson['level'];
                if (!in_array($level, $levels)) {
                    $levels[] = $level;
                }
                
                if (!isset($groupedLessons[$level])) {
                    $groupedLessons[$level] = [];
                }
                
                // Decode JSON fields and convert flags
                $lesson['pronunciation_phrases'] = json_decode($lesson['pronunciation_phrases'] ?? '[]');
                $lesson['listen_write_phrases'] = json_decode($lesson['listen_write_phrases'] ?? '[]');
                
                $lesson['has_video'] = (bool)$lesson['has_video'];
                $lesson['has_audio'] = (bool)$lesson['has_audio'];
                $lesson['has_reading'] = (bool)$lesson['has_reading'];
                $lesson['has_pronunciation'] = (bool)$lesson['has_pronunciation'];
                $lesson['has_listen_write'] = (bool)$lesson['has_listen_write'];
                $lesson['has_comments'] = (bool)$lesson['has_comments'];
                
                $groupedLessons[$level][] = $lesson;
            }
            
            // Ensure groupedLessons is always an object, not an array
            if (empty($groupedLessons)) {
                $groupedLessons = new stdClass();
            }
            
            sendResponse(true, 'Search completed successfully', [
                'query' => $query,
                'total_results' => count($lessons),
                'levels' => $levels,
                'lessons' => $groupedLessons
            ]);
            break;
            
        default:
            sendResponse(false, 'Invalid action');
    }
    
} catch (PDOException $e) {
    error_log("Lessons API PDO error: " . $e->getMessage());
    error_log("Request parameters: " . json_encode($_GET));
    sendResponse(false, 'Database error occurred');
} catch (Exception $e) {
    error_log("Lessons API general error: " . $e->getMessage());
    error_log("Request parameters: " . json_encode($_GET));
    sendResponse(false, 'An error occurred while fetching lessons');
}
