<?php
/**
 * Settings Controller
 * Handles all settings-related requests
 */
class SettingsController {
    
    private $settingsModel;
    
    public function __construct() {
        // Initialize settings model
        $this->settingsModel = new SettingsModel();
        
        // Check authentication
        $this->checkAuth();
    }
    
    /**
     * Check if user is authenticated and has permission
     */
    private function checkAuth() {
        // Start session if not started
        if (session_status() === PHP_SESSION_NONE) {
            session_start();
        }
        
        // Check if user is logged in
        if (!isset($_SESSION['user_id'])) {
            $this->redirect('auth/login');
            return;
        }
        
        // Check if user is super admin (you can modify this based on your Auth class)
        $isSuperAdmin = isset($_SESSION['is_super_admin']) && $_SESSION['is_super_admin'] === true;
        
        // Check via Auth class if it exists
        if (!$isSuperAdmin && class_exists('Auth')) {
            $isSuperAdmin = Auth::isSuperAdmin();
        }
        
        // Check roles array
        if (!$isSuperAdmin && isset($_SESSION['roles']) && is_array($_SESSION['roles'])) {
            foreach ($_SESSION['roles'] as $role) {
                if (stripos($role, 'Super Admin') !== false || stripos($role, 'SuperAdmin') !== false) {
                    $isSuperAdmin = true;
                    break;
                }
            }
        }
        
        if (!$isSuperAdmin) {
            $_SESSION['error'] = 'You do not have permission to access system settings';
            $this->redirect('dashboard');
            return;
        }
    }
    
    /**
     * Display settings page
     */
    public function index() {
        $settings = $this->settingsModel->getAllSettings();
        $groups = $this->settingsModel->getGroups();
        
        // Pass data to view
        require_once __DIR__ . '/../views/settings/index.php';
    }
    
    /**
     * Update settings (AJAX)
     */
    public function update() {
        // Check CSRF token
        if (!$this->validateCsrf()) {
            $this->jsonResponse(false, 'Invalid security token');
            return;
        }
        
        $settings = $_POST['settings'] ?? [];
        
        if (empty($settings)) {
            $this->jsonResponse(false, 'No settings to update');
            return;
        }
        
        // Process and validate settings
        $processed = [];
        foreach ($settings as $key => $value) {
            $type = $_POST['types'][$key] ?? 'string';
            $group = $_POST['groups'][$key] ?? 'general';
            $description = $_POST['descriptions'][$key] ?? '';
            $isEncrypted = isset($_POST['encrypted'][$key]) && $_POST['encrypted'][$key] === '1';
            
            // Validate based on type
            $validated = $this->validateValue($value, $type);
            if ($validated['error']) {
                $this->jsonResponse(false, $validated['message']);
                return;
            }
            
            $processed[$key] = [
                'value' => $validated['value'],
                'data_type' => $type,
                'group' => $group,
                'description' => $description,
                'is_encrypted' => $isEncrypted
            ];
        }
        
        // Save to database
        if ($this->settingsModel->saveSettings($processed)) {
            $this->logActivity('settings_updated', 'System settings were updated');
            $this->jsonResponse(true, 'Settings saved successfully');
        } else {
            $this->jsonResponse(false, 'Failed to save settings');
        }
    }
    
    /**
     * Add new setting (AJAX)
     */
    public function add() {
        // Check CSRF token
        if (!$this->validateCsrf()) {
            $this->jsonResponse(false, 'Invalid security token');
            return;
        }
        
        $key = $_POST['key'] ?? '';
        $value = $_POST['value'] ?? '';
        $group = $_POST['group'] ?? 'general';
        $type = $_POST['type'] ?? 'string';
        $description = $_POST['description'] ?? '';
        $isEncrypted = isset($_POST['is_encrypted']) && $_POST['is_encrypted'] === '1';
        
        // Validate
        if (empty($key)) {
            $this->jsonResponse(false, 'Setting key is required');
            return;
        }
        
        if (!preg_match('/^[a-zA-Z0-9_\.]+$/', $key)) {
            $this->jsonResponse(false, 'Invalid setting key format. Use only letters, numbers, dots and underscores');
            return;
        }
        
        // Check if key already exists
        $existing = $this->settingsModel->getSetting($key);
        if ($existing !== null) {
            $this->jsonResponse(false, 'Setting key already exists');
            return;
        }
        
        // Validate value based on type
        $validated = $this->validateValue($value, $type);
        if ($validated['error']) {
            $this->jsonResponse(false, $validated['message']);
            return;
        }
        
        // Save
        if ($this->settingsModel->saveSetting($key, $validated['value'], $group, $type, $description, $isEncrypted)) {
            $this->logActivity('setting_added', "Added new setting: {$key}");
            $this->jsonResponse(true, 'Setting added successfully');
        } else {
            $this->jsonResponse(false, 'Failed to add setting');
        }
    }
    
    /**
     * Delete setting (AJAX)
     */
    public function delete() {
        // Check CSRF token
        if (!$this->validateCsrf()) {
            $this->jsonResponse(false, 'Invalid security token');
            return;
        }
        
        $key = $_POST['key'] ?? '';
        
        if (empty($key)) {
            $this->jsonResponse(false, 'Setting key is required');
            return;
        }
        
        // Prevent deletion of critical settings
        $protected = ['app_name', 'app_version', 'app_url', 'encryption_key'];
        if (in_array($key, $protected)) {
            $this->jsonResponse(false, 'Cannot delete protected system setting');
            return;
        }
        
        if ($this->settingsModel->deleteSetting($key)) {
            $this->logActivity('setting_deleted', "Deleted setting: {$key}");
            $this->jsonResponse(true, 'Setting deleted successfully');
        } else {
            $this->jsonResponse(false, 'Failed to delete setting');
        }
    }
    
    /**
     * Export settings as JSON
     */
    public function export() {
        $settings = $this->settingsModel->getAllSettings();
        
        header('Content-Type: application/json');
        header('Content-Disposition: attachment; filename="settings-export-' . date('Y-m-d') . '.json"');
        echo json_encode($settings, JSON_PRETTY_PRINT);
        exit;
    }
    
    /**
     * Import settings from JSON
     */
    public function import() {
        // Check CSRF token
        if (!$this->validateCsrf()) {
            $this->jsonResponse(false, 'Invalid security token');
            return;
        }
        
        if (!isset($_FILES['import_file']) || $_FILES['import_file']['error'] !== UPLOAD_ERR_OK) {
            $this->jsonResponse(false, 'Please upload a valid JSON file');
            return;
        }
        
        $content = file_get_contents($_FILES['import_file']['tmp_name']);
        $settings = json_decode($content, true);
        
        if (!$settings) {
            $this->jsonResponse(false, 'Invalid JSON file');
            return;
        }
        
        $processed = [];
        foreach ($settings as $group => $groupSettings) {
            foreach ($groupSettings as $setting) {
                $key = $setting['setting_key'];
                $value = $setting['setting_value'];
                $type = $setting['data_type'] ?? 'string';
                $description = $setting['description'] ?? '';
                $isEncrypted = $setting['is_encrypted'] ?? false;
                
                $processed[$key] = [
                    'value' => $value,
                    'data_type' => $type,
                    'group' => $group,
                    'description' => $description,
                    'is_encrypted' => $isEncrypted
                ];
            }
        }
        
        if ($this->settingsModel->saveSettings($processed)) {
            $this->logActivity('settings_imported', 'Settings were imported from file');
            $this->jsonResponse(true, 'Settings imported successfully');
        } else {
            $this->jsonResponse(false, 'Failed to import settings');
        }
    }
    
    /**
     * Validate value based on type
     */
    private function validateValue($value, $type) {
        $result = ['error' => false, 'value' => $value, 'message' => ''];
        
        switch ($type) {
            case 'email':
                if ($value && !filter_var($value, FILTER_VALIDATE_EMAIL)) {
                    $result['error'] = true;
                    $result['message'] = 'Invalid email format';
                }
                break;
                
            case 'url':
                if ($value && !filter_var($value, FILTER_VALIDATE_URL)) {
                    $result['error'] = true;
                    $result['message'] = 'Invalid URL format';
                }
                break;
                
            case 'number':
            case 'integer':
                if ($value && !is_numeric($value)) {
                    $result['error'] = true;
                    $result['message'] = 'Must be a number';
                } else {
                    $result['value'] = (int)$value;
                }
                break;
                
            case 'float':
            case 'double':
                if ($value && !is_numeric($value)) {
                    $result['error'] = true;
                    $result['message'] = 'Must be a number';
                } else {
                    $result['value'] = (float)$value;
                }
                break;
                
            case 'boolean':
            case 'bool':
                $result['value'] = filter_var($value, FILTER_VALIDATE_BOOLEAN);
                break;
                
            case 'json':
                if ($value) {
                    json_decode($value);
                    if (json_last_error() !== JSON_ERROR_NONE) {
                        $result['error'] = true;
                        $result['message'] = 'Invalid JSON format';
                    }
                }
                break;
                
            case 'array':
                // Keep as string, will be processed by model
                break;
        }
        
        return $result;
    }
    
    /**
     * JSON response helper
     */
    private function jsonResponse($success, $message, $data = []) {
        header('Content-Type: application/json');
        echo json_encode([
            'success' => $success,
            'message' => $message,
            'data' => $data
        ]);
        exit;
    }
    
    /**
     * Validate CSRF token
     */
    private function validateCsrf() {
        $token = $_POST['csrf_token'] ?? $_SERVER['HTTP_X_CSRF_TOKEN'] ?? '';
        
        if (session_status() === PHP_SESSION_NONE) {
            session_start();
        }
        
        return isset($_SESSION['csrf_token']) && hash_equals($_SESSION['csrf_token'], $token);
    }
    
    /**
     * Redirect helper
     */
    private function redirect($url) {
        $baseUrl = defined('BASE_URL') ? BASE_URL : 'http://localhost/nis_ams';
        header('Location: ' . $baseUrl . '/' . ltrim($url, '/'));
        exit;
    }
    
    /**
     * Log activity
     */
    private function logActivity($action, $description) {
        if (class_exists('AuditLogger')) {
            AuditLogger::log($action, 'settings', null, null, $description);
        } else {
            // Simple file logging as fallback
            $logFile = __DIR__ . '/../logs/settings.log';
            $logDir = dirname($logFile);
            
            if (!is_dir($logDir)) {
                mkdir($logDir, 0777, true);
            }
            
            $logEntry = date('Y-m-d H:i:s') . " | {$action} | {$description} | User: " . ($_SESSION['user_id'] ?? 'unknown') . PHP_EOL;
            file_put_contents($logFile, $logEntry, FILE_APPEND);
        }
    }
}