<?php
declare(strict_types=1);

/**
 * Updates Controller
 * RC Developments | info@rcdevelopments.co.za | +27 61 523 9126
 */
class Updates extends Controller {
    
    public function __construct() {
        if (!isLoggedIn() || !isAdmin()) {
            header('Location: ' . URLROOT . '/users/login');
            exit;
        }
    }

    public function index(): void {
        require_once dirname(__DIR__) . '/Core/AppClient.php';
        
        $keyFile = dirname(__DIR__, 2) . '/config/license.key';
        $licenseKey = file_exists($keyFile) ? trim(file_get_contents($keyFile)) : 'UNKNOWN';
        
        $vFile = dirname(__DIR__, 2) . '/version.php';
        $appVersion = file_exists($vFile) ? include $vFile : '1.0.0';
        
        $serverUrl = 'https://license.christodev.co.za';
        $cacheDir = dirname(__DIR__, 2) . '/public/cache';

        // Initialize SDK
        $client = new AppClient($serverUrl, $licenseKey, (string)$appVersion, $cacheDir);

        $data = [
            'title' => 'License & System Updates',
            'description' => 'Manage your software license, install OTA updates, and view release notes.',
            'current_version' => $appVersion,
            'license_key' => $licenseKey,
            'license' => $client->verifyLicense(),
            'update' => $client->checkUpdates(),
            'news' => $client->getNews(),
            
            // Contextual Help
            'help_title' => 'Software Lifecycle Management',
            'help_content' => '
                <h4 class="font-bold text-gray-800 dark:text-gray-200 mt-0">Software Lifecycle Management</h4>
                <p>This module connects your application directly to the ChristoDev licensing and distribution network.</p>
                <ul class="list-disc pl-5 space-y-2 mt-2">
                    <li><strong>OTA Updates:</strong> When a new version is available, you can securely download and apply the patch (including database migrations) directly from this screen. Clicking "Install Update" triggers the background processor.</li>
                    <li><strong>License Key:</strong> If your domain changes or you upgrade your license, you can update your registration key here. The system will automatically ping the central server to re-verify your status.</li>
                    <li><strong>Developer News:</strong> The accordion feed at the bottom provides real-time release notes, security bulletins, and global announcements from the development team.</li>
                    <li><strong>Force Sync:</strong> Use this button at the top of the page to clear the local server cache and force an immediate check for updates and news.</li>
                </ul>
            '
        ];

        $this->view('admin/updates', $data);
    }

    public function process(): void {
        if ($_SERVER['REQUEST_METHOD'] == 'POST') {
            require_once dirname(__DIR__) . '/Core/AppClient.php';
            
            $keyFile = dirname(__DIR__, 2) . '/config/license.key';
            $licenseKey = file_exists($keyFile) ? trim(file_get_contents($keyFile)) : '';
            
            $vFile = dirname(__DIR__, 2) . '/version.php';
            $appVersion = file_exists($vFile) ? include $vFile : '1.0.0';
            
            $serverUrl = 'https://license.christodev.co.za';
            $cacheDir = dirname(__DIR__, 2) . '/public/cache';

            $client = new AppClient($serverUrl, $licenseKey, (string)$appVersion, $cacheDir);
            $update = $client->checkUpdates();

            if (isset($update->update_available) && $update->update_available && !empty($update->download_url)) {
                require_once dirname(__DIR__) . '/Core/OtaUpdater.php';
                
                try {
                    $updater = new OtaUpdater(dirname(__DIR__, 2));
                    
                    // --- THE FIX: DYNAMIC DB VERSION TRACKING ---
                    $settings = getSettings(true); // Force refresh to get latest settings
                    $currentDbVersion = isset($settings['db_version']) ? (int)$settings['db_version'] : 0;
                    
                    // Pass the actual local DB version to the updater
                    $result = $updater->executeUpdate($update->download_url, $currentDbVersion);
                    
                    if ($result['success']) {
                        // Update the local database version tracker with the new integer
                        $settingModel = $this->model('Setting');
                        $settingModel->updateSetting('db_version', (string)$result['new_db_version']);
                        
                        // Clear the cache so it stops showing the update notification
                        if (is_dir($cacheDir)) { array_map('unlink', glob("$cacheDir/*.json")); }
                        
                        // Overwrite the local file version
                        file_put_contents($vFile, "<?php\ndeclare(strict_types=1);\n\nreturn '{$update->new_version}';\n");
                        
                        systemLog('OTA_UPDATE', "System was successfully updated to version {$update->new_version} (DB v{$result['new_db_version']})");
                        flash('system_msg', 'Application successfully updated to v' . $update->new_version, 'success');
                    } else {
                        flash('system_msg', 'Update Failed: ' . $result['message'], 'error');
                    }
                } catch (Exception $e) {
                    flash('system_msg', 'Critical Updater Error: ' . $e->getMessage(), 'error');
                }
            } else {
                flash('system_msg', 'No valid updates found or download URL missing.', 'error');
            }
            
            header('Location: ' . URLROOT . '/updates/index');
            exit;
        }
    }

    public function forceSync(): void {
        if ($_SERVER['REQUEST_METHOD'] == 'POST') {
            $cacheDir = dirname(__DIR__, 2) . '/public/cache';
            if (is_dir($cacheDir)) { 
                array_map('unlink', glob("$cacheDir/*.json")); 
            }
            flash('system_msg', 'Successfully synced with the master server.', 'success');
            header('Location: ' . URLROOT . '/updates/index');
            exit;
        }
    }

    public function updateKey(): void {
        if ($_SERVER['REQUEST_METHOD'] == 'POST') {
            $newKey = trim(filter_input(INPUT_POST, 'new_license_key', FILTER_SANITIZE_FULL_SPECIAL_CHARS) ?? '');
            
            if (!empty($newKey)) {
                $keyFile = dirname(__DIR__, 2) . '/config/license.key';
                
                // Ensure the config directory exists before writing
                if (!is_dir(dirname($keyFile))) {
                    mkdir(dirname($keyFile), 0755, true);
                }
                
                file_put_contents($keyFile, $newKey);
                
                // Clear the cache to force immediate validation against the master server
                $cacheDir = dirname(__DIR__, 2) . '/public/cache';
                if (is_dir($cacheDir)) { 
                    array_map('unlink', glob("$cacheDir/*.json")); 
                }
                
                systemLog('LICENSE_KEY_UPDATED', 'Admin updated the local license registration key.');
                flash('system_msg', 'License key updated. The system will re-validate immediately.', 'success');
            } else {
                flash('system_msg', 'License key cannot be empty.', 'error');
            }
            
            header('Location: ' . URLROOT . '/updates/index');
            exit;
        }
        header('Location: ' . URLROOT . '/updates/index');
        exit;
    }
}