<?php

declare(strict_types=1);

session_start();

const PROJECT_ZIP = 'accounting-crm.zip';
const PROJECT_MARKER = 'artisan';

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

function rootInstallerRender(string $title, string $body): void
{
    echo '<!doctype html><html lang="fa" dir="rtl"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1"><title>'.rootInstallerH($title).'</title><style>
    body{margin:0;background:#f7f7f8;color:#111827;font-family:Tahoma,Arial,sans-serif;line-height:1.8}
    .wrap{max-width:920px;margin:40px auto;padding:0 18px}.card{background:#fff;border:1px solid #e5e7eb;border-radius:8px;padding:22px}
    .btn{display:inline-block;background:#ed1f4f;color:#fff;border:0;border-radius:6px;padding:10px 18px;text-decoration:none;cursor:pointer;font-family:inherit}
    .ok{color:#15803d}.bad{color:#dc2626}.muted{color:#6b7280}code{direction:ltr;display:inline-block}pre{direction:ltr;white-space:pre-wrap;background:#f8fafc;border:1px solid #e5e7eb;border-radius:6px;padding:12px;max-height:420px;overflow:auto}
    table{width:100%;border-collapse:collapse;margin:14px 0}td,th{border:1px solid #e5e7eb;padding:9px;text-align:right}th{background:#8d99aa;color:#fff}
    </style></head><body><main class="wrap"><div class="card"><h1>'.rootInstallerH($title).'</h1>'.$body.'</div></main></body></html>';
    exit;
}

function rootInstallerEnvValue(string $key): ?string
{
    $envPath = __DIR__.'/.env';
    if (! file_exists($envPath)) {
        return null;
    }

    foreach (preg_split('/\R/', (string) file_get_contents($envPath)) ?: [] as $line) {
        $line = trim($line);
        if ($line === '' || str_starts_with($line, '#') || ! str_contains($line, '=')) {
            continue;
        }

        [$envKey, $value] = explode('=', $line, 2);
        if ($envKey === $key) {
            return trim($value, "\"'");
        }
    }

    return null;
}

function rootInstallerTail(string $path, int $lines = 140): string
{
    if (! file_exists($path)) {
        return 'فایل پیدا نشد: '.$path;
    }

    $content = file_get_contents($path);
    if ($content === false || $content === '') {
        return 'فایل خالی است یا قابل خواندن نیست: '.$path;
    }

    return implode("\n", array_slice(preg_split('/\R/', $content) ?: [], -$lines));
}

function rootInstallerEnsureRuntimeDirectories(): void
{
    foreach ([
        'bootstrap/cache',
        'storage/app/private',
        'storage/app/public',
        'storage/framework/cache',
        'storage/framework/cache/data',
        'storage/framework/sessions',
        'storage/framework/testing',
        'storage/framework/views',
        'storage/logs',
    ] as $directory) {
        $path = __DIR__.'/'.$directory;
        if (! is_dir($path)) {
            mkdir($path, 0755, true);
        }
    }
}

function rootInstallerDiagnose(): void
{
    rootInstallerEnsureRuntimeDirectories();

    $checks = [
        ['PHP version', version_compare(PHP_VERSION, '8.3.0', '>='), PHP_VERSION],
        ['Zip extension', extension_loaded('zip'), extension_loaded('zip') ? 'enabled' : 'missing'],
        ['PDO MySQL extension', extension_loaded('pdo_mysql'), extension_loaded('pdo_mysql') ? 'enabled' : 'missing'],
        ['Mbstring extension', extension_loaded('mbstring'), extension_loaded('mbstring') ? 'enabled' : 'missing'],
        ['OpenSSL extension', extension_loaded('openssl'), extension_loaded('openssl') ? 'enabled' : 'missing'],
        ['Root writable', is_writable(__DIR__), is_writable(__DIR__) ? 'yes' : 'no'],
        ['storage writable', is_dir(__DIR__.'/storage') && is_writable(__DIR__.'/storage'), is_writable(__DIR__.'/storage') ? 'yes' : 'no'],
        ['bootstrap/cache writable', is_dir(__DIR__.'/bootstrap/cache') && is_writable(__DIR__.'/bootstrap/cache'), is_writable(__DIR__.'/bootstrap/cache') ? 'yes' : 'no'],
        ['vendor/autoload.php', file_exists(__DIR__.'/vendor/autoload.php'), file_exists(__DIR__.'/vendor/autoload.php') ? 'exists' : 'missing'],
        ['.env', file_exists(__DIR__.'/.env'), file_exists(__DIR__.'/.env') ? 'exists' : 'missing'],
        ['APP_KEY', (bool) rootInstallerEnvValue('APP_KEY'), rootInstallerEnvValue('APP_KEY') ? 'set' : 'empty'],
    ];

    $rows = '';
    foreach ($checks as [$label, $ok, $value]) {
        $rows .= '<tr><td>'.rootInstallerH($label).'</td><td class="'.($ok ? 'ok' : 'bad').'">'.($ok ? 'OK' : 'ERROR').'</td><td>'.rootInstallerH((string) $value).'</td></tr>';
    }

    $dbStatus = 'DB_CONNECTION is not mysql or .env is missing.';
    if (rootInstallerEnvValue('DB_CONNECTION') === 'mysql') {
        try {
            new PDO(
                'mysql:host='.(rootInstallerEnvValue('DB_HOST') ?: '127.0.0.1').';port='.(rootInstallerEnvValue('DB_PORT') ?: '3306').';dbname='.(rootInstallerEnvValue('DB_DATABASE') ?: '').';charset=utf8mb4',
                rootInstallerEnvValue('DB_USERNAME') ?: '',
                rootInstallerEnvValue('DB_PASSWORD') ?: '',
                [PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION]
            );
            $dbStatus = 'اتصال دیتابیس موفق است.';
        } catch (Throwable $exception) {
            $dbStatus = $exception->getMessage();
        }
    }

    $laravelLog = rootInstallerTail(__DIR__.'/storage/logs/laravel.log');
    $phpErrorLog = rootInstallerTail(__DIR__.'/error_log');

    rootInstallerRender(
        'عیب‌یابی اضطراری نصب',
        '<p class="muted">این صفحه بیرون از Laravel اجرا می‌شود و برای پیدا کردن علت 500 است. بعد از رفع مشکل، فایل installer.php را حذف کنید.</p>'
        .'<table><thead><tr><th>مورد</th><th>وضعیت</th><th>جزئیات</th></tr></thead><tbody>'.$rows.'</tbody></table>'
        .'<h2>وضعیت دیتابیس</h2><pre>'.rootInstallerH($dbStatus).'</pre>'
        .'<h2>Laravel log</h2><pre>'.rootInstallerH($laravelLog).'</pre>'
        .'<h2>PHP error_log کنار installer</h2><pre>'.rootInstallerH($phpErrorLog).'</pre>'
    );
}

function rootInstallerWriteFrontController(): void
{
    $index = <<<'PHP'
<?php

foreach ([
    'bootstrap/cache',
    'storage/app/private',
    'storage/app/public',
    'storage/framework/cache',
    'storage/framework/cache/data',
    'storage/framework/sessions',
    'storage/framework/testing',
    'storage/framework/views',
    'storage/logs',
] as $directory) {
    $path = __DIR__.'/'.$directory;
    if (! is_dir($path)) {
        mkdir($path, 0755, true);
    }
}

if (version_compare(PHP_VERSION, '8.3.0', '<')) {
    http_response_code(500);
    echo 'Korosh CRM requires PHP 8.3 or newer. Current PHP: '.htmlspecialchars(PHP_VERSION, ENT_QUOTES, 'UTF-8');
    exit;
}

if (! file_exists(__DIR__.'/vendor/autoload.php')) {
    http_response_code(500);
    echo 'vendor/autoload.php is missing. Please run installer.php again or upload the complete package.';
    exit;
}

require __DIR__.'/public/index.php';
PHP;

    $htaccess = <<<'HTACCESS'
Options -Indexes
DirectoryIndex index.php

<IfModule mod_rewrite.c>
    RewriteEngine On

    RewriteRule ^(fonts|sounds|build|storage)/(.*)$ public/$1/$2 [L]
    RewriteRule ^(favicon\.ico|robots\.txt)$ public/$1 [L]

    RewriteRule ^(\.env|composer\.(json|lock)|package\.json|phpunit\.xml|artisan)$ - [F,L]
    RewriteRule ^(app|bootstrap|config|database|docs|resources|routes|storage|tests|tools|vendor)(/|$) - [F,L]

    RewriteCond %{REQUEST_URI} !^/public/
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteRule ^ index.php [L]
</IfModule>
HTACCESS;

    if (! file_exists(__DIR__.'/index.php')) {
        file_put_contents(__DIR__.'/index.php', $index, LOCK_EX);
    }

    file_put_contents(__DIR__.'/.htaccess', $htaccess, LOCK_EX);
}

if (($_GET['diagnose'] ?? '') === '1' || ($_GET['step'] ?? '') === 'diagnose-root') {
    rootInstallerDiagnose();
}

function rootInstallerExtractProject(): void
{
    if (! extension_loaded('zip')) {
        rootInstallerRender('خطای نصب', '<p class="bad">Extension zip روی سرور فعال نیست.</p>');
    }

    if (! file_exists(__DIR__.'/'.PROJECT_ZIP)) {
        rootInstallerRender('فایل پروژه پیدا نشد', '<p>فایل <code>'.PROJECT_ZIP.'</code> باید کنار installer.php باشد.</p>');
    }

    $zip = new ZipArchive;
    if ($zip->open(__DIR__.'/'.PROJECT_ZIP) !== true) {
        rootInstallerRender('خطای نصب', '<p class="bad">فایل ZIP پروژه قابل باز شدن نیست.</p>');
    }

    if (! is_writable(__DIR__)) {
        rootInstallerRender('خطای دسترسی', '<p class="bad">روت دامنه قابل نوشتن نیست و امکان Extract وجود ندارد.</p>');
    }

    $zip->extractTo(__DIR__);
    $zip->close();
    rootInstallerEnsureRuntimeDirectories();
    rootInstallerWriteFrontController();
}

if (! file_exists(__DIR__.'/'.PROJECT_MARKER)) {
    if ($_SERVER['REQUEST_METHOD'] === 'POST') {
        rootInstallerExtractProject();
        header('Location: installer.php');
        exit;
    }

    rootInstallerRender('نصاب کوروش CRM', '<p>این بسته شامل دو فایل است:</p><ul><li><code>installer.php</code></li><li><code>'.PROJECT_ZIP.'</code></li></ul><p>با کلیک روی دکمه زیر، پروژه در همین مسیر Extract می‌شود و سپس مراحل نصب دیتابیس و کسب‌وکار شروع می‌شود.</p><form method="post"><button class="btn">Extract و شروع نصب</button></form>');
}

if (! file_exists(__DIR__.'/public/installer.php')) {
    rootInstallerRender('نصاب داخلی پیدا نشد', '<p class="bad">فایل <code>public/installer.php</code> بعد از Extract پیدا نشد.</p>');
}

rootInstallerEnsureRuntimeDirectories();

require __DIR__.'/public/installer.php';
