<?php
declare(strict_types=1);

/**
 * Shared hosting installer for Mirza Bot + Panel.
 * Upload project files, then open this file in browser once.
 */

$configPath = __DIR__ . '/config.php';
$tablePath = __DIR__ . '/table.php';

$messages = [];
$errors = [];
$installed = false;
$canSelfDelete = false;
require_once __DIR__ . '/telegram_proxy.php';

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

function normalize_domain(string $domain): string
{
    $domain = trim($domain);
    $domain = preg_replace('#^https?://#i', '', $domain);
    $domain = rtrim($domain, "/ \t\n\r\0\x0B");
    return $domain;
}

function validate_domain(string $domain): bool
{
    return (bool) preg_match('/^[a-zA-Z0-9.-]+(?:\/[a-zA-Z0-9._~\-\/]*)?$/', $domain);
}

function validate_bot_token(string $token): bool
{
    return (bool) preg_match('/^[0-9]{8,10}:[a-zA-Z0-9_-]{35}$/', $token);
}

function validate_chat_id(string $chatId): bool
{
    return (bool) preg_match('/^-?[0-9]+$/', $chatId);
}

function config_is_already_set(string $configContent): bool
{
    return !preg_match('/\{(database_url|database_name|username_db|password_db|API_KEY|admin_number|domain_name|username_bot)\}/', $configContent);
}

function can_connect_database(string $host, string $dbName, string $user, string $pass): array
{
    try {
        $dsn = "mysql:host={$host};dbname={$dbName};charset=utf8mb4";
        $pdo = new PDO($dsn, $user, $pass, [
            PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
            PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
            PDO::ATTR_EMULATE_PREPARES => false,
        ]);
        $pdo->query('SELECT 1');
        return [true, ''];
    } catch (Throwable $e) {
        return [false, $e->getMessage()];
    }
}

function telegram_api_request_with_proxy(string $url, array $postFields, string $proxyInput = ''): ?string
{
    $ch = curl_init($url);
    if ($ch === false) {
        return null;
    }

    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_TIMEOUT, 25);
    curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 15);
    curl_setopt($ch, CURLOPT_POST, true);
    curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($postFields));

    $proxyCfg = parse_telegram_proxy($proxyInput);
    if (is_array($proxyCfg)) {
        $proxyAddress = $proxyCfg['host'] . ':' . $proxyCfg['port'];
        $proxyType = defined('CURLPROXY_SOCKS5_HOSTNAME') ? CURLPROXY_SOCKS5_HOSTNAME : CURLPROXY_SOCKS5;
        curl_setopt($ch, CURLOPT_PROXYTYPE, $proxyType);
        curl_setopt($ch, CURLOPT_PROXY, $proxyAddress);
        if (($proxyCfg['user'] ?? '') !== '') {
            curl_setopt($ch, CURLOPT_PROXYUSERPWD, $proxyCfg['user'] . ':' . ($proxyCfg['pass'] ?? ''));
        }
    }

    $response = curl_exec($ch);
    if ($response === false) {
        curl_close($ch);
        return null;
    }
    curl_close($ch);
    return $response;
}

function set_telegram_webhook_with_retry(string $apiEndpoint, string $webhookUrl, string $proxyInput = ''): array
{
    $maxAttempts = 4;
    $lastRaw = null;

    for ($attempt = 1; $attempt <= $maxAttempts; $attempt++) {
        $lastRaw = telegram_api_request_with_proxy($apiEndpoint, ['url' => $webhookUrl], $proxyInput);
        if ($lastRaw === null) {
            continue;
        }

        $decoded = json_decode($lastRaw, true);
        if (is_array($decoded) && !empty($decoded['ok'])) {
            return [true, $lastRaw];
        }

        $isRateLimit = is_array($decoded)
            && (($decoded['error_code'] ?? null) === 429)
            && isset($decoded['parameters']['retry_after']);
        if ($isRateLimit && $attempt < $maxAttempts) {
            $retryAfter = max(1, (int) $decoded['parameters']['retry_after']);
            sleep($retryAfter);
            continue;
        }

        break;
    }

    return [false, $lastRaw];
}

$form = [
    'db_host' => 'localhost',
    'db_name' => '',
    'db_user' => '',
    'db_pass' => '',
    'bot_token' => '',
    'admin_chat_id' => '',
    'domain' => '',
    'bot_username' => '',
    'telegram_proxy' => '',
];

if (!is_file($configPath)) {
    $errors[] = 'config.php not found in project root.';
}
if (!is_file($tablePath)) {
    $errors[] = 'table.php not found in project root.';
}
if (is_file($configPath) && !is_writable($configPath)) {
    $errors[] = 'config.php is not writable. Set file permission to writable and reload.';
}

if ($_SERVER['REQUEST_METHOD'] === 'POST' && empty($errors)) {
    foreach ($form as $key => $value) {
        $form[$key] = trim((string) ($_POST[$key] ?? ''));
    }

    $form['domain'] = normalize_domain($form['domain']);

    if ($form['db_host'] === '') {
        $errors[] = 'Database host is required.';
    }
    if ($form['db_name'] === '') {
        $errors[] = 'Database name is required.';
    }
    if ($form['db_user'] === '') {
        $errors[] = 'Database username is required.';
    }
    if (!validate_bot_token($form['bot_token'])) {
        $errors[] = 'Bot token format is invalid.';
    }
    if (!validate_chat_id($form['admin_chat_id'])) {
        $errors[] = 'Admin chat ID format is invalid.';
    }
    if (!validate_domain($form['domain'])) {
        $errors[] = 'Domain format is invalid. Examples: example.com, sub.example.com, example.com/bot';
    }
    if ($form['bot_username'] === '') {
        $errors[] = 'Bot username is required.';
    }
    if ($form['telegram_proxy'] !== '' && parse_telegram_proxy($form['telegram_proxy']) === null) {
        $errors[] = 'Telegram proxy format is invalid.';
    }

    $configContent = (string) @file_get_contents($configPath);
    if ($configContent === '') {
        $errors[] = 'Could not read config.php.';
    }

    if (empty($errors) && config_is_already_set($configContent)) {
        $messages[] = 'Looks like config.php is already configured. Installer will continue and run database/webhook setup again.';
    }

    if (empty($errors)) {
        [$dbOk, $dbErr] = can_connect_database($form['db_host'], $form['db_name'], $form['db_user'], $form['db_pass']);
        if (!$dbOk) {
            $errors[] = 'Database connection failed: ' . $dbErr;
        } else {
            $messages[] = 'Database connection verified successfully.';
        }
    }

    if (empty($errors)) {
        $replaceMap = [
            '{database_url}' => $form['db_host'],
            '{database_name}' => $form['db_name'],
            '{username_db}' => $form['db_user'],
            '{password_db}' => $form['db_pass'],
            '{API_KEY}' => $form['bot_token'],
            '{admin_number}' => $form['admin_chat_id'],
            '{domain_name}' => $form['domain'],
            '{username_bot}' => ltrim($form['bot_username'], '@'),
        ];

        $newConfig = strtr($configContent, $replaceMap);
        $proxyLiteral = var_export($form['telegram_proxy'] !== '' ? $form['telegram_proxy'] : null, true);
        if (preg_match('/^\$telegram_proxy\s*=.*;$/m', $newConfig)) {
            $newConfig = preg_replace('/^\$telegram_proxy\s*=.*;$/m', '$telegram_proxy = ' . $proxyLiteral . ';', $newConfig, 1);
        } else {
            $newConfig .= "\n" . '$telegram_proxy = ' . $proxyLiteral . ';' . "\n";
        }
        if (@file_put_contents($configPath, $newConfig, LOCK_EX) === false) {
            $errors[] = 'Failed to write config.php.';
        } else {
            $messages[] = 'config.php updated successfully.';
        }
    }

    if (empty($errors)) {
        try {
            ob_start();
            require $tablePath;
            ob_end_clean();
            $messages[] = 'Database tables initialized via table.php.';
        } catch (Throwable $e) {
            @ob_end_clean();
            $errors[] = 'Database setup failed (table.php): ' . $e->getMessage();
        }
    }

    if (empty($errors)) {
        $webhookUrl = 'https://' . $form['domain'] . '/index.php';
        $apiEndpoint = 'https://api.telegram.org/bot' . rawurlencode($form['bot_token']) . '/setWebhook';
        [$okWebhook, $response] = set_telegram_webhook_with_retry($apiEndpoint, $webhookUrl, $form['telegram_proxy']);
        if (!$okWebhook || $response === null) {
            $errors[] = 'Webhook setup failed. Check SSL/domain and set webhook manually.';
        } else {
            $decoded = json_decode($response, true);
            if (is_array($decoded) && !empty($decoded['ok'])) {
                $messages[] = 'Telegram webhook set successfully: ' . $webhookUrl;
                $installed = true;
                $canSelfDelete = is_writable(__FILE__);
            } else {
                $errors[] = 'Webhook API error: ' . $response;
            }
        }
    }
}
?>
<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>Mirza Shared Hosting Installer</title>
    <style>
        body { font-family: Arial, sans-serif; max-width: 880px; margin: 24px auto; padding: 0 16px; }
        h1 { margin-bottom: 8px; }
        .box { border: 1px solid #ddd; border-radius: 10px; padding: 16px; margin: 16px 0; }
        .err { background: #ffecec; border-color: #f3b1b1; }
        .ok { background: #edfbee; border-color: #a8dfad; }
        label { display: block; margin: 10px 0 6px; font-weight: 600; }
        input { width: 100%; padding: 10px; border: 1px solid #ccc; border-radius: 8px; }
        button { margin-top: 14px; padding: 11px 18px; border: 0; border-radius: 8px; background: #0c63e7; color: #fff; cursor: pointer; }
        small { color: #555; display: block; margin-top: 4px; }
        code { background: #f4f4f4; padding: 2px 6px; border-radius: 6px; }
    </style>
</head>
<body>
<h1>Mirza Shared Hosting Installer</h1>
<p>Use this page once to configure <code>config.php</code>, create tables, and set Telegram webhook.</p>

<?php if (!empty($errors)): ?>
    <div class="box err">
        <strong>Errors:</strong>
        <ul>
            <?php foreach ($errors as $error): ?>
                <li><?= h($error) ?></li>
            <?php endforeach; ?>
        </ul>
    </div>
<?php endif; ?>

<?php if (!empty($messages)): ?>
    <div class="box ok">
        <strong>Status:</strong>
        <ul>
            <?php foreach ($messages as $message): ?>
                <li><?= h($message) ?></li>
            <?php endforeach; ?>
        </ul>
    </div>
<?php endif; ?>

<?php if ($installed): ?>
    <div class="box ok">
        <p>Installation completed successfully.</p>
        <?php if ($canSelfDelete && isset($_GET['delete_installer']) && $_GET['delete_installer'] === '1'): ?>
            <?php
            if (@unlink(__FILE__)) {
                echo '<p><strong>Installer deleted successfully.</strong></p>';
            } else {
                echo '<p>Could not delete installer automatically. Please remove it manually.</p>';
            }
            ?>
        <?php else: ?>
            <p>For security, delete <code>shared-installer.php</code> now.</p>
            <?php if ($canSelfDelete): ?>
                <p><a href="?delete_installer=1" style="color:#0c63e7;font-weight:700">Delete installer automatically</a></p>
            <?php endif; ?>
        <?php endif; ?>
        <p>Then open your bot and send <code>/start</code>.</p>
    </div>
<?php endif; ?>

<form method="post" class="box">
    <label for="db_host">Database Host</label>
    <input id="db_host" name="db_host" value="<?= h($form['db_host']) ?>" required>

    <label for="db_name">Database Name</label>
    <input id="db_name" name="db_name" value="<?= h($form['db_name']) ?>" required>

    <label for="db_user">Database Username</label>
    <input id="db_user" name="db_user" value="<?= h($form['db_user']) ?>" required>

    <label for="db_pass">Database Password</label>
    <input id="db_pass" name="db_pass" type="password" value="<?= h($form['db_pass']) ?>">
    <small>Can be empty only if your DB user has no password.</small>

    <label for="bot_token">Telegram Bot Token</label>
    <input id="bot_token" name="bot_token" value="<?= h($form['bot_token']) ?>" required>

    <label for="admin_chat_id">Admin Chat ID</label>
    <input id="admin_chat_id" name="admin_chat_id" value="<?= h($form['admin_chat_id']) ?>" required>

    <label for="domain">Domain or host path (without protocol)</label>
    <input id="domain" name="domain" placeholder="example.com" value="<?= h($form['domain']) ?>" required>
    <small>Accepted: <code>example.com</code>, <code>sub.example.com</code>, <code>example.com/bot</code>, <code>sub.example.com/panel/bot</code></small>

    <label for="bot_username">Bot Username (without @)</label>
    <input id="bot_username" name="bot_username" value="<?= h($form['bot_username']) ?>" required>

    <label for="telegram_proxy">Telegram SOCKS Proxy (optional)</label>
    <input id="telegram_proxy" name="telegram_proxy" value="<?= h($form['telegram_proxy']) ?>" placeholder="https://t.me/socks?server=IP&port=PORT&user=USER&pass=PASS">
    <small>Use this when your host cannot access api.telegram.org directly.</small>

    <button type="submit">Install Now</button>
</form>
</body>
</html>
