<?php

class PermissionScanner
{
    private $viewsPath;
    private $controllersPath;
    
    public function __construct()
    {
        $this->viewsPath = __DIR__ . '/../Views';
        $this->controllersPath = __DIR__ . '/../Controllers';
    }
    
    /**
     * Scan all views and controllers to generate permissions automatically
     */
    public function generatePermissions()
    {
        $permissions = [];
        
        // Scan view directories
        $viewPermissions = $this->scanViewDirectories();
        $permissions = array_merge($permissions, $viewPermissions);
        
        // Scan controllers for specific actions
        $controllerPermissions = $this->scanControllers();
        $permissions = array_merge($permissions, $controllerPermissions);
        
        // Add system-wide permissions
        $systemPermissions = $this->getSystemPermissions();
        $permissions = array_merge($permissions, $systemPermissions);
        
        return $permissions;
    }
    
    /**
     * Scan view directories to detect modules
     */
    private function scanViewDirectories()
    {
        $permissions = [];
        $viewsDir = $this->viewsPath;
        
        if (!is_dir($viewsDir)) {
            return $permissions;
        }
        
        $directories = array_filter(glob($viewsDir . '/*'), 'is_dir');
        
        foreach ($directories as $dir) {
            $moduleName = basename($dir);
            
            // Skip common directories
            if (in_array($moduleName, ['layouts', 'partials', 'includes'])) {
                continue;
            }
            
            // Generate CRUD permissions for each module
            $modulePermissions = $this->generateModulePermissions($moduleName);
            $permissions = array_merge($permissions, $modulePermissions);
        }
        
        return $permissions;
    }
    
    /**
     * Generate standard CRUD permissions for a module
     */
    private function generateModulePermissions($moduleName)
    {
        $permissions = [];
        $actions = ['view', 'create', 'edit', 'delete'];
        
        foreach ($actions as $action) {
            $permissionKey = $moduleName . '_' . $action;
            $permissions[$permissionKey] = [
                'key' => $permissionKey,
                'name' => ucfirst($action) . ' ' . ucwords(str_replace('_', ' ', $moduleName)),
                'category' => ucfirst($moduleName),
                'description' => ucfirst($action) . ' access to ' . str_replace('_', ' ', $moduleName) . ' module'
            ];
        }
        
        return $permissions;
    }
    
    /**
     * Scan controllers for specific actions
     */
    private function scanControllers()
    {
        $permissions = [];
        $controllersDir = $this->controllersPath;
        
        if (!is_dir($controllersDir)) {
            return $permissions;
        }
        
        $controllers = glob($controllersDir . '/*.php');
        
        foreach ($controllers as $controllerFile) {
            $controllerName = basename($controllerFile, '.php');
            
            // Skip base controllers
            if (in_array($controllerName, ['Controller', 'BaseController'])) {
                continue;
            }
            
            $controllerPermissions = $this->scanControllerMethods($controllerFile, $controllerName);
            $permissions = array_merge($permissions, $controllerPermissions);
        }
        
        return $permissions;
    }
    
    /**
     * Scan controller methods to detect actions
     */
    private function scanControllerMethods($filePath, $controllerName)
    {
        $permissions = [];
        $content = file_get_contents($filePath);
        
        // Extract public methods
        preg_match_all('/public\s+function\s+(\w+)\s*\(/', $content, $matches);
        
        if (!empty($matches[1])) {
            $moduleName = strtolower(str_replace('Controller', '', $controllerName));
            
            foreach ($matches[1] as $method) {
                // Skip common methods
                if (in_array($method, ['__construct', 'view', 'redirect', 'json'])) {
                    continue;
                }
                
                $permissionKey = $moduleName . '_' . strtolower($method);
                $permissions[$permissionKey] = [
                    'key' => $permissionKey,
                    'name' => ucfirst($method) . ' ' . ucfirst($moduleName),
                    'category' => ucfirst($moduleName),
                    'description' => ucfirst($method) . ' action in ' . $moduleName . ' controller'
                ];
            }
        }
        
        return $permissions;
    }
    
    /**
     * Get system-wide permissions
     */
    private function getSystemPermissions()
    {
        return [
            // Translations explicit module permissions (since no separate directory)
            'translations_view' => [
                'key' => 'translations_view',
                'name' => 'View Translations',
                'category' => 'Translations',
                'description' => 'View translation entries'
            ],
            'translations_create' => [
                'key' => 'translations_create',
                'name' => 'Create Translations',
                'category' => 'Translations',
                'description' => 'Add new translation entries'
            ],
            'translations_edit' => [
                'key' => 'translations_edit',
                'name' => 'Edit Translations',
                'category' => 'Translations',
                'description' => 'Modify existing translations'
            ],
            'translations_delete' => [
                'key' => 'translations_delete',
                'name' => 'Delete Translations',
                'category' => 'Translations',
                'description' => 'Remove translation entries'
            ],
            'admin_panel' => [
                'key' => 'admin_panel',
                'name' => 'Admin Panel Access',
                'category' => 'System',
                'description' => 'Access to administrative panel'
            ],
            'system_settings' => [
                'key' => 'system_settings',
                'name' => 'System Settings',
                'category' => 'System',
                'description' => 'Manage system-wide settings'
            ],
            'user_management' => [
                'key' => 'user_management',
                'name' => 'User Management',
                'category' => 'System',
                'description' => 'Manage users and user types'
            ],
            'reports_view' => [
                'key' => 'reports_view',
                'name' => 'View Reports',
                'category' => 'Reports',
                'description' => 'Access to system reports'
            ],
            'reports_export' => [
                'key' => 'reports_export',
                'name' => 'Export Reports',
                'category' => 'Reports',
                'description' => 'Export reports and data'
            ]
        ];
    }
    
    /**
     * Get permissions organized by category
     */
    public function getPermissionsByCategory()
    {
        $permissions = $this->generatePermissions();
        $categorized = [];
        
        foreach ($permissions as $permission) {
            $category = $permission['category'];
            $categorized[$category][] = $permission;
        }
        
        // Sort categories and permissions
        ksort($categorized);
        foreach ($categorized as &$categoryPermissions) {
            usort($categoryPermissions, function($a, $b) {
                return strcmp($a['name'], $b['name']);
            });
        }
        
        return $categorized;
    }
    
    /**
     * Check if a new permission should be automatically added
     */
    public function shouldAutoAddPermission($permissionKey)
    {
        $autoAddPatterns = [
            '/^[a-z_]+_view$/',     // View permissions
            '/^[a-z_]+_create$/',   // Create permissions
            '/^[a-z_]+_edit$/',     // Edit permissions
            '/^[a-z_]+_delete$/',   // Delete permissions
        ];
        
        foreach ($autoAddPatterns as $pattern) {
            if (preg_match($pattern, $permissionKey)) {
                return true;
            }
        }
        
        return false;
    }
    
    /**
     * Sync permissions with database (add new, keep existing)
     */
    public function syncPermissionsToDatabase()
    {
        require_once __DIR__ . '/UserType.php';
        $userTypeModel = new UserType();
        
        $generatedPermissions = $this->generatePermissions();
        
        // Get raw user types without JSON decoding
        $pdo = $GLOBALS['pdo'];
        $stmt = $pdo->query("SELECT * FROM user_types ORDER BY name ASC");
        $existingUserTypes = $stmt->fetchAll(PDO::FETCH_ASSOC);
        
        foreach ($existingUserTypes as $userType) {
            // Handle both JSON string and array formats
            if (is_string($userType['permissions'])) {
                $currentPermissions = json_decode($userType['permissions'] ?? '{}', true);
                // Ensure json_decode didn't fail
                if (!is_array($currentPermissions)) {
                    $currentPermissions = [];
                }
            } elseif (is_array($userType['permissions'])) {
                $currentPermissions = $userType['permissions'];
            } else {
                $currentPermissions = [];
            }
            
            $updated = false;
            
            // Add new permissions with default false value
            foreach ($generatedPermissions as $permission) {
                // Ensure permission is a valid array with required fields
                if (!is_array($permission) || !isset($permission['key'])) {
                    continue;
                }
                
                if (!isset($currentPermissions[$permission['key']])) {
                    // Auto-grant view permissions to existing admin types
                    $isViewPermission = strpos($permission['key'], '_view') !== false;
                    $isAdmin = strpos(strtolower($userType['name']), 'admin') !== false;
                    
                    $currentPermissions[$permission['key']] = ($isAdmin && $isViewPermission);
                    $updated = true;
                }
            }
            
            // Update user type if permissions were added
            if ($updated) {
                $userTypeModel->update($userType['id'], [
                    'name' => $userType['name'],
                    'description' => $userType['description'],
                    'permissions' => $currentPermissions, // Pass as array, not JSON
                    'color' => $userType['color'],
                    'is_active' => $userType['is_active']
                ]);
            }
        }
        
        return count($generatedPermissions);
    }
}
