<?php
declare(strict_types=1);

require_once dirname(__DIR__) . DIRECTORY_SEPARATOR . 'app' . DIRECTORY_SEPARATOR . 'bootstrap.php';
require_once __DIR__ . DIRECTORY_SEPARATOR . 'lib.php';

/** @param array<string, string> $values */
function install_form_value(array $values, string $key, string $default = ''): string
{
    return install_escape((string) ($values[$key] ?? $default));
}

/**
 * @param array<string, string> $values
 * @param array<string, string> $errors
 * @param array<int, string> $messages
 */
function install_render_page(
    string $locale,
    array $values,
    array $errors,
    array $messages,
    string $lockStatus,
    array $requirements,
    bool $justInstalled = false
): void {
    $text = install_translations($locale);
    $dictionary = install_language_dictionary($locale);
    $direction = (string) (($dictionary['install']['direction'] ?? null) ?: 'ltr');
    $availableLocales = install_available_locales();
    $alternateLocale = $availableLocales[0] ?? $locale;
    foreach ($availableLocales as $availableLocale) {
        if ($availableLocale !== $locale) { $alternateLocale = $availableLocale; break; }
    }
    $alternateLabel = install_locale_name($alternateLocale);
    $alternateUrl = '?lang=' . install_escape($alternateLocale);
    $fieldError = static function (array $errors, string $key): string {
        return isset($errors[$key]) ? '<small class="error">' . install_escape($errors[$key]) . '</small>' : '';
    };
    $input = static function (string $key, string $label, string $type = 'text', string $default = '') use ($values, $fieldError, $errors): string {
        return '<label>' . install_escape($label)
            . '<input type="' . install_escape($type) . '" name="' . install_escape($key)
            . '" value="' . install_form_value($values, $key, $default) . '" autocomplete="off">'
            . $fieldError($errors, $key) . '</label>';
    };

    echo '<!doctype html><html lang="' . install_escape($locale) . '" dir="' . $direction . '"><head>';
    echo '<meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1">';
    echo '<title>' . install_escape($text['title']) . '</title><style>';
    echo 'body{margin:0;background:#f4f1e9;color:#19352f;font-family:system-ui,sans-serif}main{max-width:52rem;margin:2rem auto;padding:1.25rem}';
    echo 'article{background:#fff;border:1px solid #d8d0bd;border-radius:1rem;padding:1.25rem;box-shadow:0 12px 30px #19352f12}';
    echo 'section{border-top:1px solid #e7e0d1;padding-top:1rem;margin-top:1rem}h1{margin-top:0;color:#0e6f5c}h2{font-size:1.1rem}';
    echo 'label{display:grid;gap:.35rem;margin:.75rem 0;font-weight:650}input{font:inherit;padding:.7rem;border:1px solid #bfb7a5;border-radius:.55rem}';
    echo 'button{background:#0e6f5c;color:#fff;border:0;border-radius:.55rem;padding:.75rem 1rem;font:inherit;font-weight:700;cursor:pointer}.muted{color:#5d6c66}';
    echo '.hint{margin:-.35rem 0 .9rem;color:#5d6c66;font-size:.9rem}textarea{font:inherit;padding:.7rem;border:1px solid #bfb7a5;border-radius:.55rem;resize:vertical}';
    echo '.error{color:#a3322c;font-weight:500}.notice{padding:.8rem;border-radius:.55rem;background:#f9e8c8;margin:.75rem 0}.ok{background:#dff3e9}.checks{padding:0;list-style:none}.checks li{padding:.35rem 0}.top{display:flex;justify-content:space-between;gap:1rem;align-items:center}.switch{color:#0e6f5c;font-weight:700;text-decoration:none}';
    echo '</style></head><body><main><article><div class="top"><h1>' . install_escape($text['title']) . '</h1><span class="muted">v' . install_escape(app_version()) . '</span><a class="switch" href="' . $alternateUrl . '">' . install_escape($alternateLabel) . '</a></div>';
    echo '<p class="muted">' . install_escape($text['intro']) . '</p>';

    if ($lockStatus === 'valid') {
        // A finished install used to land on the bare "already locked" notice,
        // which reads like a failure and offers nowhere to go. The success
        // path now says so and links to the site and the admin panel.
        if ($justInstalled) {
            $home = install_site_url($values['base_url'] ?? '');
            echo '<div class="notice ok"><strong>' . install_escape($text['success_title']) . '</strong><br>'
                . install_escape($text['success']) . '</div>';
            echo '<p><a class="switch" href="' . install_escape($home) . '">' . install_escape($text['open_site']) . '</a></p>';
            echo '<p><a class="switch" href="' . install_escape(rtrim($home, '/') . '/login') . '">' . install_escape($text['open_admin']) . '</a></p>';
            echo '<div class="notice">' . install_escape($text['remove_installer']) . '</div>';
            echo '</article></main></body></html>';
            return;
        }

        echo '<div class="notice ok">' . install_escape($text['locked']) . '</div>';
        echo '<p><a class="switch" href="' . install_escape(install_site_url($values['base_url'] ?? '')) . '">' . install_escape($text['open_site']) . '</a></p>';
        echo '</article></main></body></html>';
        return;
    }

    if ($lockStatus === 'invalid') {
        echo '<div class="notice">' . install_escape($text['invalid_lock']) . '</div></article></main></body></html>';
        return;
    }

    foreach ($messages as $message) {
        echo '<div class="notice">' . install_escape($message) . '</div>';
    }

    echo '<section><h2>' . install_escape($text['requirements']) . '</h2><ul class="checks">';

    foreach ($requirements['checks'] as $check) {
        // An advisory check that fails is a warning, not a blocker: setup still
        // proceeds, so marking it ✗ beside the fatal ones would misread.
        $state = $check['ok'] ? '✓' : (empty($check['advisory']) ? '✗' : '!');
        echo '<li><strong>' . $state . '</strong> ' . install_escape($check['message']) . '</li>';
    }

    echo '</ul></section><form method="post" autocomplete="off">';
    echo '<input type="hidden" name="csrf" value="' . install_escape(install_csrf_token()) . '">';
    echo '<input type="hidden" name="locale" value="' . install_escape($locale) . '">';
    echo '<section><h2>' . install_escape($text['database']) . '</h2>';
    echo $input('db_host', $text['host'], 'text', 'localhost');
    echo $input('db_port', $text['port'], 'number', '3306');
    echo $input('db_name', $text['database_name'], 'text', '');
    echo $input('db_user', $text['username'], 'text', '');
    echo $input('db_password', $text['password'], 'password');
    echo '</section><section><h2>' . install_escape($text['site_section']) . '</h2>';
    echo $input('site_name', $text['site_name'], 'text', 'Quaeriva');
    echo '<label>' . install_escape($text['site_description'])
        . '<textarea name="site_description" rows="2" maxlength="300">'
        . install_escape((string) ($values['site_description'] ?? '')) . '</textarea>'
        . $fieldError($errors, 'site_description') . '</label>';
    echo '<p class="hint">' . install_escape($text['site_description_hint']) . '</p>';
    echo $input('app_url', $text['app_url'], 'url', '');
    echo '<p class="hint">' . install_escape($text['app_url_hint']) . '</p>';
    echo $input('base_url', $text['site_path'], 'text', install_detect_base_url());
    echo '<p class="hint">' . install_escape($text['site_path_hint']) . '</p>';
    echo $input('admin_path', $text['admin_path'], 'text', 'admin');
    echo '<p class="hint">' . install_escape($text['admin_path_hint']) . '</p>';
    echo '</section><section><h2>' . install_escape($text['admin']) . '</h2>';
    echo $input('admin_name', $text['admin_name']);
    echo $input('admin_email', $text['admin_email'], 'email');
    echo $input('admin_password', $text['admin_password'], 'password');
    echo '<label>' . install_escape($text['language']) . '<select name="locale">';
    foreach ($availableLocales as $availableLocale) {
        echo '<option value="' . install_escape($availableLocale) . '"' . ($locale === $availableLocale ? ' selected' : '') . '>' . install_escape(install_locale_name($availableLocale)) . '</option>';
    }
    echo '</select></label><label><input type="checkbox" name="seed_starter_content" value="1" checked> ' . install_escape($text['seed_starter_content']) . '</label>';
    echo '</section><button type="submit">' . install_escape($text['submit']) . '</button></form></article></main></body></html>';
}

function install_handle_request(): void
{
    app_bootstrap();
    $root = dirname(__DIR__);
    $request = is_array($_POST ?? null) ? $_POST : [];
    $locale = install_requested_locale($request);
    $values = [
        'db_host' => trim((string) ($request['db_host'] ?? 'localhost')),
        'db_port' => trim((string) ($request['db_port'] ?? '3306')),
        'db_name' => trim((string) ($request['db_name'] ?? '')),
        'db_user' => trim((string) ($request['db_user'] ?? '')),
        'site_name' => trim((string) ($request['site_name'] ?? 'Quaeriva')),
        'site_description' => trim((string) ($request['site_description'] ?? '')),
        'app_url' => trim((string) ($request['app_url'] ?? '')),
        'base_url' => trim((string) ($request['base_url'] ?? install_detect_base_url())),
        'admin_path' => trim((string) ($request['admin_path'] ?? 'admin')),
        'admin_name' => trim((string) ($request['admin_name'] ?? '')),
        'admin_email' => trim((string) ($request['admin_email'] ?? '')),
    ];
    $errors = [];
    $messages = [];
    $justInstalled = false;
    $selection = install_lock_path($root, $_SERVER['DOCUMENT_ROOT'] ?? null);
    $lockStatus = install_lock_status($selection['path']);

    if (($_SERVER['REQUEST_METHOD'] ?? 'GET') === 'POST' && $lockStatus === 'missing') {
        if (!install_csrf_valid((string) ($request['csrf'] ?? ''))) {
            $messages[] = install_translations($locale)['csrf'];
        } else {
            $result = install_run_setup($request, [
                'project_root' => $root,
                'document_root' => $_SERVER['DOCUMENT_ROOT'] ?? null,
                'database_config_path' => $root . DIRECTORY_SEPARATOR . 'config' . DIRECTORY_SEPARATOR . 'database.local.php',
            ]);

            if ($result['ok']) {
                $lockStatus = 'valid';
                $justInstalled = true;
                $messages[] = install_translations($locale)['success'];
            } else {
                foreach ($result['errors'] as $key => $message) {
                    if (is_string($key)) {
                        $errors[$key] = $message;
                    } else {
                        $messages[] = $message;
                    }
                }
            }
        }
    }

    $requirementsConfig = app_config('database');
    $submittedValidation = install_validate_setup($request);

    if ($request !== [] && $submittedValidation['errors'] === []) {
        $requirementsConfig = install_database_config_from_setup($request, $submittedValidation['values']);
    }

    $requirements = install_check_requirements($requirementsConfig, $root);
    install_render_page($locale, $values, $errors, $messages, $lockStatus, $requirements, $justInstalled);
}

$isDirectRequest = isset($_SERVER['SCRIPT_FILENAME'])
    && realpath((string) $_SERVER['SCRIPT_FILENAME']) === realpath(__FILE__);

if ($isDirectRequest) {
    install_handle_request();
}
