<?php

namespace App\Controllers;

class Install extends BaseController
{
    public function __construct()
    {
        // Don't route if already installed
        if (file_exists(WRITEPATH . 'installed.lock') && service('uri')->getSegment(2) !== 'success') {
            header('Location: ' . base_url());
            exit;
        }
    }

    public function index()
    {
        $requirements = [
            'php' => version_compare(PHP_VERSION, '8.1.0', '>='),
            'mysqli' => extension_loaded('mysqli'),
            'curl' => extension_loaded('curl'),
            'env_writable' => is_writable(ROOTPATH . 'env') || is_writable(ROOTPATH . '.env'),
            'writable_dir' => is_writable(WRITEPATH)
        ];

        $canProceed = !in_array(false, $requirements, true);

        return view('install/step1', ['reqs' => $requirements, 'canProceed' => $canProceed]);
    }

    public function step2()
    {
        return view('install/step2');
    }

    public function processStep2()
    {
        $host = $this->request->getPost('db_host');
        $port = $this->request->getPost('db_port');
        $user = $this->request->getPost('db_user');
        $pass = $this->request->getPost('db_pass');
        $name = $this->request->getPost('db_name');
        
        // Test connection
        try {
            $mysqli = new \mysqli($host, $user, $pass, '', $port);
            if ($mysqli->connect_error) {
                return redirect()->back()->with('error', 'Connection failed: ' . $mysqli->connect_error);
            }
            
            // Create database if not exists
            $mysqli->query("CREATE DATABASE IF NOT EXISTS `$name`");
            if (!$mysqli->select_db($name)) {
                return redirect()->back()->with('error', 'Database could not be selected/created.');
            }
            $mysqli->close();

        } catch (\Exception $e) {
            return redirect()->back()->with('error', 'Error: ' . $e->getMessage());
        }

        // Apply to .env
        $envTemplate = ROOTPATH . 'env';
        $envFile = ROOTPATH . '.env';
        if (!file_exists($envFile) && file_exists($envTemplate)) {
            copy($envTemplate, $envFile);
        }

        if (file_exists($envFile)) {
            $envContent = file_get_contents($envFile);
            $envContent = preg_replace('/#?\s*CI_ENVIRONMENT\s*=\s*production/', "CI_ENVIRONMENT = development", $envContent);
            $envContent = preg_replace('/#?\s*database\.default\.hostname\s*=\s*.*/', "database.default.hostname = \"$host\"", $envContent);
            $envContent = preg_replace('/#?\s*database\.default\.database\s*=\s*.*/', "database.default.database = \"$name\"", $envContent);
            $envContent = preg_replace('/#?\s*database\.default\.username\s*=\s*.*/', "database.default.username = \"$user\"", $envContent);
            $envContent = preg_replace('/#?\s*database\.default\.password\s*=\s*.*/', "database.default.password = \"$pass\"", $envContent);
            $envContent = preg_replace('/#?\s*database\.default\.port\s*=\s*.*/', "database.default.port = \"$port\"", $envContent);
            file_put_contents($envFile, $envContent);
        }

        // Apply Native Database.php Fallback (Crucial for live shared servers where putenv() is disabled)
        $dbFile = APPPATH . 'Config/Database.php';
        if (file_exists($dbFile)) {
            $dbContent = file_get_contents($dbFile);
            $dbContent = preg_replace('/\'hostname\'\s*=>\s*\'[^\']*\'/', "'hostname' => '$host'", $dbContent, 1);
            $dbContent = preg_replace('/\'username\'\s*=>\s*\'[^\']*\'/', "'username' => '$user'", $dbContent, 1);
            $dbContent = preg_replace('/\'password\'\s*=>\s*\'[^\']*\'/', "'password' => '$pass'", $dbContent, 1);
            $dbContent = preg_replace('/\'database\'\s*=>\s*\'[^\']*\'/', "'database' => '$name'", $dbContent, 1);
            $dbContent = preg_replace('/\'port\'\s*=>\s*[0-9]+/', "'port'     => $port", $dbContent, 1);
            file_put_contents($dbFile, $dbContent);
        }

        return redirect()->to('install/step3');
    }

    public function step3()
    {
        return view('install/step3');
    }

    public function processStep3()
    {
        $adminUser = $this->request->getPost('admin_user');
        $adminEmail = $this->request->getPost('admin_email');
        $adminPass = $this->request->getPost('admin_pass');

        // Run Migrations
        try {
            $forge = \Config\Database::forge();
            $runner = \Config\Services::migrations();
            $runner->latest();
            
            // Seed defaults
            $seeder = \Config\Database::seeder();
            $seeder->call('SuffixSeeder');

        } catch(\Exception $e) {
            // Might have already run, fail silently or log
        }

        // Add the provided admin
        $db = \Config\Database::connect();
        
        // Remove existing admin seeded by seeder to avoid collision
        $db->table('users')->where('role', 'admin')->delete();

        $db->table('users')->insert([
            'username' => $adminUser,
            'email' => $adminEmail,
            'password' => password_hash($adminPass, PASSWORD_DEFAULT),
            'role' => 'admin',
            'status' => 'active',
            'created_at' => date('Y-m-d H:i:s'),
            'updated_at' => date('Y-m-d H:i:s')
        ]);

        // Place lock file
        file_put_contents(WRITEPATH . 'installed.lock', 'Installed on ' . date('Y-m-d H:i:s'));

        return redirect()->to('install/success');
    }

    public function success()
    {
        return view('install/success');
    }
}
