<?php
/*******************************************************************************************************************
| Software Name        : EasyStream - Setup Wizard Backend
| Software Description : Handles setup wizard logic and database configuration
| Software Author      : (c) Sami Ahmed
|*******************************************************************************************************************/

class SetupWizard {
    private $pdo;
    private $config;

    public function __construct() {
        $this->loadDatabaseConnection();
        $this->config = [];
    }

    private function loadDatabaseConnection() {
        try {
            $db_host = getenv('DB_HOST') ?: 'db';
            $db_name = getenv('DB_NAME') ?: 'easystream';
            $db_user = getenv('DB_USER') ?: 'easystream';
            $db_pass = getenv('DB_PASS') ?: 'easystream';

            $this->pdo = new PDO(
                "mysql:host=$db_host;dbname=$db_name;charset=utf8mb4",
                $db_user,
                $db_pass,
                [
                    PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
                    PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
                    PDO::ATTR_EMULATE_PREPARES => false
                ]
            );
        } catch (PDOException $e) {
            error_log("Setup Wizard DB Connection Error: " . $e->getMessage());
            throw new Exception("Database connection failed. Please check your configuration.");
        }
    }

    public function testDatabaseConnection($data) {
        try {
            // Test if tables exist
            $stmt = $this->pdo->query("SHOW TABLES");
            $tables = $stmt->fetchAll(PDO::FETCH_COLUMN);
            $tableCount = count($tables);

            // Check if db_settings table exists
            $hasSettings = in_array('db_settings', $tables);

            return [
                'success' => true,
                'message' => "Database connected successfully",
                'tableCount' => $tableCount,
                'hasSettings' => $hasSettings
            ];
        } catch (Exception $e) {
            return [
                'success' => false,
                'error' => $e->getMessage()
            ];
        }
    }

    public function saveConfiguration($data) {
        try {
            // Validate required fields
            $required = ['platformName', 'domainName', 'contactEmail'];
            foreach ($required as $field) {
                if (empty($data[$field])) {
                    throw new Exception("Missing required field: $field");
                }
            }

            // Save configuration to database
            $settings = [
                'site_name' => $data['platformName'],
                'site_tagline' => $data['platformTagline'] ?? '',
                'site_url' => $data['domainName'],
                'site_email' => $data['contactEmail'],
                'site_timezone' => $data['timezone'] ?? 'UTC',

                // Branding
                'theme_primary_color' => $data['primaryColor'] ?? '#667eea',
                'theme_secondary_color' => $data['secondaryColor'] ?? '#764ba2',
                'theme_default' => $data['defaultTheme'] ?? 'light',
                'theme_allow_switching' => !empty($data['enableTheming']) ? '1' : '0',

                // Membership tiers
                'tier_free_name' => $data['tier1Name'] ?? 'Free',
                'tier_free_upload_limit' => $data['tier1Upload'] ?? 100,
                'tier_free_storage_limit' => $data['tier1Storage'] ?? 5,

                'tier_premium_name' => $data['tier2Name'] ?? 'Premium',
                'tier_premium_upload_limit' => $data['tier2Upload'] ?? 500,
                'tier_premium_storage_limit' => $data['tier2Storage'] ?? 50,
                'tier_premium_price' => $data['tier2Price'] ?? 9.99,

                'tier_enterprise_name' => $data['tier3Name'] ?? 'Enterprise',
                'tier_enterprise_upload_limit' => $data['tier3Upload'] ?? 2048,
                'tier_enterprise_storage_limit' => $data['tier3Storage'] ?? 500,
                'tier_enterprise_price' => $data['tier3Price'] ?? 49.99,

                // Features
                'feature_registration' => !empty($data['enableRegistration']) ? '1' : '0',
                'feature_email_verification' => !empty($data['enableEmailVerification']) ? '1' : '0',
                'feature_live_streaming' => !empty($data['enableLiveStreaming']) ? '1' : '0',
                'feature_comments' => !empty($data['enableComments']) ? '1' : '0',
                'feature_downloads' => !empty($data['enableDownloads']) ? '1' : '0',
                'feature_monetization' => !empty($data['enableMonetization']) ? '1' : '0',
                'feature_template_builder' => !empty($data['enableTemplateBuilder']) ? '1' : '0',
                'feature_analytics' => !empty($data['enableAnalytics']) ? '1' : '0',

                // Meta
                'setup_completed' => '1',
                'setup_date' => date('Y-m-d H:i:s'),
                'setup_version' => '2.0'
            ];

            // Check if db_settings table exists
            $stmt = $this->pdo->query("SHOW TABLES LIKE 'db_settings'");
            if ($stmt->rowCount() === 0) {
                // Table doesn't exist yet, create it
                $this->createSettingsTable();
            }

            // Insert or update settings
            foreach ($settings as $key => $value) {
                $stmt = $this->pdo->prepare("
                    INSERT INTO db_settings (cfg_name, cfg_value)
                    VALUES (?, ?)
                    ON DUPLICATE KEY UPDATE cfg_value = VALUES(cfg_value)
                ");
                $stmt->execute([$key, $value]);
            }

            // Also write to config file for quick access
            $this->writeConfigFile($settings);

            return [
                'success' => true,
                'message' => 'Configuration saved successfully'
            ];
        } catch (Exception $e) {
            error_log("Setup Wizard Save Config Error: " . $e->getMessage());
            return [
                'success' => false,
                'error' => $e->getMessage()
            ];
        }
    }

    public function createAdminUser($data) {
        try {
            // Validate required fields
            if (empty($data['adminUsername']) || empty($data['adminEmail']) || empty($data['adminPassword'])) {
                throw new Exception("All admin fields are required");
            }

            // Validate password match
            if ($data['adminPassword'] !== $data['adminPasswordConfirm']) {
                throw new Exception("Passwords do not match");
            }

            // Validate password strength
            if (strlen($data['adminPassword']) < 8) {
                throw new Exception("Password must be at least 8 characters long");
            }

            // Hash password
            $passwordHash = password_hash($data['adminPassword'], PASSWORD_BCRYPT);

            // Check if db_accountuser table exists
            $stmt = $this->pdo->query("SHOW TABLES LIKE 'db_accountuser'");
            if ($stmt->rowCount() === 0) {
                throw new Exception("User table not found. Database may not be properly initialized.");
            }

            // Check if admin already exists
            $stmt = $this->pdo->prepare("SELECT usr_id FROM db_accountuser WHERE usr_user = :username OR usr_email = :email");
            $stmt->execute([
                'username' => $data['adminUsername'],
                'email' => $data['adminEmail']
            ]);

            if ($stmt->rowCount() > 0) {
                // Update existing admin
                $stmt = $this->pdo->prepare("
                    UPDATE db_accountuser
                    SET usr_password = :password,
                        usr_email = :email,
                        usr_dname = :displayname,
                        usr_role = 'admin',
                        usr_status = 1,
                        usr_verified = 1
                    WHERE usr_user = :username OR usr_email = :email
                ");
            } else {
                // Insert new admin - use SET sql_mode to allow more flexible inserts
                $this->pdo->exec("SET sql_mode=''");

                $stmt = $this->pdo->prepare("
                    INSERT INTO db_accountuser (
                        usr_key, usr_user, usr_password, usr_email, usr_dname, usr_role, usr_status, usr_verified,
                        usr_IP, usr_logins, usr_lastlogin, usr_joindate, live_key
                    ) VALUES (
                        1, :username, :password, :email, :displayname, 'admin', 1, 1,
                        '127.0.0.1', 0, NOW(), NOW(), ''
                    )
                ");
            }

            $stmt->execute([
                'username' => $data['adminUsername'],
                'password' => $passwordHash,
                'email' => $data['adminEmail'],
                'displayname' => $data['adminDisplayName'] ?? 'Administrator'
            ]);

            return [
                'success' => true,
                'message' => 'Admin user created successfully'
            ];
        } catch (Exception $e) {
            error_log("Setup Wizard Create Admin Error: " . $e->getMessage());
            return [
                'success' => false,
                'error' => $e->getMessage()
            ];
        }
    }

    public function finalizeSetup($data) {
        try {
            // Create .setup_complete file to prevent re-running setup
            file_put_contents('.setup_complete', json_encode([
                'completed_at' => date('Y-m-d H:i:s'),
                'platform_name' => $data['platformName'] ?? 'EasyStream',
                'domain' => $data['domainName'] ?? 'localhost',
                'version' => '2.0'
            ]));

            // Update Caddyfile with domain
            if (!empty($data['domainName']) && $data['domainName'] !== 'localhost') {
                $this->updateCaddyfile($data['domainName']);
            }

            // Clear any cached config
            if (function_exists('opcache_reset')) {
                opcache_reset();
            }

            return [
                'success' => true,
                'message' => 'Setup completed successfully',
                'redirect' => '/'
            ];
        } catch (Exception $e) {
            error_log("Setup Wizard Finalize Error: " . $e->getMessage());
            return [
                'success' => false,
                'error' => $e->getMessage()
            ];
        }
    }

    private function createSettingsTable() {
        $sql = "CREATE TABLE IF NOT EXISTS `db_settings` (
            `cfg_name` VARCHAR(100) NOT NULL PRIMARY KEY,
            `cfg_value` TEXT
        ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci";

        $this->pdo->exec($sql);
    }

    private function writeConfigFile($settings) {
        $configContent = "<?php\n";
        $configContent .= "// Auto-generated setup configuration\n";
        $configContent .= "// Generated on " . date('Y-m-d H:i:s') . "\n\n";

        foreach ($settings as $key => $value) {
            $safeValue = addslashes($value);
            $constantName = 'SETUP_' . strtoupper($key);
            $configContent .= "define('$constantName', '$safeValue');\n";
        }

        // Write to f_core/config.setup.php
        $configFile = __DIR__ . '/f_core/config.setup.php';
        @file_put_contents($configFile, $configContent);
    }

    private function updateCaddyfile($domain) {
        $caddyfile = __DIR__ . '/Caddyfile';

        if (file_exists($caddyfile)) {
            $content = @file_get_contents($caddyfile);

            // Replace localhost with actual domain
            $content = preg_replace('/http:\/\/localhost:\d+/', "https://$domain", $content);
            $content = preg_replace('/^:80\s*\{/', "$domain {\n    encode gzip", $content);

            @file_put_contents($caddyfile, $content);
        }
    }
}
?>
