<?php
/**
 * install.php — Instalador idempotente.
 *
 * Crea las tablas desde lib/schema.sql, siembra un admin por defecto,
 * los ajustes globales por defecto y los idiomas. Se puede ejecutar
 * tantas veces como haga falta sin duplicar datos.
 *
 * Uso por CLI:   php install.php
 * Uso por web:   abrir http://host/install.php
 */

declare(strict_types=1);

require_once __DIR__ . '/lib/db.php';
require_once __DIR__ . '/lib/helpers.php';
require_once __DIR__ . '/lib/themes.php';

$isCli = (PHP_SAPI === 'cli');
$log = [];

/**
 * Acumula una línea de log para mostrarla al final.
 */
function step(string $msg): void
{
    global $log;
    $log[] = $msg;
}

/**
 * ¿Existe la columna $column en la tabla $table? (para migraciones idempotentes).
 * SQLite no soporta "ADD COLUMN IF NOT EXISTS"; usamos PRAGMA table_info.
 */
function column_exists(PDO $pdo, string $table, string $column): bool
{
    // El nombre de tabla no viene de entrada de usuario; se usa solo internamente.
    $stmt = $pdo->query('PRAGMA table_info(' . $table . ')');
    foreach ($stmt->fetchAll() as $col) {
        if (($col['name'] ?? '') === $column) {
            return true;
        }
    }
    return false;
}

try {
    $pdo = db();

    /* 1. Crear el esquema desde schema.sql -------------------------- */
    $schema = file_get_contents(__DIR__ . '/lib/schema.sql');
    if ($schema === false) {
        throw new RuntimeException('No se pudo leer lib/schema.sql');
    }
    $pdo->exec($schema);
    step('Esquema aplicado (tablas creadas si no existían).');

    /* 1b. Migraciones idempotentes de columnas (bases antiguas) ----- */
    // En SQLite no hay "ADD COLUMN IF NOT EXISTS"; comprobamos antes con PRAGMA.
    if (!column_exists($pdo, 'playlists', 'username')) {
        $pdo->exec('ALTER TABLE playlists ADD COLUMN username TEXT');
        step('Columna playlists.username añadida.');
    }
    if (!column_exists($pdo, 'playlists', 'password')) {
        $pdo->exec('ALTER TABLE playlists ADD COLUMN password TEXT');
        step('Columna playlists.password añadida.');
    }
    // El índice sobre playlists(username, password) se crea aquí, ya garantizadas
    // las columnas (en bases nuevas o antiguas migradas).
    $pdo->exec('CREATE INDEX IF NOT EXISTS idx_playlists_userpass ON playlists(username, password)');

    // Códigos con credenciales embebidas (user/pass/DNS), permanente vs expira, proteger lista.
    foreach ([
        ['username',  'TEXT'],
        ['password',  'TEXT'],
        ['dns_id',    'INTEGER'],
        ['name',      'TEXT'],
        ['protected', 'INTEGER NOT NULL DEFAULT 0'],
        ['permanent', 'INTEGER NOT NULL DEFAULT 0'],
        ['expire',    'TEXT'],
        ['use_count', 'INTEGER NOT NULL DEFAULT 0'],
    ] as [$col, $type]) {
        if (!column_exists($pdo, 'activation_codes', $col)) {
            $pdo->exec("ALTER TABLE activation_codes ADD COLUMN $col $type");
            step("Columna activation_codes.$col añadida.");
        }
    }
    // Nombre de cuenta que el usuario ingresa en la app tras iniciar sesión.
    if (!column_exists($pdo, 'devices', 'account_name')) {
        $pdo->exec('ALTER TABLE devices ADD COLUMN account_name TEXT');
        step('Columna devices.account_name añadida.');
    }

    // Tablas nuevas (menu_ads, leagues, sport_events) ya creadas por schema.sql
    // con IF NOT EXISTS. Aquí solo dejamos constancia para bases ya existentes.
    foreach (['menu_ads', 'leagues', 'sport_events'] as $tbl) {
        $exists = (int) $pdo->query(
            "SELECT COUNT(*) FROM sqlite_master WHERE type='table' AND name='" . $tbl . "'"
        )->fetchColumn();
        step("Tabla $tbl " . ($exists ? 'presente.' : 'NO disponible (revisar schema).'));
    }

    // Índices de apoyo para las tablas nuevas (guardados con IF NOT EXISTS).
    $pdo->exec('CREATE INDEX IF NOT EXISTS idx_menu_ads_sort     ON menu_ads(sort)');
    $pdo->exec('CREATE INDEX IF NOT EXISTS idx_leagues_name      ON leagues(name)');
    $pdo->exec('CREATE INDEX IF NOT EXISTS idx_sport_events_date ON sport_events(event_date, event_time)');

    /* 2. Admin por defecto (admin / admin) -------------------------- */
    $count = (int) $pdo->query('SELECT COUNT(*) FROM admins')->fetchColumn();
    if ($count === 0) {
        $stmt = $pdo->prepare(
            'INSERT INTO admins (username, password_hash, created_at) VALUES (?, ?, ?)'
        );
        $stmt->execute([
            'admin',
            password_hash('admin', PASSWORD_DEFAULT),
            now_iso(),
        ]);
        step('Admin por defecto creado: usuario "admin" / contraseña "admin".');
        step('⚠  CAMBIA esta contraseña inmediatamente tras el primer acceso.');
    } else {
        step('Ya existe al menos un admin: no se crea otro.');
    }

    /* 3. Ajustes globales por defecto ------------------------------- */
    $defaultSettings = [
        // idx 5 -> valor IBO "6" -> activity_home_6 (home con lista/contenido). Un
        // install fresco NO debe caer en idx 0 (-> IBO "1" -> home_1 SIN lista).
        'default_theme'       => '5',
        'default_login_theme' => '5',
        'app_version'         => '1.0',
        'apk_url'             => '',
        'def_login_title'     => 'Bienvenido',
        'def_login_content'   => 'Sube tu lista para empezar',
        'def_noti_title'      => '',
        'def_noti_content'    => '',
        'tmdb_api_key'        => 'b24683ba85cd4503335347d3785ddab7',
        // Playlist DEMO (servidor + credenciales que la app puede probar).
        'demo_dns_id'         => '0',
        'demo_url'            => '',
        'demo_username'       => '',
        'demo_password'       => '',
        'demo_name'           => 'Demo',
        // Soporte / mensaje de bienvenida (dos líneas de contacto).
        'support_message_one' => '',
        'support_message_two' => '',
        // Deportes (panel de eventos): activación, estilo y ventana de días.
        'sport_enabled'       => '0',
        'sport_header'        => 'Deportes',
        'sport_border'        => '#000000',
        'sport_background'    => '#000000',
        'sport_text'          => '#ffffff',
        'sport_days'          => '7',
    ];
    $ins = $pdo->prepare('INSERT OR IGNORE INTO settings (key, value) VALUES (?, ?)');
    $seeded = 0;
    foreach ($defaultSettings as $key => $value) {
        $ins->execute([$key, $value]);
        if ($ins->rowCount() > 0) {
            $seeded++;
        }
    }
    step("Ajustes por defecto sembrados ($seeded nuevos; el resto ya existían).");

    /* 4. Idiomas ---------------------------------------------------- */
    $languages = [
        'en' => 'English',
        'es' => 'Español',
        'fr' => 'Français',
        'pt' => 'Português',
        'ar' => 'العربية',
        'de' => 'Deutsch',
        'it' => 'Italiano',
    ];
    $insLang = $pdo->prepare('INSERT OR IGNORE INTO languages (code, name, enabled) VALUES (?, ?, 1)');
    $langSeeded = 0;
    foreach ($languages as $code => $name) {
        $insLang->execute([$code, $name]);
        if ($insLang->rowCount() > 0) {
            $langSeeded++;
        }
    }
    step("Idiomas sembrados ($langSeeded nuevos; el resto ya existían).");

    /* 5. Confirmación de los 6 temas glass (viven en lib/themes.php) ----- */
    step('Temas disponibles: ' . count(theme_names()) . ' (idx 0..5, definidos en lib/themes.php).');

    step('');
    step('✔ Instalación completada. Ya puedes iniciar sesión en login.php (admin/admin).');
} catch (Throwable $ex) {
    $error = 'ERROR durante la instalación: ' . $ex->getMessage();
    if ($isCli) {
        fwrite(STDERR, $error . PHP_EOL);
        exit(1);
    }
    http_response_code(500);
    echo '<pre>' . e($error) . '</pre>';
    exit;
}

/* ---- Salida ------------------------------------------------------- */
if ($isCli) {
    echo implode(PHP_EOL, $log) . PHP_EOL;
    exit(0);
}

// Salida web sencilla.
?>
<!doctype html>
<html lang="es">
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>Instalación · Panel IPTV</title>
    <link rel="stylesheet" href="assets/panel.css">
</head>
<body class="install-page">
    <main class="install-card">
        <h1>Instalación del panel</h1>
        <ul class="install-log">
            <?php foreach ($log as $line): ?>
                <?php if ($line === ''): ?>
                    <li class="spacer"></li>
                <?php else: ?>
                    <li><?= e($line) ?></li>
                <?php endif; ?>
            <?php endforeach; ?>
        </ul>
        <p class="install-actions">
            <a class="btn btn-primary" href="login.php">Ir al login</a>
        </p>
        <p class="muted">Puedes volver a ejecutar este instalador sin problema: es idempotente.</p>
    </main>
</body>
</html>
