<?php

declare(strict_types=1);

session_name('fleetlume_install_session');
ini_set('session.use_strict_mode', '1');
ini_set('session.cookie_httponly', '1');
ini_set('session.cookie_samesite', 'Lax');
if ((!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off') || (($_SERVER['HTTP_X_FORWARDED_PROTO'] ?? '') === 'https')) {
    ini_set('session.cookie_secure', '1');
}
session_start();

$rootPath = __DIR__;
$configPath = $rootPath . '/config/config.php';
$schemaPath = $rootPath . '/database/schema.sql';
$lockPath = $rootPath . '/storage/installed.lock';

function installer_e(?string $value): string
{
    return htmlspecialchars((string) $value, ENT_QUOTES, 'UTF-8');
}

function installer_base_url(): string
{
    $script = str_replace('\\', '/', $_SERVER['SCRIPT_NAME'] ?? '');
    $root = rtrim(str_replace('/install.php', '', $script), '/');
    return ($root === '' ? '' : $root) . '/public';
}

function installer_site_url(): string
{
    $forwardedProto = strtolower((string) ($_SERVER['HTTP_X_FORWARDED_PROTO'] ?? ''));
    $isHttps = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off') || $forwardedProto === 'https';
    $scheme = $isHttps ? 'https' : 'http';
    $host = trim((string) ($_SERVER['HTTP_HOST'] ?? 'localhost')) ?: 'localhost';

    return $scheme . '://' . $host;
}

function installer_is_local_host(): bool
{
    $host = strtolower((string) ($_SERVER['HTTP_HOST'] ?? 'localhost'));
    $host = preg_replace('/:\d+$/', '', $host) ?? $host;

    return in_array($host, ['localhost', '127.0.0.1', '::1'], true)
        || str_ends_with($host, '.local')
        || str_ends_with($host, '.test');
}

function installer_public_url(string $siteUrl, string $baseUrl, string $path = ''): string
{
    $url = rtrim($siteUrl, '/') . rtrim($baseUrl, '/');
    return $url . ($path === '' ? '' : '/' . ltrim($path, '/'));
}

function installer_read_config_defaults(string $configPath): array
{
    $defaults = [
        'app_name' => 'FleetLume',
        'site_url' => installer_site_url(),
        'app_env' => installer_is_local_host() ? 'local' : 'production',
        'app_debug' => installer_is_local_host() ? '1' : '0',
        'base_url' => installer_base_url(),
        'db_host' => '127.0.0.1',
        'db_port' => '3306',
        'db_name' => 'fleetlume',
        'db_user' => 'root',
        'db_pass' => '',
        'db_charset' => 'utf8mb4',
        'session_name' => 'fleetlume_session',
        'admin_name' => 'Admin User',
        'admin_email' => 'admin@fleetlume.space',
        'admin_password' => '',
        'seed_sample_data' => '1',
        'lock_installer' => '1',
    ];

    if (!is_file($configPath)) {
        return $defaults;
    }

    $content = file_get_contents($configPath) ?: '';
    foreach ([
        'APP_NAME' => 'app_name',
        'APP_ENV' => 'app_env',
        'APP_URL' => 'site_url',
        'BASE_URL' => 'base_url',
        'DB_HOST' => 'db_host',
        'DB_PORT' => 'db_port',
        'DB_NAME' => 'db_name',
        'DB_USER' => 'db_user',
        'DB_PASS' => 'db_pass',
        'DB_CHARSET' => 'db_charset',
        'SESSION_NAME' => 'session_name',
    ] as $constant => $key) {
        if (preg_match("~const\\s+{$constant}\\s*=\\s*'([^']*)'\\s*;~", $content, $matches)) {
            $value = stripcslashes($matches[1]);
            if ($constant === 'APP_URL' && $value === '') {
                continue;
            }
            if ($constant === 'BASE_URL' && $value === '' && installer_is_local_host()) {
                continue;
            }
            $defaults[$key] = $value;
        }
    }

    if (preg_match("~const\\s+APP_DEBUG\\s*=\\s*(true|false)\\s*;~", $content, $matches)) {
        $defaults['app_debug'] = $matches[1] === 'true' ? '1' : '0';
    }

    return $defaults;
}

function installer_split_sql(string $sql): array
{
    $statements = [];
    $buffer = '';
    $length = strlen($sql);
    $inString = false;
    $stringChar = '';
    $escaped = false;

    for ($i = 0; $i < $length; $i++) {
        $char = $sql[$i];
        $next = $sql[$i + 1] ?? '';

        if (!$inString && $char === '-' && $next === '-') {
            while ($i < $length && $sql[$i] !== "\n") {
                $i++;
            }
            continue;
        }

        if (!$inString && $char === '#') {
            while ($i < $length && $sql[$i] !== "\n") {
                $i++;
            }
            continue;
        }

        if (!$inString && $char === '/' && $next === '*') {
            $i += 2;
            while ($i < $length && !(($sql[$i] ?? '') === '*' && ($sql[$i + 1] ?? '') === '/')) {
                $i++;
            }
            $i++;
            continue;
        }

        if (($char === "'" || $char === '"') && !$escaped) {
            if (!$inString) {
                $inString = true;
                $stringChar = $char;
            } elseif ($stringChar === $char) {
                $inString = false;
                $stringChar = '';
            }
        }

        if ($char === ';' && !$inString) {
            $statement = trim($buffer);
            if ($statement !== '') {
                $statements[] = $statement;
            }
            $buffer = '';
            continue;
        }

        $buffer .= $char;
        $escaped = ($char === '\\' && !$escaped);
        if ($char !== '\\') {
            $escaped = false;
        }
    }

    $statement = trim($buffer);
    if ($statement !== '') {
        $statements[] = $statement;
    }

    return $statements;
}

function installer_write_config(string $configPath, array $data): void
{
    $boolDebug = !empty($data['app_debug']) ? 'true' : 'false';
    $content = "<?php\n\n";
    $content .= "// Application\n";
    $content .= "const APP_NAME = '" . addslashes($data['app_name']) . "';\n";
    $content .= "const APP_ENV = '" . addslashes($data['app_env']) . "';\n";
    $content .= "const APP_DEBUG = {$boolDebug};\n\n";
    $content .= "// Public website\n";
    $content .= "const APP_URL = '" . addslashes(rtrim($data['site_url'], '/')) . "';\n";
    $content .= "const SEO_TITLE = 'FleetLume | Dispatch, Driver HOS, GPS & Accounting';\n";
    $content .= "const SEO_DESCRIPTION = 'FleetLume helps dispatch companies manage carriers, loads, driver logbooks and HOS, live GPS, reefer temperatures, fuel allowances, border crossings, documents, invoicing, and accounting.';\n\n";
    $content .= "// URL path\n";
    $content .= "// Use an empty value when your domain document root points directly to /public.\n";
    $content .= "const BASE_URL = '" . addslashes(rtrim($data['base_url'], '/')) . "';\n\n";
    $content .= "// Database\n";
    $content .= "const DB_HOST = '" . addslashes($data['db_host']) . "';\n";
    $content .= "const DB_PORT = '" . addslashes($data['db_port']) . "';\n";
    $content .= "const DB_NAME = '" . addslashes($data['db_name']) . "';\n";
    $content .= "const DB_USER = '" . addslashes($data['db_user']) . "';\n";
    $content .= "const DB_PASS = '" . addslashes($data['db_pass']) . "';\n";
    $content .= "const DB_CHARSET = '" . addslashes($data['db_charset']) . "';\n\n";
    $content .= "// Security\n";
    $content .= "const SESSION_NAME = '" . addslashes($data['session_name']) . "';\n";

    if (!is_dir(dirname($configPath))) {
        mkdir(dirname($configPath), 0755, true);
    }

    if (file_put_contents($configPath, $content, LOCK_EX) === false) {
        throw new RuntimeException('Unable to write config/config.php. Please make the config folder writable.');
    }
}

function installer_backtick(string $identifier): string
{
    return '`' . str_replace('`', '``', $identifier) . '`';
}

function installer_clean_host(string $host): string
{
    $host = trim($host);
    $host = preg_replace('/\s+/', '', $host) ?? $host;
    return rtrim($host, '/');
}

function installer_build_pdo(string $host, string $port, string $charset, string $user, string $password, ?string $dbName = null): PDO
{
    $dsn = "mysql:host={$host};charset={$charset}";

    if ($port !== '') {
        $dsn .= ";port={$port}";
    }

    if ($dbName !== null && $dbName !== '') {
        $dsn .= ";dbname={$dbName}";
    }

    return new PDO($dsn, $user, $password, [
        PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
        PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
        PDO::ATTR_EMULATE_PREPARES => false,
    ]);
}

function installer_friendly_db_error(Throwable $exception): string
{
    $message = $exception->getMessage();

    if (str_contains($message, 'Plugin https could not be loaded') || str_contains($message, 'plugin/https')) {
        return 'Database host is not valid. Do not use https://, http://, cPanel URLs, or /2083. Use only the database hostname, for example localhost, 127.0.0.1, or the database server name from your hosting panel. The common database port is 3306.';
    }

    if (str_contains($message, 'getaddrinfo') || str_contains($message, 'php_network_getaddresses')) {
        return 'Database host could not be resolved. Use only the database hostname from your hosting panel, not a website or cPanel URL.';
    }

    if (str_contains($message, 'Connection refused')) {
        return 'The database server refused the connection. Please check the database host and port. The common database port is 3306, not 2082, 2083, 2086, or 2087.';
    }

    if (str_contains($message, 'Access denied')) {
        return 'Database access was denied. Please confirm the database username, password, and that the user is assigned to this database with privileges.';
    }

    return $message;
}


function installer_column_exists(PDO $pdo, string $table, string $column): bool
{
    $stmt = $pdo->prepare('SELECT COUNT(*) FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = ? AND COLUMN_NAME = ?');
    $stmt->execute([$table, $column]);
    return (int) $stmt->fetchColumn() > 0;
}

function installer_table_exists(PDO $pdo, string $table): bool
{
    $stmt = $pdo->prepare('SELECT COUNT(*) FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = ?');
    $stmt->execute([$table]);
    return (int) $stmt->fetchColumn() > 0;
}

function installer_add_column_if_missing(PDO $pdo, string $table, string $column, string $definition): void
{
    if (!installer_table_exists($pdo, $table) || installer_column_exists($pdo, $table, $column)) {
        return;
    }

    $pdo->exec('ALTER TABLE ' . installer_backtick($table) . ' ADD COLUMN ' . installer_backtick($column) . ' ' . $definition);
}

function installer_try_exec(PDO $pdo, string $sql): void
{
    try {
        $pdo->exec($sql);
    } catch (Throwable $exception) {
        // Keep the installer compatible with existing hosting databases.
        // Some alterations can fail if a host has custom constraints; the core columns below are still attempted one by one.
    }
}

function installer_update_existing_database(PDO $pdo): void
{
    // Ensure legacy installations have the base columns used as migration anchors.
    installer_add_column_if_missing($pdo, 'drivers', 'medical_card_expiry', 'DATE NULL AFTER license_expiry');
    installer_add_column_if_missing($pdo, 'users', 'driver_id', 'INT UNSIGNED NULL AFTER status');
    installer_add_column_if_missing($pdo, 'trucks', 'inspection_expiry', 'DATE NULL AFTER registration_expiry');
    installer_add_column_if_missing($pdo, 'trailers', 'inspection_expiry', 'DATE NULL AFTER registration_expiry');
    installer_add_column_if_missing($pdo, 'loads', 'reference_number', 'VARCHAR(120) NULL AFTER load_number');
    installer_add_column_if_missing($pdo, 'loads', 'trailer_id', 'INT UNSIGNED NULL AFTER truck_id');
    installer_add_column_if_missing($pdo, 'loads', 'commodity', 'VARCHAR(160) NULL AFTER miles');
    installer_add_column_if_missing($pdo, 'loads', 'weight', 'DECIMAL(10,2) NULL AFTER commodity');
    installer_add_column_if_missing($pdo, 'load_stops', 'latitude', 'DECIMAL(10,7) NULL AFTER contact_name');
    installer_add_column_if_missing($pdo, 'load_stops', 'longitude', 'DECIMAL(10,7) NULL AFTER latitude');
    installer_add_column_if_missing($pdo, 'driver_hos_profiles', 'log_day_start_time', "TIME NOT NULL DEFAULT '00:00:00' AFTER home_terminal_timezone");

    // Carrier-network and cold-chain upgrade. These statements are idempotent and preserve existing records.
    installer_try_exec($pdo, "CREATE TABLE IF NOT EXISTS carriers (
        id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
        company_name VARCHAR(190) NOT NULL,
        dba_name VARCHAR(190) NULL,
        contact_name VARCHAR(140) NULL,
        email VARCHAR(190) NULL,
        phone VARCHAR(50) NULL,
        mc_number VARCHAR(80) NULL,
        dot_number VARCHAR(80) NULL,
        tax_id VARCHAR(100) NULL,
        address VARCHAR(255) NULL,
        dispatch_fee_type ENUM('percentage','fixed_per_load','monthly') NOT NULL DEFAULT 'percentage',
        dispatch_fee_value DECIMAL(12,2) NOT NULL DEFAULT 0,
        payment_terms VARCHAR(80) NOT NULL DEFAULT 'Weekly',
        authority_status ENUM('active','pending','inactive','revoked') NOT NULL DEFAULT 'active',
        safety_rating VARCHAR(80) NULL,
        insurance_expiry DATE NULL,
        cargo_insurance_expiry DATE NULL,
        onboarding_status ENUM('lead','documents_pending','review','approved','on_hold','inactive') NOT NULL DEFAULT 'documents_pending',
        status ENUM('active','on_hold','inactive') NOT NULL DEFAULT 'active',
        notes TEXT NULL,
        created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
        updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
        INDEX idx_carriers_status (status,onboarding_status)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci");

    installer_add_column_if_missing($pdo, 'users', 'carrier_id', 'INT UNSIGNED NULL AFTER driver_id');
    installer_add_column_if_missing($pdo, 'drivers', 'carrier_id', 'INT UNSIGNED NULL AFTER medical_card_expiry');
    installer_add_column_if_missing($pdo, 'drivers', 'employment_type', "ENUM('carrier_driver','owner_operator','company_driver','leased_driver') NOT NULL DEFAULT 'carrier_driver' AFTER carrier_id");
    installer_add_column_if_missing($pdo, 'trucks', 'carrier_id', 'INT UNSIGNED NULL AFTER inspection_expiry');
    installer_add_column_if_missing($pdo, 'trucks', 'ownership_type', "ENUM('carrier_owned','company_owned','leased','rental') NOT NULL DEFAULT 'carrier_owned' AFTER carrier_id");

    $trailerColumns = [
        'carrier_id' => 'INT UNSIGNED NULL AFTER inspection_expiry',
        'ownership_type' => "ENUM('carrier_owned','company_owned','leased','rental','customer_owned') NOT NULL DEFAULT 'carrier_owned' AFTER carrier_id",
        'length_ft' => 'DECIMAL(6,2) NULL AFTER ownership_type',
        'max_payload_lbs' => 'INT UNSIGNED NULL AFTER length_ft',
        'door_type' => 'VARCHAR(80) NULL AFTER max_payload_lbs',
        'food_grade' => 'TINYINT(1) NOT NULL DEFAULT 0 AFTER door_type',
        'air_ride' => 'TINYINT(1) NOT NULL DEFAULT 0 AFTER food_grade',
        'liftgate' => 'TINYINT(1) NOT NULL DEFAULT 0 AFTER air_ride',
        'hazmat_ready' => 'TINYINT(1) NOT NULL DEFAULT 0 AFTER liftgate',
        'reefer_capable' => 'TINYINT(1) NOT NULL DEFAULT 0 AFTER hazmat_ready',
        'reefer_make' => 'VARCHAR(100) NULL AFTER reefer_capable',
        'reefer_model' => 'VARCHAR(100) NULL AFTER reefer_make',
        'reefer_unit_number' => 'VARCHAR(100) NULL AFTER reefer_model',
        'reefer_year' => 'SMALLINT NULL AFTER reefer_unit_number',
        'temperature_unit' => "ENUM('F','C') NOT NULL DEFAULT 'F' AFTER reefer_year",
        'min_temperature' => 'DECIMAL(7,2) NULL AFTER temperature_unit',
        'max_temperature' => 'DECIMAL(7,2) NULL AFTER min_temperature',
        'current_setpoint' => 'DECIMAL(7,2) NULL AFTER max_temperature',
        'current_temperature' => 'DECIMAL(7,2) NULL AFTER current_setpoint',
        'reefer_mode' => "ENUM('continuous','cycle_sentry','off') NULL AFTER current_temperature",
        'reefer_hours' => 'DECIMAL(10,1) NULL AFTER reefer_mode',
        'reefer_fuel_level' => 'DECIMAL(5,2) NULL AFTER reefer_hours',
        'last_temperature_at' => 'DATETIME NULL AFTER reefer_fuel_level',
        'last_washout_date' => 'DATE NULL AFTER last_temperature_at',
        'reefer_service_due' => 'DATE NULL AFTER last_washout_date',
        'telematics_id' => 'VARCHAR(120) NULL AFTER reefer_service_due',
        'equipment_features' => 'TEXT NULL AFTER telematics_id',
    ];
    foreach ($trailerColumns as $column => $definition) installer_add_column_if_missing($pdo, 'trailers', $column, $definition);

    $loadColumns = [
        'carrier_id' => 'INT UNSIGNED NULL AFTER broker_id',
        'carrier_rate' => 'DECIMAL(12,2) NOT NULL DEFAULT 0 AFTER rate',
        'dispatch_fee_type' => "ENUM('percentage','fixed') NOT NULL DEFAULT 'percentage' AFTER carrier_rate",
        'dispatch_fee_value' => 'DECIMAL(12,2) NOT NULL DEFAULT 0 AFTER dispatch_fee_type',
        'dispatch_fee_amount' => 'DECIMAL(12,2) NOT NULL DEFAULT 0 AFTER dispatch_fee_value',
        'carrier_net_amount' => 'DECIMAL(12,2) NOT NULL DEFAULT 0 AFTER dispatch_fee_amount',
        'equipment_source' => "ENUM('external_carrier','company_equipment','rental','power_only') NOT NULL DEFAULT 'external_carrier' AFTER carrier_net_amount",
        'payment_responsibility' => "ENUM('broker_pays_carrier','dispatch_collects','carrier_collects') NOT NULL DEFAULT 'broker_pays_carrier' AFTER equipment_source",
        'carrier_reference' => 'VARCHAR(120) NULL AFTER payment_responsibility',
        'carrier_confirmation_status' => "ENUM('not_sent','sent','accepted','rejected') NOT NULL DEFAULT 'not_sent' AFTER carrier_reference",
        'temperature_controlled' => 'TINYINT(1) NOT NULL DEFAULT 0 AFTER weight',
        'temperature_unit' => "ENUM('F','C') NOT NULL DEFAULT 'F' AFTER temperature_controlled",
        'temperature_setpoint' => 'DECIMAL(7,2) NULL AFTER temperature_unit',
        'temperature_min' => 'DECIMAL(7,2) NULL AFTER temperature_setpoint',
        'temperature_max' => 'DECIMAL(7,2) NULL AFTER temperature_min',
        'reefer_mode' => "ENUM('continuous','cycle_sentry') NULL AFTER temperature_max",
        'precool_required' => 'TINYINT(1) NOT NULL DEFAULT 0 AFTER reefer_mode',
        'precool_temperature' => 'DECIMAL(7,2) NULL AFTER precool_required',
        'pulp_temperature_required' => 'TINYINT(1) NOT NULL DEFAULT 0 AFTER precool_temperature',
        'washout_required' => 'TINYINT(1) NOT NULL DEFAULT 0 AFTER pulp_temperature_required',
        'seal_required' => 'TINYINT(1) NOT NULL DEFAULT 0 AFTER washout_required',
        'temperature_instructions' => 'TEXT NULL AFTER seal_required',
    ];
    foreach ($loadColumns as $column => $definition) installer_add_column_if_missing($pdo, 'loads', $column, $definition);
    installer_try_exec($pdo, 'UPDATE loads SET carrier_rate=rate WHERE carrier_rate=0 AND rate>0');
    installer_try_exec($pdo, 'UPDATE loads SET carrier_net_amount=carrier_rate-dispatch_fee_amount WHERE carrier_net_amount=0 AND carrier_rate>0');

    installer_add_column_if_missing($pdo, 'load_stops', 'temperature_reading', 'DECIMAL(7,2) NULL AFTER longitude');
    installer_add_column_if_missing($pdo, 'load_stops', 'temperature_unit', "ENUM('F','C') NULL AFTER temperature_reading");
    installer_add_column_if_missing($pdo, 'load_stops', 'seal_number', 'VARCHAR(120) NULL AFTER temperature_unit');

    installer_try_exec($pdo, "CREATE TABLE IF NOT EXISTS temperature_logs (
        id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
        load_id INT UNSIGNED NOT NULL,
        trailer_id INT UNSIGNED NULL,
        driver_id INT UNSIGNED NULL,
        stop_id INT UNSIGNED NULL,
        document_id INT UNSIGNED NULL,
        temperature DECIMAL(7,2) NOT NULL,
        temperature_unit ENUM('F','C') NOT NULL DEFAULT 'F',
        setpoint DECIMAL(7,2) NULL,
        reefer_mode ENUM('continuous','cycle_sentry','off') NULL,
        reefer_fuel_level DECIMAL(5,2) NULL,
        pulp_temperature DECIMAL(7,2) NULL,
        latitude DECIMAL(10,7) NULL,
        longitude DECIMAL(10,7) NULL,
        location_address VARCHAR(255) NULL,
        notes TEXT NULL,
        recorded_at DATETIME NOT NULL,
        created_by INT UNSIGNED NULL,
        created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
        INDEX idx_temperature_load (load_id,recorded_at),
        INDEX idx_temperature_trailer (trailer_id,recorded_at)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci");
    installer_add_column_if_missing($pdo, 'drivers', 'medical_card_expiry', 'DATE NULL AFTER license_expiry');

    installer_add_column_if_missing($pdo, 'users', 'driver_id', 'INT UNSIGNED NULL AFTER status');

    installer_add_column_if_missing($pdo, 'trucks', 'inspection_expiry', 'DATE NULL AFTER registration_expiry');

    installer_add_column_if_missing($pdo, 'trailers', 'inspection_expiry', 'DATE NULL AFTER registration_expiry');
    installer_add_column_if_missing($pdo, 'trailers', 'truck_id', 'INT UNSIGNED NULL AFTER status');
    installer_add_column_if_missing($pdo, 'trailers', 'notes', 'TEXT NULL AFTER truck_id');

    installer_add_column_if_missing($pdo, 'loads', 'reference_number', 'VARCHAR(120) NULL AFTER load_number');
    installer_add_column_if_missing($pdo, 'loads', 'trailer_id', 'INT UNSIGNED NULL AFTER truck_id');
    installer_add_column_if_missing($pdo, 'loads', 'commodity', 'VARCHAR(160) NULL AFTER miles');
    installer_add_column_if_missing($pdo, 'loads', 'weight', 'DECIMAL(10,2) NULL AFTER commodity');
    installer_add_column_if_missing($pdo, 'loads', 'current_latitude', 'DECIMAL(10,7) NULL AFTER status');
    installer_add_column_if_missing($pdo, 'loads', 'current_longitude', 'DECIMAL(10,7) NULL AFTER current_latitude');
    installer_add_column_if_missing($pdo, 'loads', 'last_location_address', 'VARCHAR(255) NULL AFTER current_longitude');
    installer_add_column_if_missing($pdo, 'loads', 'last_location_at', 'DATETIME NULL AFTER last_location_address');

    if (installer_table_exists($pdo, 'loads')) {
        installer_try_exec($pdo, "ALTER TABLE loads MODIFY status ENUM('new', 'assigned', 'arrived_pickup', 'picked_up', 'in_transit', 'arrived_delivery', 'delivered', 'invoiced', 'paid', 'cancelled') NOT NULL DEFAULT 'new'");
    }

    installer_add_column_if_missing($pdo, 'load_stops', 'latitude', 'DECIMAL(10,7) NULL AFTER contact_name');
    installer_add_column_if_missing($pdo, 'load_stops', 'longitude', 'DECIMAL(10,7) NULL AFTER latitude');
    installer_add_column_if_missing($pdo, 'driver_hos_profiles', 'log_day_start_time', "TIME NOT NULL DEFAULT '00:00:00' AFTER home_terminal_timezone");
    installer_add_column_if_missing($pdo, 'load_stops', 'completed_at', 'DATETIME NULL AFTER longitude');
    installer_add_column_if_missing($pdo, 'load_stops', 'completed_by', 'INT UNSIGNED NULL AFTER completed_at');

    installer_add_column_if_missing($pdo, 'documents', 'stored_name', 'VARCHAR(255) NULL AFTER file_name');
    installer_add_column_if_missing($pdo, 'documents', 'mime_type', 'VARCHAR(120) NULL AFTER file_path');
    installer_add_column_if_missing($pdo, 'documents', 'file_size', 'INT UNSIGNED NULL AFTER mime_type');
    installer_add_column_if_missing($pdo, 'documents', 'expires_at', 'DATE NULL AFTER file_size');
    installer_add_column_if_missing($pdo, 'documents', 'notes', 'TEXT NULL AFTER expires_at');
    installer_add_column_if_missing($pdo, 'documents', 'latitude', 'DECIMAL(10,7) NULL AFTER notes');
    installer_add_column_if_missing($pdo, 'documents', 'longitude', 'DECIMAL(10,7) NULL AFTER latitude');
    installer_add_column_if_missing($pdo, 'documents', 'location_address', 'VARCHAR(255) NULL AFTER longitude');
    installer_add_column_if_missing($pdo, 'documents', 'captured_at', 'DATETIME NULL AFTER location_address');

    if (installer_table_exists($pdo, 'documents')) {
        installer_try_exec($pdo, "ALTER TABLE documents MODIFY related_type ENUM('driver', 'truck', 'trailer', 'broker', 'load', 'invoice', 'stop') NOT NULL");
        installer_try_exec($pdo, "UPDATE documents SET stored_name = file_name WHERE stored_name IS NULL OR stored_name = ''");
        installer_try_exec($pdo, 'ALTER TABLE documents MODIFY stored_name VARCHAR(255) NOT NULL');
    }

    installer_try_exec($pdo, "CREATE TABLE IF NOT EXISTS driver_locations (
        id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
        driver_id INT UNSIGNED NOT NULL,
        user_id INT UNSIGNED NULL,
        load_id INT UNSIGNED NULL,
        status VARCHAR(80) NULL,
        latitude DECIMAL(10,7) NOT NULL,
        longitude DECIMAL(10,7) NOT NULL,
        accuracy DECIMAL(10,2) NULL,
        location_address VARCHAR(255) NULL,
        notes TEXT NULL,
        created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
        INDEX idx_driver_locations_driver (driver_id),
        INDEX idx_driver_locations_load (load_id),
        CONSTRAINT fk_location_driver FOREIGN KEY (driver_id) REFERENCES drivers(id) ON DELETE CASCADE,
        CONSTRAINT fk_location_user FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE SET NULL,
        CONSTRAINT fk_location_load FOREIGN KEY (load_id) REFERENCES loads(id) ON DELETE SET NULL
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci");

    installer_try_exec($pdo, "CREATE TABLE IF NOT EXISTS load_events (
        id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
        load_id INT UNSIGNED NOT NULL,
        user_id INT UNSIGNED NULL,
        event_type VARCHAR(80) NOT NULL,
        description TEXT NULL,
        latitude DECIMAL(10,7) NULL,
        longitude DECIMAL(10,7) NULL,
        location_address VARCHAR(255) NULL,
        created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
        INDEX idx_load_events_load (load_id),
        CONSTRAINT fk_event_load FOREIGN KEY (load_id) REFERENCES loads(id) ON DELETE CASCADE,
        CONSTRAINT fk_event_user FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE SET NULL
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci");

    installer_add_column_if_missing($pdo, 'invoices', 'notes', 'TEXT NULL AFTER paid_at');

    installer_add_column_if_missing($pdo, 'driver_settlements', 'settlement_number', 'VARCHAR(100) NULL AFTER id');
    installer_add_column_if_missing($pdo, 'driver_settlements', 'notes', 'TEXT NULL AFTER paid_at');

    if (installer_table_exists($pdo, 'driver_settlements')) {
        installer_try_exec($pdo, "UPDATE driver_settlements SET settlement_number = CONCAT('SET-', LPAD(id, 5, '0')) WHERE settlement_number IS NULL OR settlement_number = ''");
        installer_try_exec($pdo, 'ALTER TABLE driver_settlements MODIFY settlement_number VARCHAR(100) NOT NULL');
        installer_try_exec($pdo, 'ALTER TABLE driver_settlements ADD UNIQUE KEY unique_settlement_number (settlement_number)');
    }

    installer_add_column_if_missing($pdo, 'maintenance_records', 'trailer_id', 'INT UNSIGNED NULL AFTER truck_id');
    installer_add_column_if_missing($pdo, 'maintenance_records', 'next_service_date', 'DATE NULL AFTER service_date');
    installer_add_column_if_missing($pdo, 'maintenance_records', 'status', "ENUM('scheduled', 'completed', 'pending') NOT NULL DEFAULT 'completed' AFTER cost");

    if (installer_table_exists($pdo, 'maintenance_records')) {
        installer_try_exec($pdo, 'ALTER TABLE maintenance_records MODIFY truck_id INT UNSIGNED NULL');
    }


    // Portals, accounting, tracking, documents, and border-crossing upgrades.
    installer_add_column_if_missing($pdo, 'users', 'department', 'VARCHAR(100) NULL AFTER role');
    installer_add_column_if_missing($pdo, 'users', 'phone', 'VARCHAR(50) NULL AFTER department');
    installer_add_column_if_missing($pdo, 'users', 'permissions', 'TEXT NULL AFTER phone');
    installer_add_column_if_missing($pdo, 'users', 'last_login_at', 'DATETIME NULL AFTER permissions');
    if (installer_table_exists($pdo, 'users')) {
        installer_try_exec($pdo, "ALTER TABLE users MODIFY role VARCHAR(40) NOT NULL DEFAULT 'admin'");
    }

    installer_add_column_if_missing($pdo, 'driver_locations', 'speed', 'DECIMAL(10,2) NULL AFTER accuracy');
    installer_add_column_if_missing($pdo, 'driver_locations', 'heading', 'DECIMAL(10,2) NULL AFTER speed');
    installer_add_column_if_missing($pdo, 'driver_locations', 'battery_level', 'DECIMAL(5,2) NULL AFTER heading');

    installer_add_column_if_missing($pdo, 'invoices', 'invoice_date', 'DATE NULL AFTER status');
    installer_add_column_if_missing($pdo, 'invoices', 'tax', 'DECIMAL(12,2) NOT NULL DEFAULT 0 AFTER invoice_date');
    installer_add_column_if_missing($pdo, 'invoices', 'discount', 'DECIMAL(12,2) NOT NULL DEFAULT 0 AFTER tax');
    installer_add_column_if_missing($pdo, 'invoices', 'balance_due', 'DECIMAL(12,2) NOT NULL DEFAULT 0 AFTER discount');
    installer_add_column_if_missing($pdo, 'invoices', 'sent_at', 'DATETIME NULL AFTER balance_due');
    installer_add_column_if_missing($pdo, 'invoices', 'viewed_at', 'DATETIME NULL AFTER sent_at');
    installer_add_column_if_missing($pdo, 'invoices', 'payment_terms', 'VARCHAR(100) NULL AFTER viewed_at');
    installer_add_column_if_missing($pdo, 'invoices', 'billing_notes', 'TEXT NULL AFTER payment_terms');
    if (installer_table_exists($pdo, 'invoices')) {
        installer_try_exec($pdo, "ALTER TABLE invoices MODIFY status ENUM('draft','approved','sent','viewed','partially_paid','paid','overdue','cancelled','written_off','void') NOT NULL DEFAULT 'draft'");
        installer_try_exec($pdo, "UPDATE invoices SET invoice_date=DATE(created_at) WHERE invoice_date IS NULL");
        installer_try_exec($pdo, "UPDATE invoices SET balance_due=GREATEST(0,total-COALESCE((SELECT SUM(amount) FROM payments WHERE payments.invoice_id=invoices.id),0))");
    }

    if (installer_table_exists($pdo, 'documents')) {
        installer_try_exec($pdo, "ALTER TABLE documents MODIFY related_type VARCHAR(40) NOT NULL");
    }
}
$defaults = installer_read_config_defaults($configPath);
$values = array_merge($defaults, $_POST ?: []);
$errors = [];
$success = false;
$loginUrl = rtrim((string) ($values['site_url'] ?? installer_site_url()), '/') . rtrim((string) ($values['base_url'] ?? installer_base_url()), '/') . '/login';

if (is_file($lockPath) && ($_GET['unlock'] ?? '') !== '1') {
    $locked = true;
} else {
    $locked = false;
}

if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    $locked = false;

    if (version_compare(PHP_VERSION, '8.1.0', '<')) {
        $errors[] = 'The server runtime must be version 8.1 or newer.';
    }
    if (!class_exists('PDO') || !in_array('mysql', PDO::getAvailableDrivers(), true)) {
        $errors[] = 'The required database connector is not enabled on this server.';
    }
    if (!is_dir($rootPath . '/storage') || !is_writable($rootPath . '/storage')) {
        $errors[] = 'The storage folder must be writable during installation.';
    }
    if (!is_writable(dirname($configPath)) && !is_writable($configPath)) {
        $errors[] = 'The config folder must be writable during installation.';
    }
    $values['seed_sample_data'] = isset($_POST['seed_sample_data']) ? '1' : '0';
    $values['lock_installer'] = isset($_POST['lock_installer']) ? '1' : '0';
    $values['app_debug'] = isset($_POST['app_debug']) ? '1' : '0';

    $required = [
        'app_name' => 'Application name',
        'site_url' => 'Site URL',
        'db_host' => 'Database host',
        'db_name' => 'Database name',
        'db_user' => 'Database username',
        'admin_name' => 'Admin name',
        'admin_email' => 'Admin email',
        'admin_password' => 'Admin password',
    ];

    foreach ($required as $key => $label) {
        if (trim((string) ($values[$key] ?? '')) === '') {
            $errors[] = "{$label} is required.";
        }
    }

    $values['site_url'] = rtrim(trim((string) ($values['site_url'] ?? '')), '/');
    if (!filter_var($values['site_url'], FILTER_VALIDATE_URL) || !in_array(parse_url($values['site_url'], PHP_URL_SCHEME), ['http', 'https'], true)) {
        $errors[] = 'Site URL must be a valid full URL, for example http://localhost or https://fleetlume.space.';
    }

    $values['base_url'] = rtrim(trim((string) ($values['base_url'] ?? '')), '/');
    if ($values['base_url'] !== '' && !str_starts_with($values['base_url'], '/')) {
        $errors[] = 'Base URL must be blank or start with a forward slash.';
    }

    $values['db_host'] = installer_clean_host((string) ($values['db_host'] ?? ''));
    $values['db_port'] = trim((string) ($values['db_port'] ?? '3306'));
    $values['db_charset'] = trim((string) ($values['db_charset'] ?? 'utf8mb4')) ?: 'utf8mb4';

    if (!preg_match('/^[A-Za-z0-9_]+$/', (string) ($values['db_name'] ?? ''))) {
        $errors[] = 'Database name can only contain letters, numbers, and underscores.';
    }

    if (str_contains((string) $values['db_host'], '://') || str_contains((string) $values['db_host'], '/')) {
        $errors[] = 'Database host must be a hostname only. Do not enter https://, http://, cPanel URLs, or paths. Use localhost, 127.0.0.1, or the database server name from your hosting panel.';
    }

    if ((string) $values['db_port'] !== '' && !ctype_digit((string) $values['db_port'])) {
        $errors[] = 'Database port must be numeric. The common database port is 3306.';
    }

    if (in_array((string) $values['db_port'], ['2082', '2083', '2086', '2087'], true)) {
        $errors[] = 'Port ' . $values['db_port'] . ' is a hosting/cPanel port, not a database port. Use the database port, usually 3306.';
    }

    if (!filter_var((string) ($values['admin_email'] ?? ''), FILTER_VALIDATE_EMAIL)) {
        $errors[] = 'Admin email must be a valid email address.';
    }

    if (strlen((string) ($values['admin_password'] ?? '')) < 8) {
        $errors[] = 'Admin password must be at least 8 characters.';
    }

    if (($values['admin_password'] ?? '') !== ($_POST['admin_password_confirm'] ?? '')) {
        $errors[] = 'Admin password confirmation does not match.';
    }

    if (!is_file($schemaPath)) {
        $errors[] = 'database/schema.sql was not found.';
    }

    if (!$errors) {
        try {
            $host = installer_clean_host((string) $values['db_host']);
            $port = trim((string) ($values['db_port'] ?? '3306'));
            $charset = trim((string) ($values['db_charset'] ?? 'utf8mb4')) ?: 'utf8mb4';
            $dbName = trim((string) $values['db_name']);

            try {
                $pdo = installer_build_pdo($host, $port, $charset, (string) $values['db_user'], (string) ($values['db_pass'] ?? ''));

                try {
                    $pdo->exec('CREATE DATABASE IF NOT EXISTS ' . installer_backtick($dbName) . ' CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci');
                    $pdo->exec('USE ' . installer_backtick($dbName));
                } catch (Throwable $createException) {
                    // Many shared hosts do not allow automatic database creation.
                    // If the database was already created in cPanel, continue by connecting directly to it.
                    $pdo = installer_build_pdo($host, $port, $charset, (string) $values['db_user'], (string) ($values['db_pass'] ?? ''), $dbName);
                }
            } catch (Throwable $connectionException) {
                try {
                    $pdo = installer_build_pdo($host, $port, $charset, (string) $values['db_user'], (string) ($values['db_pass'] ?? ''), $dbName);
                } catch (Throwable $directConnectionException) {
                    throw new RuntimeException(installer_friendly_db_error($directConnectionException));
                }
            }

            $values['db_host'] = $host;
            $values['db_port'] = $port;
            $values['db_charset'] = $charset;

            $sql = file_get_contents($schemaPath);
            if ($sql === false) {
                throw new RuntimeException('Unable to read database/schema.sql.');
            }

            $schemaStatements = [];
            $essentialStatements = [];
            $seedStatements = [];

            foreach (installer_split_sql($sql) as $statement) {
                $normalized = strtolower(ltrim($statement));
                if (str_starts_with($normalized, 'insert into users')) {
                    continue;
                }

                if (str_starts_with($normalized, 'insert into expense_categories') || str_starts_with($normalized, 'insert into chart_accounts') || str_starts_with($normalized, 'insert into system_settings')) {
                    $essentialStatements[] = $statement;
                    continue;
                }

                if (str_starts_with($normalized, 'insert into')) {
                    $seedStatements[] = $statement;
                    continue;
                }

                $schemaStatements[] = $statement;
            }

            foreach ($schemaStatements as $statement) {
                $pdo->exec($statement);
            }

            installer_update_existing_database($pdo);

            foreach ($essentialStatements as $statement) {
                $pdo->exec($statement);
            }

            $adminPasswordHash = password_hash((string) $values['admin_password'], PASSWORD_DEFAULT);
            $admin = $pdo->prepare('INSERT INTO users (id, name, email, password, role, status) VALUES (1, ?, ?, ?, "admin", "active") ON DUPLICATE KEY UPDATE name = VALUES(name), email = VALUES(email), password = VALUES(password), role = "admin", status = "active"');
            $admin->execute([
                trim((string) $values['admin_name']),
                trim((string) $values['admin_email']),
                $adminPasswordHash,
            ]);

            if (!empty($values['seed_sample_data'])) {
                foreach ($seedStatements as $statement) {
                    $pdo->exec($statement);
                }
            }

            installer_write_config($configPath, $values);

            if (!is_dir(dirname($lockPath))) {
                mkdir(dirname($lockPath), 0755, true);
            }

            if (!empty($values['lock_installer'])) {
                file_put_contents($lockPath, 'Installed on ' . date('Y-m-d H:i:s'));
            } elseif (is_file($lockPath)) {
                unlink($lockPath);
            }

            $success = true;
            $loginUrl = rtrim((string) $values['site_url'], '/') . rtrim((string) $values['base_url'], '/') . '/login';
        } catch (Throwable $exception) {
            $errors[] = installer_friendly_db_error($exception);
        }
    }
}

?><!doctype html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <meta name="robots" content="noindex,nofollow,noarchive">
    <meta name="theme-color" content="#071f5b">
    <link rel="icon" href="public/assets/images/favicon.ico" sizes="any">
    <title>Install FleetLume</title>
    <style>
        :root {
            --bg: #f5f7fb;
            --panel: #ffffff;
            --text: #111827;
            --muted: #6b7280;
            --border: #e5e7eb;
            --primary: #2563eb;
            --primary-dark: #1d4ed8;
            --danger: #dc2626;
            --success: #059669;
            --shadow: 0 20px 60px rgba(15, 23, 42, 0.10);
        }
        * { box-sizing: border-box; }
        body {
            margin: 0;
            font-family: Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
            background:
                radial-gradient(circle at top left, rgba(37, 99, 235, 0.14), transparent 32rem),
                radial-gradient(circle at bottom right, rgba(14, 165, 233, 0.12), transparent 28rem),
                var(--bg);
            color: var(--text);
        }
        a { color: var(--primary); text-decoration: none; }
        .wrap { width: min(1080px, calc(100% - 32px)); margin: 36px auto; }
        .hero { display: grid; grid-template-columns: 1fr auto; gap: 24px; align-items: center; margin-bottom: 22px; }
        .brand { display: flex; align-items: center; gap: 14px; }
        .brand-logo { width: 190px; height: auto; display: block; object-fit: contain; }
        h1 { margin: 0; letter-spacing: -0.04em; font-size: clamp(30px, 4vw, 48px); }
        .hero p { margin: 6px 0 0; color: var(--muted); }
        .card { background: rgba(255,255,255,.88); border: 1px solid var(--border); border-radius: 24px; box-shadow: var(--shadow); overflow: hidden; backdrop-filter: blur(12px); }
        .card-head { padding: 24px 28px; border-bottom: 1px solid var(--border); display:flex; align-items:center; justify-content:space-between; gap:16px; }
        .card-head h2 { margin: 0; letter-spacing: -0.03em; }
        .content { padding: 28px; }
        .grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 18px; }
        .section { margin-top: 26px; padding-top: 24px; border-top: 1px solid var(--border); }
        .section:first-child { margin-top: 0; padding-top: 0; border-top: 0; }
        .section h3 { margin: 0 0 14px; letter-spacing: -0.02em; }
        label { display: block; font-weight: 700; font-size: 13px; margin-bottom: 7px; }
        input, select { width: 100%; border: 1px solid var(--border); border-radius: 14px; padding: 13px 14px; background: #fff; color: var(--text); outline: none; }
        input:focus, select:focus { border-color: var(--primary); box-shadow: 0 0 0 4px rgba(37, 99, 235, 0.10); }
        .help { margin-top: 7px; color: var(--muted); font-size: 13px; line-height: 1.45; }
        .check { display: flex; gap: 10px; align-items: flex-start; padding: 14px; border: 1px solid var(--border); border-radius: 16px; background: #fff; }
        .check input { width: auto; margin-top: 3px; }
        .check label { margin: 0; }
        .actions { display:flex; align-items:center; justify-content:space-between; gap:16px; margin-top: 28px; }
        .btn { appearance:none; border:0; border-radius: 15px; padding: 13px 18px; font-weight: 800; cursor:pointer; display:inline-flex; align-items:center; justify-content:center; background: var(--primary); color:#fff; box-shadow: 0 12px 28px rgba(37, 99, 235, .26); }
        .btn:hover { background: var(--primary-dark); }
        .btn.secondary { background:#fff; color:var(--text); border:1px solid var(--border); box-shadow:none; }
        .alert { padding: 15px 16px; border-radius: 16px; margin-bottom: 18px; line-height: 1.55; }
        .alert-danger { background: #fef2f2; color: #991b1b; border: 1px solid #fecaca; }
        .alert-success { background: #f0fdf4; color: #166534; border: 1px solid #bbf7d0; }
        .alert-info { background: #eff6ff; color: #1e40af; border: 1px solid #bfdbfe; }
        .muted { color: var(--muted); }
        code { background: #eef2ff; padding: 3px 7px; border-radius: 8px; }
        ul { margin: 8px 0 0; padding-left: 20px; }
        @media (max-width: 760px) {
            .hero, .grid { grid-template-columns: 1fr; }
            .card-head, .actions { flex-direction: column; align-items: stretch; }
            .content, .card-head { padding: 20px; }
        }
    </style>
</head>
<body>
<div class="wrap">
    <div class="hero">
        <div class="brand">
            <img class="brand-logo" src="public/assets/images/fleetlume-logo-horizontal.png" alt="FleetLume">
            <div>
                <h1>FleetLume Installer</h1>
                <p>Create the database, import tables, seed admin user, and generate your config file.</p>
            </div>
        </div>
        <a class="btn secondary" href="<?= installer_e(installer_public_url((string) ($values['site_url'] ?? installer_site_url()), (string) ($values['base_url'] ?? installer_base_url()))) ?>">Open App</a>
    </div>

    <div class="card">
        <div class="card-head">
            <div>
                <h2>System Setup</h2>
                <p class="muted" style="margin:6px 0 0;">Use your hosting or local database details below.</p>
            </div>
            <span class="muted">Setup Wizard</span>
        </div>

        <div class="content">
            <?php if ($locked): ?>
                <div class="alert alert-info">
                    The installer is locked because this system already appears to be installed. To run it again, delete <code>storage/installed.lock</code> or open this page with <code>?unlock=1</code>.
                </div>
                <a class="btn" href="<?= installer_e(installer_public_url((string) $values['site_url'], (string) $values['base_url'], '/login')) ?>">Go to Login</a>
            <?php elseif ($success): ?>
                <div class="alert alert-success">
                    Installation completed successfully. Your database was created/updated and <code>config/config.php</code> was generated.
                </div>
                <div class="grid">
                    <div>
                        <label>Admin Email</label>
                        <input value="<?= installer_e((string) $values['admin_email']) ?>" readonly>
                    </div>
                    <div>
                        <label>Login URL</label>
                        <input value="<?= installer_e($loginUrl) ?>" readonly>
                    </div>
                </div>
                <div class="actions">
                    <p class="muted" style="margin:0;">For production, keep the installer locked or remove <code>install.php</code> after setup.</p>
                    <a class="btn" href="<?= installer_e($loginUrl) ?>">Go to Login</a>
                </div>
            <?php else: ?>
                <?php if ($errors): ?>
                    <div class="alert alert-danger">
                        <strong>Please fix the following:</strong>
                        <ul>
                            <?php foreach ($errors as $error): ?>
                                <li><?= installer_e($error) ?></li>
                            <?php endforeach; ?>
                        </ul>
                    </div>
                <?php endif; ?>

                <form method="post" autocomplete="off">
                    <div class="section">
                        <h3>Application</h3>
                        <div class="grid">
                            <div>
                                <label for="app_name">Application Name</label>
                                <input id="app_name" name="app_name" value="<?= installer_e((string) $values['app_name']) ?>" readonly required>
                            </div>
                            <div>
                                <label for="site_url">Site URL</label>
                                <input id="site_url" name="site_url" type="url" value="<?= installer_e((string) $values['site_url']) ?>" placeholder="http://localhost or https://fleetlume.space" required>
                                <div class="help">Automatically detected from the current browser address. Use http://localhost locally and https://fleetlume.space on live hosting.</div>
                            </div>
                            <div>
                                <label for="base_url">Base URL</label>
                                <input id="base_url" name="base_url" value="<?= installer_e((string) $values['base_url']) ?>">
                                <div class="help">Example: <code>/fleetlume/public</code>. Use blank only when the domain points directly to the public folder.</div>
                            </div>
                            <div>
                                <label for="app_env">Environment</label>
                                <select id="app_env" name="app_env">
                                    <option value="local" <?= ($values['app_env'] ?? '') === 'local' ? 'selected' : '' ?>>Local</option>
                                    <option value="production" <?= ($values['app_env'] ?? '') === 'production' ? 'selected' : '' ?>>Production</option>
                                </select>
                            </div>
                            <div class="check">
                                <input type="checkbox" id="app_debug" name="app_debug" value="1" <?= !empty($values['app_debug']) ? 'checked' : '' ?>>
                                <div>
                                    <label for="app_debug">Enable debug mode</label>
                                    <div class="help">Keep this enabled locally. Disable it on live hosting.</div>
                                </div>
                            </div>
                        </div>
                    </div>

                    <div class="section">
                        <h3>Database</h3>
                        <div class="grid">
                            <div>
                                <label for="db_host">Host</label>
                                <input id="db_host" name="db_host" value="<?= installer_e((string) $values['db_host']) ?>" required>
                                <div class="help">Use only the database hostname. Do not include <code>https://</code>, <code>http://</code>, <code>/cpanel</code>, or <code>:2083</code>. Common values: <code>localhost</code>, <code>127.0.0.1</code>, or the database host from your hosting panel.</div>
                            </div>
                            <div>
                                <label for="db_port">Port</label>
                                <input id="db_port" name="db_port" value="<?= installer_e((string) ($values['db_port'] ?? '3306')) ?>">
                                <div class="help">Usually <code>3306</code>. Do not use hosting/cPanel ports like <code>2083</code>.</div>
                            </div>
                            <div>
                                <label for="db_name">Database Name</label>
                                <input id="db_name" name="db_name" value="<?= installer_e((string) $values['db_name']) ?>" required>
                            </div>
                            <div>
                                <label for="db_charset">Charset</label>
                                <input id="db_charset" name="db_charset" value="<?= installer_e((string) $values['db_charset']) ?>" required>
                            </div>
                            <div>
                                <label for="db_user">Username</label>
                                <input id="db_user" name="db_user" value="<?= installer_e((string) $values['db_user']) ?>" required>
                            </div>
                            <div>
                                <label for="db_pass">Password</label>
                                <input id="db_pass" name="db_pass" type="password" value="<?= installer_e((string) ($values['db_pass'] ?? '')) ?>">
                            </div>
                        </div>
                    </div>

                    <div class="section">
                        <h3>Admin User</h3>
                        <div class="grid">
                            <div>
                                <label for="admin_name">Admin Name</label>
                                <input id="admin_name" name="admin_name" value="<?= installer_e((string) $values['admin_name']) ?>" required>
                            </div>
                            <div>
                                <label for="admin_email">Admin Email</label>
                                <input id="admin_email" name="admin_email" type="email" value="<?= installer_e((string) $values['admin_email']) ?>" required>
                            </div>
                            <div>
                                <label for="admin_password">Admin Password</label>
                                <input id="admin_password" name="admin_password" type="password" value="<?= installer_e((string) $values['admin_password']) ?>" required>
                            </div>
                            <div>
                                <label for="admin_password_confirm">Confirm Password</label>
                                <input id="admin_password_confirm" name="admin_password_confirm" type="password" value="<?= installer_e((string) ($values['admin_password_confirm'] ?? $values['admin_password'])) ?>" required>
                            </div>
                        </div>
                    </div>

                    <div class="section">
                        <h3>Options</h3>
                        <div class="grid">
                            <div class="check">
                                <input type="checkbox" id="seed_sample_data" name="seed_sample_data" value="1" <?= !empty($values['seed_sample_data']) ? 'checked' : '' ?>>
                                <div>
                                    <label for="seed_sample_data">Add sample drivers, trucks, brokers, and loads</label>
                                    <div class="help">Good for testing. Uncheck this for a clean production database.</div>
                                </div>
                            </div>
                            <div class="check">
                                <input type="checkbox" id="lock_installer" name="lock_installer" value="1" <?= !empty($values['lock_installer']) ? 'checked' : '' ?>>
                                <div>
                                    <label for="lock_installer">Lock installer after successful setup</label>
                                    <div class="help">Recommended for security. Delete <code>storage/installed.lock</code> to unlock later.</div>
                                </div>
                            </div>
                        </div>
                    </div>

                    <div class="actions">
                        <p class="muted" style="margin:0;">The installer will create the database if your database user has permission.</p>
                        <button class="btn" type="submit">Install System</button>
                    </div>
                </form>
            <?php endif; ?>
        </div>
    </div>
</div>
</body>
</html>
