<?php
/**
 * Flexia — first-run installer lock + shared help HTML for 403 / hosting errors.
 */

declare(strict_types=1);

if (!defined('ANTARA_ROOT')) {
    define('ANTARA_ROOT', dirname(__DIR__));
}

require_once ANTARA_ROOT . '/core/security/paths.php';
require_once ANTARA_ROOT . '/core/security/vault_state.php';
require_once __DIR__ . '/vendor_assets.php';

function antara_install_is_locked(): bool
{
    return is_file(AntaraPaths::installLockFile());
}

/** true mientras no exista install.lock (asistente /install/ activo). */
function antara_install_is_active(): bool
{
    return !antara_install_is_locked();
}

/**
 * Redirige al instalador si la instalación inicial no ha terminado.
 */
function antara_install_redirect_if_active(): void
{
    if (antara_install_is_locked()) {
        return;
    }
    $to = antara_install_base_url();
    if (!headers_sent()) {
        header('Location: ' . $to, true, 302);
        header('Cache-Control: no-store, no-cache, must-revalidate');
    } else {
        echo '<script>location.replace(' . json_encode($to, JSON_UNESCAPED_SLASHES | JSON_HEX_TAG | JSON_HEX_AMP) . ');</script>';
    }
    exit;
}

/**
 * Public URL path prefix of the app (ends with /). Uses SCRIPT_NAME.
 */
function antara_public_app_base(): string
{
    $sn = str_replace('\\', '/', (string)($_SERVER['SCRIPT_NAME'] ?? ''));
    if ($sn === '' || $sn === '/') {
        return '/';
    }
    if (preg_match('#^/install/(index|forbidden|recover|formatting)\.php$#', $sn)) {
        return '/';
    }
    if (preg_match('#^(.+)/install/(index|forbidden|recover|formatting)\.php$#', $sn, $m)) {
        return rtrim($m[1], '/') . '/';
    }
    if (preg_match('#^/admin/#', $sn)) {
        return '/';
    }
    if (preg_match('#^(.+)/admin/#', $sn, $m)) {
        return rtrim($m[1], '/') . '/';
    }
    if (preg_match('#^/login/index\.php$#', $sn)) {
        return '/';
    }
    if (preg_match('#^(.+)/login/index\.php$#', $sn, $m)) {
        return rtrim($m[1], '/') . '/';
    }
    if (preg_match('#^/core/auth/#', $sn)) {
        return '/';
    }
    if (preg_match('#^(.+)/core/auth/#', $sn, $m)) {
        return rtrim($m[1], '/') . '/';
    }

    return rtrim(dirname($sn), '/') . '/';
}

/**
 * @return string Ruta web al login (barra final).
 */
function antara_public_login_url(): string
{
    return antara_public_app_base() . 'login/';
}

/**
 * Punto de acceso público: instalador si está activo; si no, login.
 */
function antara_public_auth_entry_url(): string
{
    return antara_install_is_active() ? antara_install_base_url() : antara_public_login_url();
}

/**
 * Valores por defecto de start_url y scope del manifest según la ruta pública de la app.
 *
 * @return array{startUrl: string, scope: string}
 */
function antara_install_pwa_default_scope_and_start(): array
{
    $base = antara_public_app_base();
    if ($base === '/' || $base === '') {
        return ['startUrl' => './', 'scope' => './'];
    }

    return ['startUrl' => './', 'scope' => $base];
}

/**
 * @return string Web path to install/ (trailing slash).
 */
function antara_install_base_url(): string
{
    return antara_public_app_base() . 'install/';
}

/**
 * @return string Web path to install/recover.php (no trailing slash on file).
 */
function antara_recovery_url(): string
{
    return antara_public_app_base() . 'install/recover.php';
}

/**
 * Render HTML help for deployment / permissions (Flexia branding).
 *
 * @param array $opts {
 *   @var string $title Short heading
 *   @var string $message Main paragraph
 *   @var bool $show_install_link Offer link to /install/ when not locked
 *   @var int $http_status Optional status code (default 403)
 * }
 */
function antara_install_render_help_page(array $opts): void
{
    $title = htmlspecialchars((string)($opts['title'] ?? 'Flexia'), ENT_QUOTES, 'UTF-8');
    $message = htmlspecialchars((string)($opts['message'] ?? ''), ENT_QUOTES, 'UTF-8');
    $showInstall = !empty($opts['show_install_link']) && !antara_install_is_locked();
    $installHref = htmlspecialchars(antara_install_base_url(), ENT_QUOTES, 'UTF-8');
    $status = (int)($opts['http_status'] ?? 403);
    if (!headers_sent()) {
        http_response_code($status);
        header('Content-Type: text/html; charset=utf-8');
        header('X-Robots-Tag: noindex, nofollow');
    }
    echo '<!DOCTYPE html><html lang="es"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1">';
    echo '<title>' . $title . ' — Flexia</title>';
    echo '<style>
      body{font-family:system-ui,Segoe UI,sans-serif;background:#0a0f18;color:#e8f0ff;margin:0;line-height:1.55}
      .wrap{max-width:42rem;margin:0 auto;padding:2rem 1.25rem 3rem}
      h1{font-size:1.35rem;font-weight:700;margin:0 0 .5rem;color:#7dd3fc}
      h2{font-size:1rem;margin:1.5rem 0 .5rem;color:#94a3b8}
      p{margin:.65rem 0}
      ul{padding-left:1.2rem;margin:.5rem 0}
      li{margin:.35rem 0}
      a{color:#38bdf8}
      .card{background:#111827;border:1px solid #1e293b;border-radius:12px;padding:1.25rem 1.35rem;margin-top:1rem}
      .btn{display:inline-block;margin-top:1rem;padding:.55rem 1rem;background:#0ea5e9;color:#fff;border-radius:8px;text-decoration:none;font-weight:600}
    </style></head><body><div class="wrap">';
    echo '<h1>' . $title . '</h1>';
    echo '<p>' . $message . '</p>';
    echo '<div class="card"><h2>Despliegue en hosting</h2><ul>';
    echo '<li>Sube el proyecto completo y comprueba con el hosting que las carpetas internas que usa Flexia tengan permiso de escritura.</li>';
    echo '<li>El esquema de seguridad esencial funciona mejor si la clave de cifrado queda fuera de la web pública (lo prepara el instalador) o en la zona interna protegida del servidor.</li>';
    echo '<li>Usa <strong>HTTPS</strong> en producción.</li>';
    echo '<li>Si ves 403 al abrir una carpeta por URL, suele ser correcto: no debe ser accesible por navegador.</li>';
    echo '</ul>';
    if (AntaraVaultState::recoveryWebAllowed()) {
        $recoverHref = htmlspecialchars(antara_recovery_url(), ENT_QUOTES, 'UTF-8');
        echo '<p><a class="btn" href="' . $recoverHref . '" style="background:#0369a1">Recuperación criptográfica</a> — solo si debes apartar los datos cifrados a cuarentena y reinstalar (pérdida de usuarios y credenciales).</p>';
    } elseif (antara_install_is_locked()) {
        echo '<p>Recuperación criptográfica: quien administra el servidor debe activar el permiso de recuperación o el token acordado; después podrás abrir la página de recuperación del instalador.</p>';
    }
    if ($showInstall) {
        echo '<p><a class="btn" href="' . $installHref . '">Abrir instalador Flexia</a></p>';
    } elseif (antara_install_is_locked()) {
        echo '<p>El instalador ya se completó. Si algo falla, revisa permisos con el hosting o entra al panel de administración.</p>';
    }
    echo '</div></div></body></html>';
    exit;
}

function antara_install_write_lock(): bool
{
    $path = AntaraPaths::installLockFile();
    AntaraPaths::ensureDirs();
    $payload = json_encode([
        'completed_at' => gmdate('Y-m-d\TH:i:s\Z'),
        'version' => 1,
    ], JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE);
    if ($payload === false) {
        return false;
    }
    $written = @file_put_contents($path, $payload . "\n", LOCK_EX) !== false;
    if ($written) {
        require_once __DIR__ . '/flexia_instance.php';
        antara_flexia_regenerate_instance('install_complete');
    }
    return $written;
}

/**
 * Elimina install.lock para volver a habilitar el asistente web en /install/.
 */
function antara_install_remove_lock(): bool
{
    $path = AntaraPaths::installLockFile();
    if (!is_file($path)) {
        return true;
    }
    return @unlink($path);
}
