<?php
// --- REDIRECT IF ALREADY INSTALLED ---
$basePath = dirname(__DIR__);
if (file_exists($basePath . '/.env') && file_exists(__DIR__ . '/install.lock')) {
    header('Location: /');
    exit;
}

require_once 'api.php'; 
?>
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>OwnStore Setup Wizard</title>
    
    <style>
        :root {
            --background: #ffffff;
            --foreground: #09090b;
            --card: #ffffff;
            --card-foreground: #09090b;
            --popover: #ffffff;
            --popover-foreground: #09090b;
            --primary: #2563eb; /* Blue primary for OwnStore */
            --primary-foreground: #ffffff;
            --primary-hover: #1d4ed8;
            --secondary: #f4f4f5;
            --secondary-foreground: #18181b;
            --muted: #f4f4f5;
            --muted-foreground: #71717a;
            --accent: #f4f4f5;
            --accent-foreground: #18181b;
            --destructive: #ef4444;
            --destructive-foreground: #fafafa;
            --border: #e4e4e7;
            --input: #e4e4e7;
            --ring: #2563eb;
            --radius: 0.75rem;
            --success: #16a34a;
            --success-bg: #dcfce7;
        }

        [data-theme="dark"] {
            --background: #09090b;
            --foreground: #fafafa;
            --card: #09090b;
            --card-foreground: #fafafa;
            --popover: #09090b;
            --popover-foreground: #fafafa;
            --primary: #3b82f6; /* Lighter blue for dark mode */
            --primary-foreground: #ffffff;
            --primary-hover: #2563eb;
            --secondary: #27272a;
            --secondary-foreground: #fafafa;
            --muted: #27272a;
            --muted-foreground: #a1a1aa;
            --accent: #27272a;
            --accent-foreground: #fafafa;
            --destructive: #7f1d1d;
            --destructive-foreground: #fafafa;
            --border: #27272a;
            --input: #27272a;
            --ring: #3b82f6;
            --success: #22c55e;
            --success-bg: rgba(34, 197, 94, 0.15);
        }

        * { box-sizing: border-box; margin: 0; padding: 0; }

        body {
            font-family: ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
            background-color: var(--muted);
            color: var(--foreground);
            min-height: 100vh;
            display: flex;
            align-items: center;
            justify-content: center;
            padding: 1rem;
            transition: background-color 0.3s, color 0.3s;
            line-height: 1.5;
        }

        .container {
            width: 100%;
            max-width: 1024px;
            background-color: var(--card);
            border: 1px solid var(--border);
            border-radius: var(--radius);
            box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05);
            display: flex;
            flex-direction: column;
            overflow: hidden;
            position: relative;
            min-height: 600px;
        }

        @media (min-width: 768px) {
            .container { flex-direction: row; }
        }

        .sidebar {
            width: 100%;
            background-color: var(--muted);
            border-bottom: 1px solid var(--border);
            padding: 2rem;
            flex-shrink: 0;
            display: flex;
            flex-direction: column;
        }

        @media (min-width: 768px) {
            .sidebar { width: 280px; border-bottom: none; border-right: 1px solid var(--border); }
        }

        .logo { font-size: 1.5rem; font-weight: 800; color: var(--foreground); letter-spacing: -0.025em; display: flex; align-items: center; gap: 0.5rem; }
        .logo-sub { font-size: 0.75rem; font-weight: 600; color: var(--muted-foreground); text-transform: uppercase; letter-spacing: 0.05em; margin-bottom: 2rem; margin-top: 0.25rem; }

        .steps { list-style: none; display: none; flex-direction: column; gap: 1rem; }
        @media (min-width: 768px) { .steps { display: flex; } }

        .step-item { display: flex; align-items: center; gap: 0.75rem; font-size: 0.875rem; transition: all 0.2s; color: var(--muted-foreground); font-weight: 500; }
        .step-item.active { color: var(--foreground); font-weight: 600; }
        .step-item.completed { color: var(--foreground); }
        
        .step-icon {
            width: 24px; height: 24px; border-radius: 50%; display: flex; align-items: center; justify-content: center;
            border: 1px solid var(--border); font-size: 0.75rem; transition: all 0.2s; background: var(--background);
        }
        .step-item.active .step-icon { border-color: var(--primary); color: var(--primary); }
        .step-item.completed .step-icon { border-color: var(--foreground); background-color: var(--foreground); color: var(--background); }

        .content {
            flex: 1; padding: 1.5rem; display: flex; flex-direction: column; position: relative; background-color: var(--background);
        }
        @media (min-width: 768px) { .content { padding: 2.5rem; } }

        .step-view { display: none; flex-direction: column; height: 100%; animation: fadeIn 0.3s ease-in-out forwards; }
        .step-view.active { display: flex; }

        @keyframes fadeIn { from { opacity: 0; transform: translateY(5px); } to { opacity: 1; transform: translateY(0); } }

        h1 { font-size: 1.5rem; font-weight: 700; margin-bottom: 0.5rem; letter-spacing: -0.025em; color: var(--foreground); }
        p.subtitle { color: var(--muted-foreground); font-size: 0.875rem; margin-bottom: 1.5rem; }

        .btn {
            display: inline-flex; align-items: center; justify-content: center; padding: 0.5rem 1rem;
            border-radius: calc(var(--radius) - 2px); font-weight: 500; font-size: 0.875rem; cursor: pointer; transition: all 0.2s; border: 1px solid transparent; outline: none; height: 2.5rem;
        }
        .btn:disabled { opacity: 0.5; cursor: not-allowed; }
        .btn-primary { background-color: var(--primary); color: var(--primary-foreground); }
        .btn-primary:hover:not(:disabled) { background-color: var(--primary-hover); }
        .btn-outline { background-color: transparent; border-color: var(--border); color: var(--foreground); }
        .btn-outline:hover:not(:disabled) { background-color: var(--accent); color: var(--accent-foreground); }

        .alert { padding: 1rem; border-radius: var(--radius); font-size: 0.875rem; font-weight: 500; margin-bottom: 1.5rem; display: none; align-items: flex-start; gap: 0.5rem; }
        .alert.show { display: flex; }
        .alert-error { background-color: var(--destructive); color: var(--destructive-foreground); }
        .alert-warning { background-color: var(--accent); border: 1px solid var(--border); color: var(--foreground); }

        .table-container { flex: 1; overflow-y: auto; border: 1px solid var(--border); border-radius: var(--radius); margin-bottom: 1.5rem; }
        table { width: 100%; border-collapse: collapse; text-align: left; font-size: 0.875rem; }
        th, td { padding: 0.75rem 1rem; border-bottom: 1px solid var(--border); color: var(--foreground); }
        tr:last-child td { border-bottom: none; }
        tr:hover td { background-color: var(--muted); }
        .badge { display: inline-flex; align-items: center; padding: 0.125rem 0.625rem; border-radius: 9999px; font-size: 0.75rem; font-weight: 600; }
        .badge-success { background-color: var(--success-bg); color: var(--success); }
        .badge-error { background-color: rgba(239, 68, 68, 0.15); color: #ef4444; }

        .form-grid { display: grid; grid-template-columns: 1fr; gap: 1rem; margin-bottom: 1.5rem; }
        @media (min-width: 640px) { .form-grid { grid-template-columns: 1fr 1fr; } }
        .form-group { display: flex; flex-direction: column; gap: 0.5rem; }
        .col-span-2 { grid-column: span 1; }
        @media (min-width: 640px) { .col-span-2 { grid-column: span 2; } }
        
        label { font-size: 0.875rem; font-weight: 500; color: var(--foreground); }
        input { 
            display: flex; height: 2.5rem; width: 100%; border-radius: calc(var(--radius) - 2px); border: 1px solid var(--border); 
            background-color: var(--background); color: var(--foreground); padding: 0.5rem 0.75rem; font-size: 0.875rem; transition: border-color 0.2s, box-shadow 0.2s;
        }
        input:focus { outline: none; border-color: var(--ring); box-shadow: 0 0 0 1px var(--ring); }
        input::placeholder { color: var(--muted-foreground); }

        .card-switch {
            display: flex; align-items: center; justify-content: space-between; padding: 1rem;
            border: 1px solid var(--border); border-radius: var(--radius); background-color: var(--card); cursor: pointer; margin-bottom: 1rem; transition: background-color 0.2s;
        }
        .card-switch:hover { background-color: var(--muted); }
        .card-switch h4 { font-size: 0.875rem; font-weight: 600; color: var(--foreground); }
        .card-switch p { font-size: 0.875rem; color: var(--muted-foreground); margin-top: 0.125rem; }
        
        .switch { position: relative; width: 40px; height: 24px; background-color: var(--input); border-radius: 9999px; transition: background-color 0.2s; }
        .switch.active { background-color: var(--primary); }
        .switch-thumb { position: absolute; top: 2px; left: 2px; width: 20px; height: 20px; background-color: white; border-radius: 50%; transition: transform 0.2s; box-shadow: 0 1px 2px rgba(0,0,0,0.1); }
        .switch.active .switch-thumb { transform: translateX(16px); }

        .actions { display: flex; justify-content: space-between; align-items: center; padding-top: 1.5rem; border-top: 1px solid var(--border); margin-top: auto; }

        .spinner { animation: spin 1s linear infinite; border: 2px solid var(--border); border-top-color: var(--primary); border-radius: 50%; width: 1.25rem; height: 1.25rem; }
        @keyframes spin { 100% { transform: rotate(360deg); } }
        
        .skeleton { background: linear-gradient(90deg, var(--muted) 25%, var(--border) 50%, var(--muted) 75%); background-size: 200% 100%; animation: pulse 1.5s infinite; border-radius: 0.25rem; height: 1rem; width: 100%; }
        @keyframes pulse { 0% { background-position: 200% 0; } 100% { background-position: -200% 0; } }

        .theme-toggle { position: absolute; top: 1.5rem; right: 1.5rem; z-index: 50; background: transparent; border: 1px solid var(--border); border-radius: 0.5rem; width: 36px; height: 36px; display: flex; align-items: center; justify-content: center; cursor: pointer; color: var(--foreground); transition: background-color 0.2s; }
        .theme-toggle:hover { background-color: var(--muted); }
        
        .hidden { display: none !important; }
        .flex { display: flex !important; }
        .custom-scrollbar::-webkit-scrollbar { width: 6px; } 
        .custom-scrollbar::-webkit-scrollbar-track { background: transparent; } 
        .custom-scrollbar::-webkit-scrollbar-thumb { background-color: rgba(156, 163, 175, 0.5); border-radius: 10px; }
    </style>
</head>
<body>

    <div class="container">
        
        <button class="theme-toggle" onclick="toggleTheme()" title="Toggle Theme">
            <svg id="icon-sun" class="hidden" width="16" height="16" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M12 3v1m0 16v1m9-9h-1M4 12H3m15.364 6.364l-.707-.707M6.343 6.343l-.707-.707m12.728 0l-.707.707M6.343 17.657l-.707.707M16 12a4 4 0 11-8 0 4 4 0 018 0z" /></svg>
            <svg id="icon-moon" width="16" height="16" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M20.354 15.354A9 9 0 018.646 3.646 9.003 9.003 0 0012 21a9.003 9.003 0 008.354-5.646z" /></svg>
        </button>

        <div class="sidebar">
            <div class="logo">
                <svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" style="color: var(--primary);"><path d="M6 2L3 6v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2V6l-3-4z"/><line x1="3" y1="6" x2="21" y2="6"/><path d="M16 10a4 4 0 0 1-8 0"/></svg>
                OwnStore
            </div>
            <div class="logo-sub">Installer</div>
            
            <ul class="steps" id="steps-list">
                <li class="step-item active" id="nav-step-0"><div class="step-icon">1</div> Welcome</li>
                <li class="step-item" id="nav-step-1"><div class="step-icon">2</div> Requirements</li>
                <li class="step-item" id="nav-step-2"><div class="step-icon">3</div> Permissions</li>
                <li class="step-item" id="nav-step-3"><div class="step-icon">4</div> Database</li>
                <li class="step-item" id="nav-step-4"><div class="step-icon">5</div> Install</li>
                <li class="step-item" id="nav-step-5"><div class="step-icon">6</div> Finish</li>
            </ul>
        </div>

        <div class="content">
            
            <div id="global-error" class="alert alert-error">
                <svg width="18" height="18" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z"/></svg>
                <span id="error-text"></span>
            </div>

            <div id="step-0" class="step-view active" style="align-items: center; justify-content: center; text-align: center;">
                <div style="width: 64px; height: 64px; background-color: var(--muted); border: 1px solid var(--border); border-radius: 50%; display: flex; align-items: center; justify-content: center; margin: 0 auto 1.5rem;">
                    <svg width="32" height="32" style="color: var(--primary);" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path d="M6 2L3 6v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2V6l-3-4z"/><line x1="3" y1="6" x2="21" y2="6"/><path d="M16 10a4 4 0 0 1-8 0"/></svg>
                </div>
                <h1>Welcome to OwnStore Setup</h1>
                <p class="subtitle" style="max-width: 400px; margin: 0 auto 2rem;">Follow this setup wizard to securely configure your digital marketplace and environment settings.</p>
                <button class="btn btn-primary" onclick="goToStep(1)" style="width: 100%; max-width: 250px;">Start Installation</button>
            </div>

            <div id="step-1" class="step-view">
                <h1>Server Requirements</h1>
                <p class="subtitle">Verifying PHP version and required extensions.</p>
                <div class="table-container custom-scrollbar">
                    <table><tbody id="req-tbody"></tbody></table>
                </div>
                <div class="actions">
                    <button class="btn btn-outline" onclick="goToStep(0)">Back</button>
                    <div>
                        <button id="btn-refresh-req" class="btn btn-outline hidden" onclick="checkRequirements()" style="margin-right: 0.5rem;">Refresh</button>
                        <button id="btn-next-req" class="btn btn-primary" onclick="goToStep(2)" disabled>Continue</button>
                    </div>
                </div>
            </div>

            <div id="step-2" class="step-view">
                <h1>Folder Permissions</h1>
                <p class="subtitle">Checking write access for core directories.</p>
                <div class="table-container custom-scrollbar">
                    <table><tbody id="perm-tbody"></tbody></table>
                </div>
                <div class="actions">
                    <button class="btn btn-outline" onclick="goToStep(1)">Back</button>
                    <div>
                        <button id="btn-refresh-perm" class="btn btn-outline hidden" onclick="checkPermissions()" style="margin-right: 0.5rem;">Refresh</button>
                        <button id="btn-next-perm" class="btn btn-primary" onclick="goToStep(3)" disabled>Continue</button>
                    </div>
                </div>
            </div>

            <div id="step-3" class="step-view">
                <h1>Database Configuration</h1>
                <p class="subtitle">Enter your MySQL connection details below.</p>
                <div style="flex: 1; overflow-y: auto; padding-right: 0.5rem;" class="custom-scrollbar">
                    <form id="db-form">
                        <div class="form-grid">
                            <div class="form-group">
                                <label>Database Host</label>
                                <input type="text" id="db_host" value="127.0.0.1" required>
                            </div>
                            <div class="form-group">
                                <label>Port</label>
                                <input type="text" id="db_port" value="3306" required>
                            </div>
                            <div class="form-group col-span-2">
                                <label>Database Name</label>
                                <input type="text" id="db_name" required placeholder="e.g. ownstore_db">
                            </div>
                            <div class="form-group">
                                <label>Username</label>
                                <input type="text" id="db_user" required placeholder="e.g. root">
                            </div>
                            <div class="form-group">
                                <label>Password</label>
                                <input type="password" id="db_pass" placeholder="Optional">
                            </div>
                        </div>

                        <div class="card-switch" onclick="toggleSeeders()">
                            <div>
                                <h4>Install Demo Content</h4>
                                <p>Includes sample products, categories, dummy users, and an admin account.</p>
                            </div>
                            <div class="switch active" id="seeder-toggle"><div class="switch-thumb"></div></div>
                        </div>

                        <div id="admin-setup-box" class="hidden" style="padding: 1rem; border: 1px solid var(--border); background: var(--muted); border-radius: var(--radius); margin-bottom: 1.5rem;">
                            <h4 style="font-weight: 600; font-size: 0.875rem; margin-bottom: 1rem; color: var(--foreground);">Administrator Account</h4>
                            <div class="form-grid" style="background: transparent; border: none; padding: 0; margin: 0;">
                                <div class="form-group">
                                    <label>Full Name</label>
                                    <input type="text" id="admin_name" placeholder="John Doe">
                                </div>
                                <div class="form-group">
                                    <label>Username</label>
                                    <input type="text" id="admin_username" placeholder="admin">
                                </div>
                                <div class="form-group">
                                    <label>Email</label>
                                    <input type="email" id="admin_email" placeholder="admin@domain.com">
                                </div>
                                <div class="form-group">
                                    <label>Password</label>
                                    <input type="password" id="admin_password" placeholder="••••••••" minlength="8">
                                </div>
                            </div>
                        </div>
                    </form>
                </div>

                <div class="actions">
                    <button class="btn btn-outline" onclick="goToStep(2)">Back</button>
                    <button id="btn-submit-db" class="btn btn-primary" onclick="submitDatabase()">
                        <span id="btn-submit-text">Verify Database</span>
                    </button>
                </div>
            </div>

            <div id="step-4" class="step-view" style="align-items: center; justify-content: center; text-align: center;">
                <div style="margin: 0 auto 1.5rem; display: flex; align-items: center; justify-content: center;">
                    <div class="spinner" style="width: 48px; height: 48px; border-width: 3px;"></div>
                </div>
                <h1>Installing OwnStore</h1>
                <p class="subtitle" style="margin-bottom: 0;">Writing environment configs and running database migrations.</p>
                <p style="color: var(--muted-foreground); font-size: 0.75rem; margin-top: 1rem;">Please do not refresh or close this page.</p>
            </div>

            <div id="step-5" class="step-view" style="align-items: center; justify-content: center; text-align: center;">
                <div style="width: 64px; height: 64px; background-color: var(--success-bg); color: var(--success); border-radius: 50%; display: flex; align-items: center; justify-content: center; margin: 0 auto 1.5rem;">
                    <svg width="32" height="32" fill="none" stroke="currentColor" stroke-width="3" stroke-linecap="round" stroke-linejoin="round"><path d="M20 6 9 17l-5-5"/></svg>
                </div>
                <h1>Installation Complete!</h1>
                <p class="subtitle">Your digital marketplace has been successfully configured.</p>
                
                <div id="warnings-box" class="alert alert-warning" style="max-width: 500px; margin: 0 auto 1.5rem; text-align: left; display: none;">
                    <svg width="18" height="18" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2" style="flex-shrink:0; margin-top:2px;"><path stroke-linecap="round" stroke-linejoin="round" d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z"/></svg>
                    <div>
                        <strong style="display: block; margin-bottom: 0.25rem;">Action Required</strong>
                        <div id="warnings-text" style="font-size: 0.8rem; font-weight: normal; color: var(--muted-foreground);"></div>
                    </div>
                </div>

                <div style="background-color: var(--muted); border: 1px solid var(--border); border-radius: var(--radius); padding: 1rem; width: 100%; max-width: 320px; margin: 0 auto 2rem; text-align: left;">
                    <h4 style="font-size: 0.75rem; font-weight: 600; text-transform: uppercase; color: var(--muted-foreground); margin-bottom: 0.75rem;">Admin Login Details</h4>
                    <div style="display: flex; justify-content: space-between; margin-bottom: 0.5rem; font-size: 0.875rem;">
                        <span style="color: var(--muted-foreground);">Email:</span>
                        <strong id="final-email" style="user-select: all;"></strong>
                    </div>
                    <div style="display: flex; justify-content: space-between; font-size: 0.875rem;">
                        <span style="color: var(--muted-foreground);">Password:</span>
                        <strong id="final-pass" style="user-select: all;"></strong>
                    </div>
                </div>

                <a href="/" class="btn btn-primary" style="padding: 0.75rem 2rem;">
                    Launch Marketplace
                </a>
            </div>

        </div>
    </div>

    <script>
        let currentStep = 0;
        let runSeeders = true;

        const toggleTheme = () => {
            const isDark = document.documentElement.getAttribute('data-theme') === 'dark';
            document.documentElement.setAttribute('data-theme', isDark ? 'light' : 'dark');
            document.getElementById('icon-sun').classList.toggle('hidden');
            document.getElementById('icon-moon').classList.toggle('hidden');
        };

        if (window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches) {
            document.documentElement.setAttribute('data-theme', 'dark');
            document.getElementById('icon-sun').classList.remove('hidden');
            document.getElementById('icon-moon').classList.add('hidden');
        }

        const showError = (msg) => {
            const box = document.getElementById('global-error');
            if (msg) {
                document.getElementById('error-text').innerText = msg;
                box.classList.add('show');
            } else {
                box.classList.remove('show');
            }
        };

        const updateSidebar = () => {
            document.querySelectorAll('.step-item').forEach((el, index) => {
                el.classList.remove('active', 'completed');
                const icon = el.querySelector('.step-icon');
                if (index === currentStep) {
                    el.classList.add('active');
                    icon.innerHTML = index + 1;
                } else if (index < currentStep) {
                    el.classList.add('completed');
                    icon.innerHTML = '<svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="3" stroke-linecap="round" stroke-linejoin="round"><path d="M20 6 9 17l-5-5"/></svg>';
                } else {
                    icon.innerHTML = index + 1;
                }
            });
        };

        const goToStep = (target) => {
            showError(null);
            document.querySelectorAll('.step-view').forEach(el => el.classList.remove('active'));
            document.getElementById(`step-${target}`).classList.add('active');
            currentStep = target;
            updateSidebar();

            if (target === 1) checkRequirements();
            if (target === 2) checkPermissions();
            if (target === 4) executeInstall();
        };

        const safeFetch = async (action, options = {}) => {
            const res = await fetch(`?installer_api=${action}`, options);
            const text = await res.text();
            try {
                return JSON.parse(text);
            } catch (e) {
                throw new Error("Server error: " + text.substring(0, 100));
            }
        };

        const getSkeletonRows = (count) => {
            let html = '';
            for(let i=0; i<count; i++) {
                html += `<tr><td><div class="skeleton" style="width: 60%;"></div></td><td style="text-align: right; width: 100px;"><div class="skeleton"></div></td></tr>`;
            }
            return html;
        };

        const renderTable = (tbodyId, data) => {
            const tbody = document.getElementById(tbodyId);
            tbody.innerHTML = '';
            for (const [key, passed] of Object.entries(data)) {
                const badge = passed ? '<span class="badge badge-success">Passed</span>' : '<span class="badge badge-error">Failed</span>';
                tbody.innerHTML += `<tr><td style="font-family: monospace; font-size: 0.8rem;">${key}</td><td style="text-align: right;">${badge}</td></tr>`;
            }
        };

        const checkRequirements = async () => {
            const tbody = document.getElementById('req-tbody');
            const btnNext = document.getElementById('btn-next-req');
            const btnRefresh = document.getElementById('btn-refresh-req');
            
            btnNext.disabled = true;
            btnRefresh.classList.add('hidden');
            showError(null);
            tbody.innerHTML = getSkeletonRows(5);

            try {
                const res = await safeFetch('requirements');
                if (!res.success) throw new Error(res.message);
                
                renderTable('req-tbody', res.data);
                
                if (res.passed) btnNext.disabled = false;
                else { btnRefresh.classList.remove('hidden'); showError("Please install missing PHP extensions to continue."); }
            } catch (e) {
                btnRefresh.classList.remove('hidden');
                tbody.innerHTML = `<tr><td colspan="2" style="text-align:center; color: var(--muted-foreground);">Failed to fetch requirements.</td></tr>`;
                showError(e.message);
            }
        };

        const checkPermissions = async () => {
            const tbody = document.getElementById('perm-tbody');
            const btnNext = document.getElementById('btn-next-perm');
            const btnRefresh = document.getElementById('btn-refresh-perm');
            
            btnNext.disabled = true;
            btnRefresh.classList.add('hidden');
            showError(null);
            tbody.innerHTML = getSkeletonRows(4);

            try {
                const res = await safeFetch('permissions');
                if (!res.success) throw new Error(res.message);
                
                renderTable('perm-tbody', res.data);
                
                if (res.passed) btnNext.disabled = false;
                else { btnRefresh.classList.remove('hidden'); showError("Please fix folder permissions (chmod 775 or 777) to continue."); }
            } catch (e) {
                btnRefresh.classList.remove('hidden');
                tbody.innerHTML = `<tr><td colspan="2" style="text-align:center; color: var(--muted-foreground);">Failed to check permissions.</td></tr>`;
                showError(e.message);
            }
        };

        const toggleSeeders = () => {
            runSeeders = !runSeeders;
            const toggle = document.getElementById('seeder-toggle');
            const adminBox = document.getElementById('admin-setup-box');
            
            if (runSeeders) {
                toggle.classList.add('active');
                adminBox.classList.add('hidden');
                ['admin_name', 'admin_username', 'admin_email', 'admin_password'].forEach(id => document.getElementById(id).removeAttribute('required'));
            } else {
                toggle.classList.remove('active');
                adminBox.classList.remove('hidden');
                ['admin_name', 'admin_username', 'admin_email', 'admin_password'].forEach(id => document.getElementById(id).setAttribute('required', 'true'));
            }
        };

        const submitDatabase = async () => {
            const form = document.getElementById('db-form');
            
            if (!runSeeders) {
                // Manually validate admin inputs if runSeeders is false
                const adminFields = ['admin_name', 'admin_username', 'admin_email', 'admin_password'];
                for (const id of adminFields) {
                    if (!document.getElementById(id).value) {
                        showError("Please fill out all Administrator details.");
                        return;
                    }
                }
            }

            if (!form.checkValidity()) {
                form.reportValidity();
                return;
            }

            const payload = {
                db_host: document.getElementById('db_host').value,
                db_port: document.getElementById('db_port').value,
                db_name: document.getElementById('db_name').value,
                db_user: document.getElementById('db_user').value,
                db_pass: document.getElementById('db_pass').value,
            };

            const btn = document.getElementById('btn-submit-db');
            btn.disabled = true;
            document.getElementById('btn-submit-text').innerText = "Connecting...";
            showError(null);

            try {
                const res = await safeFetch('database', { method: 'POST', body: JSON.stringify(payload) });
                if (!res.success) throw new Error(res.message);
                goToStep(4);
            } catch (e) {
                showError("Database connection failed: " + e.message);
            } finally {
                btn.disabled = false;
                document.getElementById('btn-submit-text').innerText = "Verify Database";
            }
        };

        const executeInstall = async () => {
            const payload = {
                db_host: document.getElementById('db_host').value,
                db_port: document.getElementById('db_port').value,
                db_name: document.getElementById('db_name').value,
                db_user: document.getElementById('db_user').value,
                db_pass: document.getElementById('db_pass').value,
                run_seeders: runSeeders,
                admin_name: document.getElementById('admin_name').value,
                admin_username: document.getElementById('admin_username').value,
                admin_email: document.getElementById('admin_email').value,
                admin_password: document.getElementById('admin_password').value,
            };

            try {
                const res = await safeFetch('install', { method: 'POST', body: JSON.stringify(payload) });
                if (!res.success) throw new Error(res.message);

                document.getElementById('final-email').innerText = runSeeders ? 'admin@example.com' : payload.admin_email;
                document.getElementById('final-pass').innerText = runSeeders ? '12345678' : payload.admin_password;

                if (res.warnings && res.warnings.length > 0) {
                    document.getElementById('warnings-box').style.display = 'flex';
                    document.getElementById('warnings-text').innerHTML = res.warnings.map(w => `<p style="margin-bottom:0.25rem;">${w}</p>`).join('');
                }

                goToStep(5);
            } catch (e) {
                showError("Installation failed: " + e.message);
                goToStep(3); 
            }
        };

        // Start Sidebar Setup
        updateSidebar();
    </script>
</body>
</html>