<?php

declare(strict_types=1);

session_start();
set_time_limit(600);
ini_set('memory_limit', '512M');

const APP_FOLDER = 'telebot-app';
const PACKAGE_FOLDER = 'telebot-package';

$root = __DIR__;
$lockFile = $root . '/.telebot-installed';
$errors = [];
$messages = [];
$installed = is_file($lockFile);

if (empty($_SESSION['installer_token'])) {
    $_SESSION['installer_token'] = bin2hex(random_bytes(32));
}

$defaults = [
    'main_root' => $root,
    'admin_root' => dirname($root) . '/admin.kifech.com',
    'api_root' => dirname($root) . '/api.kifech.com',
    'db_host' => 'localhost',
    'db_port' => '3306',
    'db_name' => '',
    'db_user' => '',
    'db_password' => '',
    'admin_name' => 'Administrator',
    'admin_email' => 'admin@kifech.com',
    'admin_password' => '',
];

$data = array_merge($defaults, array_map(
    static fn ($value) => is_string($value) ? trim($value) : $value,
    $_POST
));

if ($_SERVER['REQUEST_METHOD'] === 'POST' && !$installed) {
    if (!hash_equals($_SESSION['installer_token'], (string) ($_POST['_token'] ?? ''))) {
        $errors[] = 'انتهت جلسة المثبت. أعد تحميل الصفحة وحاول مرة أخرى.';
    }

    foreach (['main_root', 'admin_root', 'api_root', 'db_host', 'db_port', 'db_name', 'db_user', 'admin_name', 'admin_email', 'admin_password'] as $field) {
        if (($data[$field] ?? '') === '') {
            $errors[] = "الحقل {$field} مطلوب.";
        }
    }

    if (!filter_var($data['admin_email'], FILTER_VALIDATE_EMAIL)) {
        $errors[] = 'بريد المدير غير صالح.';
    }

    if (strlen($data['admin_password']) < 10) {
        $errors[] = 'كلمة مرور المدير يجب أن تكون 10 أحرف على الأقل.';
    }

    if (!class_exists('ZipArchive')) {
        $errors[] = 'امتداد PHP ZipArchive غير متاح على الاستضافة.';
    }

    if (!extension_loaded('pdo_mysql')) {
        $errors[] = 'امتداد pdo_mysql غير متاح على الاستضافة.';
    }

    $mainRoot = normalizePath($data['main_root']);
    $adminRoot = normalizePath($data['admin_root']);
    $apiRoot = normalizePath($data['api_root']);
    $appRoot = dirname($mainRoot) . '/' . APP_FOLDER;
    $package = $root . '/' . PACKAGE_FOLDER . '.zip';

    if (!is_file($package)) {
        $errors[] = 'ملف telebot-package.zip غير موجود بجانب install.php.';
    }

    if (!$errors) {
        try {
            $dsn = sprintf('mysql:host=%s;port=%s;dbname=%s;charset=utf8mb4', $data['db_host'], $data['db_port'], $data['db_name']);
            new PDO($dsn, $data['db_user'], $data['db_password'], [PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION]);
            $messages[] = 'تم الاتصال بقاعدة البيانات بنجاح.';
        } catch (Throwable $exception) {
            $errors[] = 'تعذر الاتصال بقاعدة البيانات: ' . $exception->getMessage();
        }
    }

    if (!$errors) {
        try {
            ensureDirectory($mainRoot);
            ensureDirectory($adminRoot);
            ensureDirectory($apiRoot);
            ensureDirectory($appRoot);

            $zip = new ZipArchive();
            if ($zip->open($package) !== true) {
                throw new RuntimeException('تعذر فتح حزمة التطبيق الداخلية.');
            }
            if (!$zip->extractTo($appRoot)) {
                $zip->close();
                throw new RuntimeException('تعذر استخراج حزمة التطبيق.');
            }
            $zip->close();
            $messages[] = 'تم استخراج تطبيق Laravel.';

            $appKey = 'base64:' . base64_encode(random_bytes(32));
            $env = buildEnvironment($data, $appKey);
            if (file_put_contents($appRoot . '/.env', $env, LOCK_EX) === false) {
                throw new RuntimeException('تعذر كتابة ملف .env.');
            }
            @chmod($appRoot . '/.env', 0600);

            makeWritable($appRoot . '/storage');
            makeWritable($appRoot . '/bootstrap/cache');

            copyPublicDirectory($appRoot . '/public', $mainRoot, ['install.php']);
            copyPublicDirectory($appRoot . '/public', $adminRoot);
            copyPublicDirectory($appRoot . '/public', $apiRoot);

            writeFrontController($mainRoot . '/index.php', $appRoot);
            writeFrontController($adminRoot . '/index.php', $appRoot);
            writeFrontController($apiRoot . '/index.php', $appRoot);
            writeHtaccess($mainRoot);
            writeHtaccess($adminRoot);
            writeHtaccess($apiRoot);
            $messages[] = 'تم تجهيز الدومين الرئيسي والدومينات الفرعية.';

            bootstrapLaravel($appRoot, $data);
            $messages[] = 'تم تشغيل migrations وإنشاء حساب المدير وتحسين الكاش.';

            file_put_contents($lockFile, date(DATE_ATOM), LOCK_EX);
            @unlink($package);
            $installed = true;
        } catch (Throwable $exception) {
            $errors[] = 'فشل التثبيت: ' . $exception->getMessage();
        }
    }
}

function normalizePath(string $path): string
{
    return rtrim(str_replace('\\', '/', $path), '/');
}

function ensureDirectory(string $path): void
{
    if (!is_dir($path) && !mkdir($path, 0755, true) && !is_dir($path)) {
        throw new RuntimeException("تعذر إنشاء المجلد: {$path}");
    }
    if (!is_writable($path)) {
        throw new RuntimeException("المجلد غير قابل للكتابة: {$path}");
    }
}

function makeWritable(string $path): void
{
    ensureDirectory($path);
    @chmod($path, 0775);

    $iterator = new RecursiveIteratorIterator(
        new RecursiveDirectoryIterator($path, FilesystemIterator::SKIP_DOTS),
        RecursiveIteratorIterator::SELF_FIRST
    );
    foreach ($iterator as $item) {
        @chmod($item->getPathname(), $item->isDir() ? 0775 : 0664);
    }
}

function copyPublicDirectory(string $source, string $target, array $exclude = []): void
{
    ensureDirectory($target);
    $iterator = new RecursiveIteratorIterator(
        new RecursiveDirectoryIterator($source, FilesystemIterator::SKIP_DOTS),
        RecursiveIteratorIterator::SELF_FIRST
    );

    foreach ($iterator as $item) {
        $relative = substr($item->getPathname(), strlen($source) + 1);
        if (in_array(str_replace('\\', '/', $relative), $exclude, true)) {
            continue;
        }
        $destination = $target . '/' . $relative;
        if ($item->isDir()) {
            ensureDirectory($destination);
        } elseif (!copy($item->getPathname(), $destination)) {
            throw new RuntimeException("تعذر نسخ الملف العام: {$relative}");
        }
    }
}

function writeFrontController(string $path, string $appRoot): void
{
    $appRoot = addslashes($appRoot);
    $content = <<<PHP
<?php

use Illuminate\Foundation\Application;
use Illuminate\Http\Request;

define('LARAVEL_START', microtime(true));

require '{$appRoot}/vendor/autoload.php';

/** @var Application \$app */
\$app = require_once '{$appRoot}/bootstrap/app.php';
\$app->handleRequest(Request::capture());
PHP;

    if (file_put_contents($path, $content, LOCK_EX) === false) {
        throw new RuntimeException("تعذر كتابة index.php في {$path}");
    }
}

function writeHtaccess(string $target): void
{
    $content = <<<'HTACCESS'
<IfModule mod_rewrite.c>
    RewriteEngine On
    RewriteCond %{HTTPS} !=on
    RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteRule ^ index.php [L]
</IfModule>

<FilesMatch "^\.(env|git)|composer\.(json|lock)|artisan$">
    Require all denied
</FilesMatch>

Options -Indexes
HTACCESS;

    if (file_put_contents($target . '/.htaccess', $content, LOCK_EX) === false) {
        throw new RuntimeException("تعذر كتابة .htaccess في {$target}");
    }
}

function buildEnvironment(array $data, string $appKey): string
{
    $values = [
        'APP_NAME' => 'TeleBot Manager',
        'APP_ENV' => 'production',
        'APP_KEY' => $appKey,
        'APP_DEBUG' => 'false',
        'APP_URL' => 'https://admin.kifech.com',
        'ADMIN_URL' => 'https://admin.kifech.com',
        'API_URL' => 'https://api.kifech.com',
        'WEBHOOK_URL' => 'https://api.kifech.com',
        'APP_LOCALE' => 'en',
        'APP_FALLBACK_LOCALE' => 'en',
        'LOG_CHANNEL' => 'stack',
        'LOG_STACK' => 'single',
        'LOG_LEVEL' => 'warning',
        'DB_CONNECTION' => 'mysql',
        'DB_HOST' => $data['db_host'],
        'DB_PORT' => $data['db_port'],
        'DB_DATABASE' => $data['db_name'],
        'DB_USERNAME' => $data['db_user'],
        'DB_PASSWORD' => $data['db_password'],
        'SESSION_DRIVER' => 'database',
        'SESSION_LIFETIME' => '120',
        'SESSION_ENCRYPT' => 'true',
        'SESSION_DOMAIN' => '.kifech.com',
        'CACHE_STORE' => 'database',
        'QUEUE_CONNECTION' => 'database',
        'FILESYSTEM_DISK' => 'local',
        'DOWNLOAD_MEDIA' => 'false',
        'STORAGE_LIMIT_MB' => '2048',
        'MAIL_MAILER' => 'log',
    ];

    $lines = [];
    foreach ($values as $key => $value) {
        $escaped = str_replace(['\\', '"', "\r", "\n"], ['\\\\', '\\"', '', ''], (string) $value);
        $lines[] = $key . '="' . $escaped . '"';
    }

    return implode(PHP_EOL, $lines) . PHP_EOL;
}

function bootstrapLaravel(string $appRoot, array $data): void
{
    require_once $appRoot . '/vendor/autoload.php';
    $app = require $appRoot . '/bootstrap/app.php';
    $app->make(Illuminate\Contracts\Console\Kernel::class)->bootstrap();

    Illuminate\Support\Facades\Artisan::call('migrate', ['--force' => true]);

    App\Models\User::query()->updateOrCreate(
        ['email' => $data['admin_email']],
        [
            'name' => $data['admin_name'],
            'password' => $data['admin_password'],
            'role' => App\Models\User::ROLE_ADMIN,
            'is_active' => true,
            'email_verified_at' => now(),
        ]
    );

    Illuminate\Support\Facades\Artisan::call('optimize:clear');
    Illuminate\Support\Facades\Artisan::call('config:cache');
}

?><!doctype html>
<html lang="ar" dir="rtl">
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width,initial-scale=1">
    <title>تثبيت TeleBot Manager</title>
    <style>
        *{box-sizing:border-box}body{margin:0;background:#08111f;color:#e5edf7;font-family:Tahoma,Arial,sans-serif;min-height:100vh;padding:32px 16px}.wrap{max-width:920px;margin:auto}.hero{margin-bottom:24px}.hero h1{font-size:30px;margin:0 0 8px}.hero p{color:#9fb0c5;margin:0}.card{background:#101c2f;border:1px solid #21314a;border-radius:18px;padding:24px;box-shadow:0 20px 50px #0005}.grid{display:grid;grid-template-columns:1fr 1fr;gap:16px}.full{grid-column:1/-1}label{display:block;font-size:13px;color:#b8c5d6;margin-bottom:7px}input{width:100%;border:1px solid #334662;background:#0a1525;color:#fff;border-radius:10px;padding:12px;outline:none}input:focus{border-color:#5b8cff}.section{grid-column:1/-1;margin-top:8px;padding-top:18px;border-top:1px solid #24344d;font-weight:bold}.button{border:0;border-radius:11px;background:linear-gradient(135deg,#4f7cff,#7c5cff);color:#fff;padding:14px 22px;font-weight:bold;cursor:pointer;width:100%;font-size:16px}.alert{border-radius:12px;padding:14px 16px;margin-bottom:16px}.error{background:#3b1520;border:1px solid #7f2b42}.ok{background:#103625;border:1px solid #267a50}.note{background:#132b49;border:1px solid #285c91;color:#cce3ff}.small{font-size:12px;color:#91a3ba;margin-top:7px;direction:ltr;text-align:left}.success{text-align:center;padding:30px}.success a{color:#91b1ff}@media(max-width:700px){.grid{grid-template-columns:1fr}.full,.section{grid-column:1}.card{padding:18px}}
    </style>
</head>
<body><div class="wrap">
    <div class="hero"><h1>TeleBot Manager</h1><p>مثبت الاستضافة المشتركة الخاص بـ kifech.com</p></div>
    <?php if ($installed && !$errors): ?>
        <div class="card success">
            <h2>تم التثبيت بنجاح</h2>
            <?php foreach ($messages as $message): ?><div class="alert ok"><?= htmlspecialchars($message) ?></div><?php endforeach; ?>
            <p><a href="https://admin.kifech.com/login">فتح لوحة الإدارة</a></p>
            <p>احذف <code>install.php</code> من جذر الموقع بعد التأكد من التشغيل. اترك ملف القفل المخفي كما هو.</p>
            <p>أضف Cron Job:</p><div class="small">/usr/local/bin/php <?= htmlspecialchars(dirname(normalizePath($data['main_root'])) . '/' . APP_FOLDER) ?>/artisan queue:work --stop-when-empty --tries=3</div>
        </div>
    <?php else: ?>
        <?php foreach ($errors as $error): ?><div class="alert error"><?= htmlspecialchars($error) ?></div><?php endforeach; ?>
        <div class="alert note">ارفع الحزمة الواحدة واستخرجها في <code>/home/ztyyoefjsg/kifech.com</code>، ثم املأ هذه البيانات. لا تحتاج إلى نقل أي ملف يدوياً.</div>
        <form method="post" class="card grid">
            <input type="hidden" name="_token" value="<?= htmlspecialchars($_SESSION['installer_token']) ?>">
            <div class="section">مسارات الدومينات</div>
            <div class="full"><label>جذر kifech.com</label><input name="main_root" value="<?= htmlspecialchars($data['main_root']) ?>" required></div>
            <div><label>جذر admin.kifech.com</label><input name="admin_root" value="<?= htmlspecialchars($data['admin_root']) ?>" required></div>
            <div><label>جذر api.kifech.com</label><input name="api_root" value="<?= htmlspecialchars($data['api_root']) ?>" required></div>
            <div class="section">قاعدة MySQL</div>
            <div><label>DB Host</label><input name="db_host" value="<?= htmlspecialchars($data['db_host']) ?>" required></div>
            <div><label>DB Port</label><input name="db_port" value="<?= htmlspecialchars($data['db_port']) ?>" required></div>
            <div><label>DB Name</label><input name="db_name" value="<?= htmlspecialchars($data['db_name']) ?>" required></div>
            <div><label>DB Username</label><input name="db_user" value="<?= htmlspecialchars($data['db_user']) ?>" required></div>
            <div class="full"><label>DB Password</label><input type="password" name="db_password" value="<?= htmlspecialchars($data['db_password']) ?>"></div>
            <div class="section">حساب مدير المنصة</div>
            <div><label>الاسم</label><input name="admin_name" value="<?= htmlspecialchars($data['admin_name']) ?>" required></div>
            <div><label>البريد</label><input type="email" name="admin_email" value="<?= htmlspecialchars($data['admin_email']) ?>" required></div>
            <div class="full"><label>كلمة المرور (10 أحرف على الأقل)</label><input type="password" name="admin_password" required minlength="10"></div>
            <div class="full"><button class="button" type="submit">تثبيت وتوزيع المشروع تلقائياً</button></div>
        </form>
    <?php endif; ?>
</div></body></html>
