<?php
/**
 * Auto-Instalador Premium - Versión Blindada Master Core
 * FIX: Tolerancia de tiempo masiva (12 Horas) para servidores en distintos países.
 */

class GoogleAuthenticator {
    protected $_codeLength = 6;

    public function createSecret($secretLength = 16) {
        $validChars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567";
        $secret = "";
        for ($i = 0; $i < $secretLength; $i++) { $secret .= $validChars[rand(0, 31)]; }
        return $secret;
    }

    public function getCode($secret, $timeSlice = null) {
        if ($timeSlice === null) { $timeSlice = floor(time() / 30); }
        $secretkey = $this->_base32Decode($secret);
        $time = chr(0).chr(0).chr(0).chr(0).pack('N*', $timeSlice);
        $hm = hash_hmac('SHA1', $time, $secretkey, true);
        $offset = ord(substr($hm, -1)) & 0x0F;
        $hashpart = substr($hm, $offset, 4);
        $value = unpack('N', $hashpart);
        $value = $value[1] & 0x7FFFFFFF;
        return str_pad($value % pow(10, $this->_codeLength), $this->_codeLength, '0', STR_PAD_LEFT);
    }

    public function verifyCode($secret, $code, $discrepancy = 1440) {
        $currentTimeSlice = floor(time() / 30);
        for ($i = -$discrepancy; $i <= $discrepancy; $i++) {
            if ($this->getCode($secret, $currentTimeSlice + $i) == $code) { return true; }
        }
        return false;
    }

    protected function _base32Decode($secret) {
        if (empty($secret)) return '';
        $base32chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567";
        $base32charsFlipped = array_flip(str_split($base32chars));
        $secret = str_replace('=','', strtoupper($secret));
        $secret = str_split($secret);
        $binaryString = "";
        for ($i = 0; $i < count($secret); $i = $i+8) {
            $x = "";
            for ($j = 0; $j < 8; $j++) { $x .= str_pad(base_convert(@$base32charsFlipped[@$secret[$i+$j]], 10, 2), 5, '0', STR_PAD_LEFT); }
            $eightBits = str_split($x, 8);
            for ($z = 0; $z < count($eightBits); $z++) { $binaryString .= ( ($y = chr(base_convert($eightBits[$z], 2, 10))) || ord($y) == 48 ) ? $y : ""; }
        }
        return $binaryString;
    }
}

if (isset($_GET['action'])) {
    header('Content-Type: application/json');
    $ga = new GoogleAuthenticator();

    if ($_GET['action'] == 'run_install') {
        try {
            $key    = $_POST['license_key'] ?? '';
            $v_ip    = $_POST['vps_ip'] ?? '';
            $v_db    = $_POST['vps_db'] ?? 'MuOnline';
            $v_user = $_POST['vps_user'] ?? '';
            $v_pass = $_POST['vps_pass'] ?? '';
            $adm_u  = $_POST['admin_user'] ?? '';
            $adm_p  = $_POST['admin_pass'] ?? '';
            $mode   = $_POST['install_mode'] ?? 'detect';

            if(empty($key)) throw new Exception("La licencia es obligatoria.");

            $raw_host = $_SERVER['HTTP_HOST'];
            $clean_host = strtolower(trim(str_ireplace('www.', '', explode(':', $raw_host)[0])));

            $ch = curl_init("https://aetherhost.com/aecms/check.php");
            curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
            curl_setopt($ch, CURLOPT_POSTFIELDS, ['key' => trim($key), 'domain' => $clean_host]);
            $response = curl_exec($ch);
            $api_res = json_decode($response, true);

            if (!$api_res || $api_res['status'] !== 'success') {
                throw new Exception(($api_res['message'] ?? 'Error de validación') . " (Detectado: $clean_host)");
            }

            $dsn = "dblib:host=$v_ip:1433;dbname=$v_db;charset=UTF8";
            $pdo = new PDO($dsn, $v_user, $v_pass);
            $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

            if ($mode === 'detect') {
                $st = $pdo->query("SELECT COUNT(*) FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'Web_Settings'");
                if ($st->fetchColumn() > 0) { echo json_encode(['status' => 'conflict']); exit; }
                $mode = 'reset';
            }

            $sql_sp_hero = "IF OBJECT_ID('SP_CALCULATE_HERO_OF_MONTH', 'P') IS NOT NULL DROP PROCEDURE SP_CALCULATE_HERO_OF_MONTH;
            EXEC('CREATE PROCEDURE SP_CALCULATE_HERO_OF_MONTH AS
            BEGIN
                SET NOCOUNT ON;
                DELETE FROM Web_HeroOfMonth;
                INSERT INTO Web_HeroOfMonth (char_name, char_class, month_year, description, created_at)
                SELECT TOP 1 Name, Class, FORMAT(GETDATE(), ''MM-yyyy''), CAST(SUM(Puntos) AS VARCHAR) + '' PUNTOS DE GLORIA'', GETDATE()
                FROM (
                    SELECT TOP 5 Name, Class, 50 as Puntos FROM Character ORDER BY cLevel DESC
                    UNION ALL
                    SELECT TOP 5 Name, Class, 50 as Puntos FROM Character ORDER BY ResetCount DESC
                    UNION ALL
                    SELECT TOP 5 Name, Class, 30 as Puntos FROM Character ORDER BY PkCount DESC
                ) AS Rankings GROUP BY Name, Class ORDER BY SUM(Puntos) DESC;
            END');";

            if ($mode === 'reset') {
                $sql_reset = "
                IF OBJECT_ID('Web_News', 'U') IS NOT NULL DROP TABLE Web_News;
                CREATE TABLE Web_News (id INT PRIMARY KEY IDENTITY(1,1), title VARCHAR(150) NOT NULL, content TEXT NOT NULL, category VARCHAR(50), image_url VARCHAR(255), created_at DATETIME DEFAULT GETDATE());
                IF OBJECT_ID('Web_Ranking_Config', 'U') IS NOT NULL DROP TABLE Web_Ranking_Config;
                CREATE TABLE Web_Ranking_Config (setting_key VARCHAR(50) PRIMARY KEY, setting_value VARCHAR(MAX));
                IF OBJECT_ID('Web_Settings', 'U') IS NOT NULL DROP TABLE Web_Settings;
                CREATE TABLE Web_Settings (setting_key VARCHAR(50) PRIMARY KEY, setting_value VARCHAR(MAX));
                IF OBJECT_ID('Web_HeroOfMonth', 'U') IS NOT NULL DROP TABLE Web_HeroOfMonth;
                CREATE TABLE Web_HeroOfMonth (id INT PRIMARY KEY IDENTITY(1,1), char_name VARCHAR(10) NOT NULL, char_class INT DEFAULT 0, description VARCHAR(MAX) NULL, month_year VARCHAR(20) NOT NULL, created_at DATETIME DEFAULT GETDATE());
                IF OBJECT_ID('Web_Schedules', 'U') IS NOT NULL DROP TABLE Web_Schedules;
                CREATE TABLE Web_Schedules (id INT PRIMARY KEY IDENTITY(1,1), type VARCHAR(20) NOT NULL, name VARCHAR(100) NOT NULL, times VARCHAR(MAX) NOT NULL, gmt VARCHAR(50), image_url VARCHAR(255), description NVARCHAR(150) NULL, drops VARCHAR(MAX) NULL, drop_rarity VARCHAR(50) DEFAULT 'common', status INT DEFAULT 1, created_at DATETIME DEFAULT GETDATE());
                IF OBJECT_ID('Web_Schedules_Drops', 'U') IS NOT NULL DROP TABLE Web_Schedules_Drops;
                CREATE TABLE Web_Schedules_Drops (id INT IDENTITY(1,1) PRIMARY KEY, schedule_id INT, image_path VARCHAR(255), CONSTRAINT FK_S_Drops FOREIGN KEY (schedule_id) REFERENCES Web_Schedules(id) ON DELETE CASCADE);
                IF OBJECT_ID('Web_Downloads', 'U') IS NOT NULL DROP TABLE Web_Downloads;
                CREATE TABLE Web_Downloads (id INT PRIMARY KEY IDENTITY(1,1), name VARCHAR(100) NOT NULL, url VARCHAR(255) NOT NULL, description VARCHAR(MAX) NULL, date_added DATETIME DEFAULT GETDATE());
                IF OBJECT_ID('Web_Market_Chars', 'U') IS NOT NULL DROP TABLE Web_Market_Chars;
                CREATE TABLE Web_Market_Chars (id INT PRIMARY KEY IDENTITY(1,1), char_name VARCHAR(10) NOT NULL, seller_id VARCHAR(10) NOT NULL, price INT NOT NULL, char_class INT, char_level INT, char_resets INT, char_str INT DEFAULT 0, char_agi INT DEFAULT 0, char_vit INT DEFAULT 0, char_ene INT DEFAULT 0, inventory VARBINARY(MAX) NULL, magic_list VARBINARY(MAX) NULL, status INT DEFAULT 1, date_listed DATETIME DEFAULT GETDATE());
                IF OBJECT_ID('Web_Guides', 'U') IS NOT NULL DROP TABLE Web_Guides;
                CREATE TABLE Web_Guides (id INT PRIMARY KEY IDENTITY(1,1), title VARCHAR(255) NOT NULL, category VARCHAR(50) NOT NULL, content TEXT NOT NULL, image_path VARCHAR(255) NULL, date_posted DATETIME DEFAULT GETDATE());";
                $pdo->exec($sql_reset);
                $pdo->exec($sql_sp_hero);
                $pdo->exec("EXEC SP_CALCULATE_HERO_OF_MONTH");
            }

            if ($mode === 'update') {
                $pdo->exec("IF OBJECT_ID('Web_Guides', 'U') IS NOT NULL DROP TABLE Web_Guides;
                CREATE TABLE Web_Guides (id INT PRIMARY KEY IDENTITY(1,1), title VARCHAR(255) NOT NULL, category VARCHAR(50) NOT NULL, content TEXT NOT NULL, image_path VARCHAR(255) NULL, date_posted DATETIME DEFAULT GETDATE());");
            }

            $pdo->exec("IF NOT EXISTS (SELECT * FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = 'MEMB_INFO' AND COLUMN_NAME = 'google_2fa_secret') ALTER TABLE MEMB_INFO ADD google_2fa_secret VARCHAR(100) NULL;");

            $check_admin = $pdo->prepare("SELECT COUNT(*) FROM MEMB_INFO WHERE memb___id = ?");
            $check_admin->execute([$adm_u]);
            if ($check_admin->fetchColumn() == 0) {
                $qCols = $pdo->query("SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = 'MEMB_INFO'");
                $realCols = $qCols->fetchAll(PDO::FETCH_COLUMN);
                $fields = ['memb___id', 'memb__pwd', 'memb_name'];
                $params = [':u' => $adm_u, ':p' => $adm_p, ':n' => $adm_u];
                if (in_array('sno__numb', $realCols)) { $fields[] = 'sno__numb'; $params[':sno'] = '1'; }
                if (in_array('mail_addr', $realCols)) { $fields[] = 'mail_addr'; $params[':mail'] = 'admin@mail.com'; }
                if (in_array('ctlcode', $realCols))   { $fields[] = 'ctlcode';   $params[':ctl'] = '1'; }
                $pdo->prepare("INSERT INTO MEMB_INFO (" . implode(',', $fields) . ") VALUES (" . implode(',', array_keys($params)) . ")")->execute($params);
            } else {
                $pdo->prepare("UPDATE MEMB_INFO SET memb__pwd = :p WHERE memb___id = :u")->execute([':u' => $adm_u, ':p' => $adm_p]);
            }

            $folder = __DIR__ . '/../config';
            if (!file_exists($folder)) { mkdir($folder, 0755, true); }
            file_put_contents($folder . '/settings.php', "<?php\n\$db_settings = ['host'=>'$v_ip','user'=>'$v_user','pass'=>'$v_pass','name'=>'$v_db','key'=>'$key','admin_user'=>'$adm_u'];\n?>");

            $new_secret = $ga->createSecret();
            $qrUrl = "https://api.qrserver.com/v1/create-qr-code/?size=300x300&data=" . urlencode("otpauth://totp/MasterCore:".$adm_u."?secret=".$new_secret."&issuer=MasterCore");

            echo json_encode(['status' => 'success', 'secret' => $new_secret, 'qr' => $qrUrl]);
        } catch (Exception $e) { echo json_encode(['status' => 'error', 'message' => $e->getMessage()]); }
        exit;
    }

    if ($_GET['action'] == 'activate_2fa') {
        try {
            require(__DIR__ . '/../config/settings.php');
            $dsn = "dblib:host=".$db_settings['host'].":1433;dbname=".$db_settings['name'].";charset=UTF8";
            $pdo = new PDO($dsn, $db_settings['user'], $db_settings['pass']);
            
            $code = str_replace(' ', '', $_POST['code']);
            $secret = trim($_POST['secret']);

            if ($ga->verifyCode($secret, $code)) {
                $pdo->prepare("UPDATE MEMB_INFO SET google_2fa_secret = ? WHERE memb___id = ?")->execute([$secret, $db_settings['admin_user']]);
                echo json_encode(['status' => 'success']);
            } else {
                throw new Exception("Código Inválido. Se intentó validar con una ventana de 12 horas pero sigue fallando.");
            }
        } catch (Exception $e) { echo json_encode(['status' => 'error', 'message' => $e->getMessage()]); }
        exit;
    }
}
?>
<!DOCTYPE html>
<html lang="es">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Master Core - Auto-Installer v2.0</title>
    <script src="https://cdn.tailwindcss.com"></script>
    <link href="https://fonts.googleapis.com/css2?family=Cinzel:wght@400;700&family=Roboto:wght@300;400;700&display=swap" rel="stylesheet">
    <script src="https://unpkg.com/lucide@latest"></script>
    <style>
        body { 
            background: radial-gradient(circle at center, #1a0a0a 0%, #050505 100%); 
            font-family: 'Roboto', sans-serif;
            color: #e6d6c6;
        }
        .font-title { font-family: 'Cinzel', serif; }
        .glass { background: rgba(255, 255, 255, 0.02); backdrop-filter: blur(10px); border: 1px solid rgba(255, 255, 255, 0.05); }
        .input-dark { background: rgba(0,0,0,0.3); border: 1px solid rgba(255,255,255,0.1); color: white; transition: 0.3s; }
        .input-dark:focus { border-color: #991b1b; outline: none; background: rgba(0,0,0,0.5); box-shadow: 0 0 15px rgba(153, 27, 27, 0.1); }
        .btn-install { background: linear-gradient(135deg, #991b1b 0%, #450a0a 100%); transition: 0.3s; }
        .btn-install:hover { transform: translateY(-2px); filter: brightness(1.1); box-shadow: 0 10px 20px rgba(0,0,0,0.4); }
        .progress-bar { height: 4px; background: #222; border-radius: 2px; overflow: hidden; }
        .progress-fill { width: 0%; height: 100%; background: #991b1b; transition: width 0.4s; }
        .modal-2fa-overlay { background: rgba(0, 0, 0, 0.95); backdrop-filter: blur(20px); position: fixed; inset: 0; z-index: 999; display: none; align-items: center; justify-content: center; padding: 20px; }
        .modal-2fa-content { 
            background: linear-gradient(145deg, #2a0505 0%, #0a0202 100%); 
            border: 2px solid #d4af37; 
            box-shadow: 0 0 60px rgba(212, 175, 55, 0.15);
            border-radius: 40px;
            padding: 45px;
            max-width: 480px;
            width: 100%;
            text-align: center;
        }
        .gold-text { color: #d4af37; text-shadow: 0 0 15px rgba(212, 175, 55, 0.4); }
        .red-crystal { color: #ff0000; filter: drop-shadow(0 0 20px #ff0000); }
        .btn-gold { background: linear-gradient(135deg, #d4af37 0%, #8a6d3b 100%); color: #000; font-weight: 900; transition: 0.4s; }
        .btn-gold:hover { transform: scale(1.02); filter: brightness(1.2); box-shadow: 0 0 25px rgba(212, 175, 55, 0.3); }
        .qr-frame { background: #fff; padding: 15px; border-radius: 25px; display: inline-block; margin: 25px 0; border: 5px solid #d4af37; box-shadow: 0 0 30px rgba(255,255,255,0.1); }
        #qr-img { width: 260px; height: 260px; }
        .peer:checked ~ .toggle-bg { background-color: #ff0000; box-shadow: 0 0 15px rgba(255, 0, 0, 0.4); }
    </style>
</head>
<body class="min-h-screen flex items-center justify-center p-6">
    <div class="max-w-xl w-full">
        <div class="text-center mb-8">
            <h1 class="text-4xl font-title text-white mb-2 tracking-widest text-shadow">MASTER <span class="text-red-700">CORE</span></h1>
            <p class="text-gray-500 text-[10px] uppercase tracking-[0.5em]">Premium Auto-Installer v2.0</p>
        </div>

        <div class="glass rounded-3xl p-8 shadow-2xl relative overflow-hidden">
            <div id="setup-form">
                <div class="flex items-center gap-3 mb-6 pb-4 border-b border-white/5">
                    <i data-lucide="gem" class="text-red-600 w-5 h-5 red-crystal"></i>
                    <h2 class="text-white font-bold uppercase text-xs tracking-widest">Configuración SQL Server</h2>
                </div>
                <div class="grid grid-cols-2 gap-4">
                    <div class="col-span-2">
                        <label class="text-[9px] uppercase text-gray-500 font-bold mb-1 block">Licencia Master Key</label>
                        <input type="text" id="license_key" class="input-dark w-full p-3 rounded-xl text-sm" placeholder="MU-PRO-XXXX-XXXX">
                    </div>
                    <div>
                        <label class="text-[9px] uppercase text-gray-500 font-bold mb-1 block">IP VPS / Host</label>
                        <input type="text" id="vps_ip" class="input-dark w-full p-3 rounded-xl text-sm" value="185.140.33.79">
                    </div>
                    <div>
                        <label class="text-[9px] uppercase text-gray-500 font-bold mb-1 block">Base de Datos</label>
                        <input type="text" id="vps_db" class="input-dark w-full p-3 rounded-xl text-sm" value="MuOnline">
                    </div>
                    <div>
                        <label class="text-[9px] uppercase text-gray-500 font-bold mb-1 block">Usuario SQL</label>
                        <input type="text" id="vps_user" class="input-dark w-full p-3 rounded-xl text-sm" value="sa">
                    </div>
                    <div>
                        <label class="text-[9px] uppercase text-gray-500 font-bold mb-1 block">Contraseña SQL</label>
                        <input type="password" id="vps_pass" class="input-dark w-full p-3 rounded-xl text-sm">
                    </div>
                </div>
                <div class="flex items-center gap-3 mt-8 mb-6 pb-4 border-b border-white/5">
                    <i data-lucide="shield-check" class="text-red-600 w-5 h-5"></i>
                    <h2 class="text-white font-bold uppercase text-xs tracking-widest">Credenciales Administrativas</h2>
                </div>
                <div class="grid grid-cols-2 gap-4 mb-6">
                    <div>
                        <label class="text-[9px] uppercase text-gray-500 font-bold mb-1 block">Usuario Admin</label>
                        <input type="text" id="admin_user" class="input-dark w-full p-3 rounded-xl text-sm" placeholder="Admin">
                    </div>
                    <div>
                        <label class="text-[9px] uppercase text-gray-500 font-bold mb-1 block">Contraseña Admin</label>
                        <input type="password" id="admin_pass" class="input-dark w-full p-3 rounded-xl text-sm">
                    </div>
                </div>

                <div class="flex items-center justify-between bg-white/5 p-4 rounded-2xl mb-8 border border-white/10">
                    <div class="flex items-center gap-3">
                        <i data-lucide="shield-alert" class="red-crystal w-5 h-5"></i>
                        <div>
                            <p class="text-[10px] gold-text font-bold uppercase tracking-widest">Seguridad Adicional</p>
                            <p class="text-[9px] text-gray-500 uppercase">Activar Blindaje 2FA</p>
                        </div>
                    </div>
                    <label class="relative inline-flex items-center cursor-pointer">
                        <input type="checkbox" id="enable_2fa" class="sr-only peer" checked>
                        <div class="w-11 h-6 bg-gray-700 peer-focus:outline-none rounded-full peer toggle-bg after:content-[''] after:absolute after:top-[2px] after:left-[2px] after:bg-white after:rounded-full after:h-5 after:w-5 after:transition-all peer-checked:after:translate-x-full"></div>
                    </label>
                </div>

                <button onclick="runInstall('detect')" class="btn-install w-full py-4 rounded-2xl text-white font-bold uppercase text-xs tracking-[0.2em] shadow-lg">Finalizar Instalación</button>
            </div>

            <div id="conflict-form" class="hidden py-8 text-center">
                <i data-lucide="alert-triangle" class="text-yellow-500 w-12 h-12 mx-auto mb-4"></i>
                <h3 class="text-white font-bold uppercase text-sm mb-2">Tablas Existentes</h3>
                <p class="text-gray-500 text-xs mb-8">Se detectó una instalación previa.</p>
                <div class="flex gap-4">
                    <button onclick="runInstall('update')" class="flex-1 bg-white/5 hover:bg-white/10 p-4 rounded-xl text-white text-[10px] uppercase font-bold tracking-widest transition">Actualizar</button>
                    <button onclick="runInstall('reset')" class="flex-1 bg-red-600/20 hover:bg-red-600/40 p-4 rounded-xl text-red-500 text-[10px] uppercase font-bold tracking-widest transition border border-red-600/20">Reinstalar</button>
                </div>
            </div>

            <div id="loading-area" class="hidden py-12 text-center">
                <div class="mb-8 relative inline-block">
                    <div class="w-20 h-20 border-4 border-red-600/20 border-t-red-600 rounded-full animate-spin mx-auto"></div>
                    <i data-lucide="refresh-cw" class="absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 text-red-600 w-6 h-6"></i>
                </div>
                <h3 id="status-text" class="text-white font-bold uppercase text-sm tracking-widest mb-4">Iniciando Sincronización...</h3>
                <div class="progress-bar max-w-xs mx-auto"><div id="bar" class="progress-fill"></div></div>
            </div>
        </div>
    </div>

    <div id="modal-2fa" class="modal-2fa-overlay">
        <div class="modal-2fa-content">
            <i data-lucide="shield-check" class="red-crystal w-14 h-14 mx-auto mb-4"></i>
            <div id="step-qr">
                <h2 class="font-title gold-text text-2xl mb-2 uppercase tracking-tighter">Blindaje 2FA Maestro</h2>
                <p class="text-gray-500 text-[10px] uppercase tracking-widest mb-4">Sincronización de Tiempo Extendida (12H)</p>
                <div class="qr-frame"><img id="qr-img" src="" alt="Google Auth QR"></div>
                <p class="text-xs text-gray-400 mb-6 px-4">Ingresa el código generado en tu aplicación para finalizar el blindaje del panel.</p>
                <input type="text" id="2fa_code" maxlength="6" class="input-dark w-full p-5 rounded-2xl text-center text-4xl font-bold tracking-[0.3em] mb-6 border-2 border-[#d4af37]/30" placeholder="000000">
                <button onclick="verifyAndActivate()" class="btn-gold w-full py-5 rounded-2xl uppercase text-sm tracking-widest shadow-xl">VINCULAR Y FINALIZAR</button>
            </div>
        </div>
    </div>

    <script>
        lucide.createIcons();
        let globalSecret = "";

        function runInstall(mode) {
            const data = new FormData();
            const ids = ['vps_ip', 'vps_db', 'vps_user', 'vps_pass', 'admin_user', 'admin_pass', 'license_key'];
            const use2FA = document.getElementById('enable_2fa').checked;

            for(let id of ids) {
                let v = document.getElementById(id).value;
                if(!v && id !== 'vps_pass') { alert("Completa el campo: " + id); return; }
                data.append(id, v);
            }
            data.append('install_mode', mode);

            document.getElementById('setup-form').style.display = 'none';
            document.getElementById('conflict-form').style.display = 'none';
            document.getElementById('loading-area').style.display = 'block';
            
            fetch('?action=run_install', { method: 'POST', body: data })
            .then(r => r.json())
            .then(res => {
                if(res.status === 'conflict') {
                    document.getElementById('loading-area').style.display = 'none';
                    document.getElementById('conflict-form').style.display = 'block';
                    return;
                }
                if(res.status === 'success') {
                    globalSecret = res.secret;
                    document.getElementById('qr-img').src = res.qr;
                    
                    let p = 0;
                    let bar = document.getElementById('bar');
                    let txt = document.getElementById('status-text');
                    let itv = setInterval(() => {
                        p += 2; bar.style.width = p + '%';
                        if(p == 30) txt.innerText = "Estructurando Puntos de Gloria...";
                        if(p == 50) txt.innerText = "Desplegando Sistema de Guías...";
                        if(p == 70) txt.innerText = "Aplicando Parches de Rareza...";
                        if(p == 90) txt.innerText = "Preparando Blindaje de Seguridad...";
                        if(p >= 100) {
                            clearInterval(itv);
                            if(use2FA) {
                                document.getElementById('modal-2fa').style.display = 'flex';
                            } else {
                                alert("¡Instalación Finalizada!");
                                window.location.href = "../index.php";
                            }
                        }
                    }, 30);
                } else {
                    alert("ERROR: " + res.message);
                    location.reload();
                }
            }).catch(e => { alert("Error de red."); location.reload(); });
        }

        function verifyAndActivate() {
            const code = document.getElementById('2fa_code').value.replace(/\s/g, '');
            if(code.length !== 6) { alert("Ingresa los 6 dígitos."); return; }
            const data = new FormData();
            data.append('code', code);
            data.append('secret', globalSecret);
            fetch('?action=activate_2fa', { method: 'POST', body: data })
            .then(r => r.json())
            .then(res => {
                if(res.status === 'success') {
                    alert("¡Blindaje Maestro Activado!");
                    window.location.href = "../index.php";
                } else {
                    alert(res.message);
                }
            });
        }
    </script>
</body>
</html>