<?php
session_start();
error_reporting(E_ALL);
ini_set('display_errors', 1);

// Configuration file path
$config_file = __DIR__ . '/db/config.php';
$is_configured = file_exists($config_file);

// Step 0: Check requirements
$requirements = [
    'PHP Version >= 7.4' => version_compare(PHP_VERSION, '7.4.0', '>='),
    'PDO Extension' => extension_loaded('pdo'),
    'PDO MySQL Extension' => extension_loaded('pdo_mysql'),
    'Config Directory Writable' => is_writable(__DIR__ . '/db/'),
    'Uploads Directory Writable' => is_writable(__DIR__ . '/uploads/') || (mkdir(__DIR__ . '/uploads/', 0777, true) && is_writable(__DIR__ . '/uploads/')),
];

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

// Current step
$step = isset($_GET['step']) ? (int)$_GET['step'] : 1;

// Handle form submissions
$error = '';
$success = '';

if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    if ($step === 2) {
        // Save database configuration
        $host = $_POST['db_host'] ?? '127.0.0.1';
        $name = $_POST['db_name'] ?? 'app_database';
        $user = $_POST['db_user'] ?? 'root';
        $password = $_POST['db_pass'] ?? '';

        // Test connection
        try {
            $test_pdo = new PDO("mysql:host=$host;dbname=$name;charset=utf8mb4", $user, $password);
            $test_pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

            // Generate config file content
            $content = "<?php\n";
            $content .= "// Database configuration generated by installer\n";
            $content .= "define('DB_HOST', " . var_export($host, true) . ");\n";
            $content .= "define('DB_NAME', " . var_export($name, true) . ");\n";
            $content .= "define('DB_USER', " . var_export($user, true) . ");\n";
            $content .= "define('DB_PASS', " . var_export($password, true) . ");\n";
            $content .= "\n";
            $content .= "if (!function_exists('db')) {\n";
            $content .= "    function db() {\n";
            $content .= "        static \$pdo;\n";
            $content .= "        if (!\$pdo) {\n";
            $content .= "            try {\n";
            $content .= "                \$pdo = new PDO('mysql:host=' . DB_HOST . ';dbname=' . DB_NAME . ';charset=utf8mb4', DB_USER, DB_PASS);
";
            $content .= "                \$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
";
            $content .= "                \$pdo->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC);
";
            $content .= "                \$pdo->setAttribute(PDO::MYSQL_ATTR_USE_BUFFERED_QUERY, true);
";
            $content .= "            } catch (PDOException \$e) {\n";
            $content .= "                die('Connection failed: ' . \$e->getMessage());\n";
            $content .= "            }\n";
            $content .= "        }\n";
            $content .= "        return \$pdo;\n";
            $content .= "    }\n";
            $content .= "}\n";

            if (file_put_contents($config_file, $content)) {
                header('Location: ' . htmlspecialchars($_SERVER['SCRIPT_NAME']) . '?step=3');
                exit;
            } else {
                $error = "Failed to write configuration file to $config_file. Please check permissions.";
            }
        } catch (PDOException $e) {
            $error = "Connection failed: " . $e->getMessage();
        }
    } elseif ($step === 3) {
        // Run migrations
        if (!file_exists($config_file)) {
            $error = "Configuration file not found. Please go back to Step 2.";
        } else {
            try {
                require_once $config_file;
                if (!function_exists('db')) {
                    throw new Exception("The 'db()' function is not defined in your config file.");
                }
                $pdo = db();
                $pdo->setAttribute(PDO::MYSQL_ATTR_USE_BUFFERED_QUERY, true);
                
                // Create migration table if not exists
                $pdo->exec("CREATE TABLE IF NOT EXISTS migrations (
                    id INT AUTO_INCREMENT PRIMARY KEY,
                    migration_name VARCHAR(255) NOT NULL UNIQUE,
                    applied_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
                )");

                $migrations_dir = __DIR__ . '/db/migrations/';
                $files = glob($migrations_dir . '*.sql');
                if ($files === false) $files = [];
                sort($files);

                $applied = 0;
                $errors = [];

                foreach ($files as $file) {
                    $migration_name = basename($file);
                    
                    // Check if already applied
                    $stmt = $pdo->prepare("SELECT id FROM migrations WHERE migration_name = ?");
                    $stmt->execute([$migration_name]);
                    if ($stmt->fetch()) {
                        continue;
                    }

                    $sql = file_get_contents($file);
                    if (empty($sql)) continue;

                    // Split SQL into individual statements by ; followed by newline
                    $statements = preg_split('/;(?:\\s*[
]+)/', $sql);
                    
                    $file_success = true;
                    foreach ($statements as $stmt_sql) {
                        $stmt_sql = trim($stmt_sql);
                        if (empty($stmt_sql)) continue;

                        // Basic comment removal
                        $stmt_lines = explode("\n", $stmt_sql);
                        $clean_stmt = "";
                        foreach ($stmt_lines as $line) {
                            if (trim(substr(trim($line), 0, 2)) === '--') continue;
                            $clean_stmt .= $line . "\n";
                        }
                        $clean_stmt = trim($clean_stmt);
                        if (empty($clean_stmt)) continue;

                        try {
                            $res = $pdo->query($clean_stmt);
                            if ($res) {
                                $res->closeCursor();
                            }
                        } catch (Throwable $e) {
                            $msg = $e->getMessage();
                            // If the error is about a table already existing, it's fine
                            if (strpos($msg, "already exists") !== false || 
                                strpos($msg, "Duplicate column") !== false || 
                                strpos($msg, "Duplicate entry") !== false ||
                                strpos($msg, "already a column") !== false ||
                                strpos($msg, "Duplicate key") !== false ||
                                strpos($msg, "errno: 121") !== false) {
                                continue;
                            } else {
                                $errors[] = $migration_name . " at statement: " . substr($clean_stmt, 0, 50) . "... Error: " . $msg;
                                $file_success = false;
                                break;
                            }
                        }
                    }
                    
                    if ($file_success) {
                        $ins = $pdo->prepare("INSERT INTO migrations (migration_name) VALUES (?)");
                        $ins->execute([$migration_name]);
                        $applied++;
                    }
                }

                if (empty($errors)) {
                    $success = "Successfully applied migrations.";
                    header('Location: ' . htmlspecialchars($_SERVER['SCRIPT_NAME']) . '?step=4');
                    exit;
                } else {
                    $error = "Applied migrations, but some errors occurred:<br><ul><li>" . implode('</li><li>', $errors) . "</li></ul>";
                }
            } catch (Throwable $e) {
                $error = "Migration failed: " . $e->getMessage();
            }
        }
    } elseif ($step === 4) {
        // Final setup (Admin account)
        require_once $config_file;
        $pdo = db();

        $admin_user = $_POST['admin_user'] ?? 'admin';
        $admin_pass = $_POST['admin_pass'] ?? '';
        $admin_email = $_POST['admin_email'] ?? 'admin@example.com';

        if (strlen($admin_pass) < 6) {
            $error = "Password must be at least 6 characters long.";
        } else {
            try {
                $hashed_pass = password_hash($admin_pass, PASSWORD_DEFAULT);
                $stmt = $pdo->prepare("INSERT INTO users (username, password, email, role) VALUES (?, ?, ?, 'admin') 
                                      ON DUPLICATE KEY UPDATE password = ?, email = ?");
                $stmt->execute([$admin_user, $hashed_pass, $admin_email, $hashed_pass, $admin_email]);

                // Set initial settings
                $pdo->exec("INSERT IGNORE INTO charity_settings (id, charity_name) VALUES (1, 'Admin Panel')");
                $pdo->exec("INSERT IGNORE INTO smtp_settings (id, is_enabled) VALUES (1, 0)");

                header('Location: ' . htmlspecialchars($_SERVER['SCRIPT_NAME']) . '?step=5');
                exit;
            } catch (Throwable $e) {
                $error = "Failed to create admin account: " . $e->getMessage();
            }
        }
    }
}

// UI Template
?>
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Installer - Step <?= $step ?></title>
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
    <style>
        body { background-color: #f8f9fa; padding-top: 50px; }
        .installer-card { max-width: 600px; margin: 0 auto; box-shadow: 0 0.5rem 1rem rgba(0, 0, 0, 0.15); border-radius: 1rem; }
        .step-indicator { margin-bottom: 2rem; }
        .step-dot { width: 30px; height: 30px; border-radius: 50%; background: #dee2e6; display: inline-block; text-align: center; line-height: 30px; font-weight: bold; margin: 0 5px; }
        .step-dot.active { background: #0d6efd; color: white; }
        .step-dot.completed { background: #198754; color: white; }
    </style>
</head>
<body>
<div class="container">
    <div class="card installer-card">
        <div class="card-body p-5">
            <h2 class="text-center mb-4">Installer</h2>
            
            <div class="text-center step-indicator">
                <?php for ($i = 1; $i <= 5; $i++):
                    $class = ($i == $step) ? 'active' : (($i < $step) ? 'completed' : '');
                    echo "<span class=\"step-dot $class\">$i</span>\n";
                endfor; ?>
            </div>

            <?php if ($error): ?>
                <div class="alert alert-danger"><?= $error ?></div>
            <?php endif; ?>

            <?php if ($success): ?>
                <div class="alert alert-success"><?= $success ?></div>
            <?php endif; ?>

            <?php if ($step === 1): ?>
                <h4>Step 1: System Requirements</h4>
                <ul class="list-group mb-4">
                    <?php foreach ($requirements as $name => $met):
                        echo "<li class=\"list-group-item d-flex justify-content-between align-items-center\">";
                        echo "$name\n";
                        if ($met) {
                            echo "<span class=\"badge bg-success rounded-pill\">OK</span>";
                        } else {
                            echo "<span class=\"badge bg-danger rounded-pill\">Failed</span>";
                        }
                        echo "</li>\n";
                    endforeach; ?>
                </ul>
                <div class="d-grid">
                    <?php if ($all_requirements_met): ?>
                        <a href="<?= htmlspecialchars($_SERVER['SCRIPT_NAME']) ?>?step=2" class="btn btn-primary">Next: Database Config</a>
                    <?php else:
                        echo "<button class=\"btn btn-secondary\" disabled>Fix requirements to continue</button>";
                    endif; ?>
                </div>

            <?php elseif ($step === 2): ?>
                <h4>Step 2: Database Connection</h4>
                <form method="POST" action="<?= htmlspecialchars($_SERVER['SCRIPT_NAME']) ?>?step=2">
                    <div class="mb-3">
                        <label class="form-label">Database Host</label>
                        <input type="text" name="db_host" class="form-control" value="127.0.0.1" required>
                    </div>
                    <div class="mb-3">
                        <label class="form-label">Database Name</label>
                        <input type="text" name="db_name" class="form-control" value="app_database" required>
                    </div>
                    <div class="mb-3">
                        <label class="form-label">Database User</label>
                        <input type="text" name="db_user" class="form-control" value="root" required>
                    </div>
                    <div class="mb-3">
                        <label class="form-label">Database Password</label>
                        <input type="password" name="db_pass" class="form-control">
                    </div>
                    <div class="d-grid">
                        <button type="submit" class="btn btn-primary">Test & Save Config</button>
                    </div>
                </form>

            <?php elseif ($step === 3): ?>
                <h4>Step 3: Database Migrations</h4>
                <p>We will now run the SQL scripts to set up your database tables.</p>
                <form method="POST" action="<?= htmlspecialchars($_SERVER['SCRIPT_NAME']) ?>?step=3">
                    <div class="d-grid">
                        <button type="submit" class="btn btn-primary">Run Migrations</button>
                    </div>
                </form>

            <?php elseif ($step === 4): ?>
                <h4>Step 4: Admin Account</h4>
                <form method="POST" action="<?= htmlspecialchars($_SERVER['SCRIPT_NAME']) ?>?step=4">
                    <div class="mb-3">
                        <label class="form-label">Admin Username</label>
                        <input type="text" name="admin_user" class="form-control" value="admin" required>
                    </div>
                    <div class="mb-3">
                        <label class="form-label">Admin Email</label>
                        <input type="email" name="admin_email" class="form-control" value="admin@example.com" required>
                    </div>
                    <div class="mb-3">
                        <label class="form-label">Admin Password</label>
                        <input type="password" name="admin_pass" class="form-control" required minlength="6">
                    </div>
                    <div class="d-grid">
                        <button type="submit" class="btn btn-primary">Complete Setup</button>
                    </div>
                </form>

            <?php elseif ($step === 5): ?>
                <div class="text-center">
                    <h4 class="text-success">Installation Complete!</h4>
                    <p>The system is ready to use. For security, please delete <b>install.php</b> or rename it.</p>
                    <div class="d-grid">
                        <a href="login.php" class="btn btn-primary">Go to Login</a>
                    </div>
                </div>
            <?php endif; ?>
        </div>
    </div>
</div>
</body>
</html>
