<?php
/**
 * DW Ads Reporter Web Installer
 * Datweb / DW installer helper.
 *
 * Güvenlik: Kurulum bittikten sonra bu dosyayı ve public/install.php dosyasını silin.
 */

declare(strict_types=1);

$appRoot = defined('DW_INSTALL_APP_ROOT') ? DW_INSTALL_APP_ROOT : __DIR__;
$publicRoot = defined('DW_INSTALL_PUBLIC_ROOT') ? DW_INSTALL_PUBLIC_ROOT : (is_dir($appRoot . '/public') ? $appRoot . '/public' : __DIR__);
$sqlFile = $appRoot . '/database/sql/dw_ads_reporter_install.sql';
$envFile = $appRoot . '/.env';
$errors = [];
$messages = [];
$warnings = [];

function e(string $value): string { return htmlspecialchars($value, ENT_QUOTES, 'UTF-8'); }
function old(string $key, string $default = ''): string { return (string)($_POST[$key] ?? $default); }
function checked(string $key, bool $default = false): string { return (isset($_POST[$key]) ? (bool)$_POST[$key] : $default) ? ' checked' : ''; }
function installer_random_key(): string { return 'base64:' . base64_encode(random_bytes(32)); }
function env_quote(string $value): string {
    $value = str_replace(["\\", "\r", "\n", '"'], ["\\\\", '', '', '\\"'], $value);
    return '"' . $value . '"';
}
function env_bool(bool $value): string { return $value ? 'true' : 'false'; }
function run_command(string $command, string $cwd, array &$messages, array &$warnings): void {
    if (!function_exists('proc_open')) {
        $warnings[] = 'proc_open kapalı olduğu için komut çalıştırılamadı: ' . $command;
        return;
    }
    $descriptorSpec = [
        0 => ['pipe', 'r'],
        1 => ['pipe', 'w'],
        2 => ['pipe', 'w'],
    ];
    $process = @proc_open($command, $descriptorSpec, $pipes, $cwd);
    if (!is_resource($process)) {
        $warnings[] = 'Komut başlatılamadı: ' . $command;
        return;
    }
    fclose($pipes[0]);
    $output = stream_get_contents($pipes[1]);
    $error = stream_get_contents($pipes[2]);
    fclose($pipes[1]);
    fclose($pipes[2]);
    $code = proc_close($process);
    if ($code === 0) {
        $messages[] = 'Komut başarılı: ' . $command;
        if (trim($output) !== '') { $messages[] = '<pre>' . e(trim($output)) . '</pre>'; }
    } else {
        $warnings[] = 'Komut tamamlanamadı: ' . $command . ($error ? '<pre>' . e(trim($error)) . '</pre>' : '');
    }
}
function split_sql_statements(string $sql): array {
    $statements = [];
    $buffer = '';
    $inString = false;
    $quote = '';
    $escape = false;
    $len = strlen($sql);
    for ($i = 0; $i < $len; $i++) {
        $char = $sql[$i];
        $next = $i + 1 < $len ? $sql[$i + 1] : '';
        if (!$inString && $char === '-' && $next === '-') {
            while ($i < $len && $sql[$i] !== "\n") { $i++; }
            $buffer .= "\n";
            continue;
        }
        if (!$inString && $char === '/' && $next === '*') {
            $i += 2;
            while ($i < $len - 1 && !($sql[$i] === '*' && $sql[$i + 1] === '/')) { $i++; }
            $i++;
            continue;
        }
        if ($inString) {
            $buffer .= $char;
            if ($escape) { $escape = false; continue; }
            if ($char === '\\') { $escape = true; continue; }
            if ($char === $quote) { $inString = false; $quote = ''; }
            continue;
        }
        if ($char === "'" || $char === '"' || $char === '`') {
            $inString = true;
            $quote = $char;
            $buffer .= $char;
            continue;
        }
        if ($char === ';') {
            $trimmed = trim($buffer);
            if ($trimmed !== '') { $statements[] = $trimmed; }
            $buffer = '';
            continue;
        }
        $buffer .= $char;
    }
    $trimmed = trim($buffer);
    if ($trimmed !== '') { $statements[] = $trimmed; }
    return $statements;
}
function import_sql(PDO $pdo, string $sqlFile): int {
    $sql = file_get_contents($sqlFile);
    if ($sql === false || trim($sql) === '') {
        throw new RuntimeException('SQL dosyası okunamadı veya boş: ' . $sqlFile);
    }
    $count = 0;
    foreach (split_sql_statements($sql) as $statement) {
        $pdo->exec($statement);
        $count++;
    }
    return $count;
}
function write_env(string $envFile, array $data): void {
    $lines = [
        'APP_NAME=' . env_quote($data['app_name']),
        'APP_ENV=production',
        'APP_KEY=' . $data['app_key'],
        'APP_DEBUG=' . env_bool($data['app_debug']),
        'APP_URL=' . env_quote($data['app_url']),
        '',
        'LOG_CHANNEL=stack',
        'LOG_DEPRECATIONS_CHANNEL=null',
        'LOG_LEVEL=debug',
        '',
        'DB_CONNECTION=mysql',
        'DB_HOST=' . env_quote($data['db_host']),
        'DB_PORT=' . env_quote($data['db_port']),
        'DB_DATABASE=' . env_quote($data['db_name']),
        'DB_USERNAME=' . env_quote($data['db_user']),
        'DB_PASSWORD=' . env_quote($data['db_pass']),
        '',
        'BROADCAST_DRIVER=log',
        'CACHE_DRIVER=file',
        'FILESYSTEM_DISK=local',
        'QUEUE_CONNECTION=sync',
        'SESSION_DRIVER=file',
        'SESSION_LIFETIME=120',
        '',
        'MAIL_MAILER=smtp',
        'MAIL_HOST=' . env_quote($data['mail_host']),
        'MAIL_PORT=' . env_quote($data['mail_port']),
        'MAIL_USERNAME=' . env_quote($data['mail_user']),
        'MAIL_PASSWORD=' . env_quote($data['mail_pass']),
        'MAIL_ENCRYPTION=' . env_quote($data['mail_encryption']),
        'MAIL_FROM_ADDRESS=' . env_quote($data['mail_from_address']),
        'MAIL_FROM_NAME=' . env_quote($data['mail_from_name']),
        '',
        'GOOGLE_CLIENT_ID=',
        'GOOGLE_CLIENT_SECRET=',
        'GOOGLE_ADS_DEVELOPER_TOKEN=',
        'GOOGLE_ADS_API_VERSION=v23',
        'META_GRAPH_VERSION=v23.0',
        '',
    ];
    if (file_exists($envFile)) {
        copy($envFile, $envFile . '.backup-' . date('Ymd-His'));
    }
    if (file_put_contents($envFile, implode("\n", $lines)) === false) {
        throw new RuntimeException('.env dosyası yazılamadı: ' . $envFile);
    }
}

$requirements = [
    'PHP 8.1+' => version_compare(PHP_VERSION, '8.1.0', '>='),
    'PDO MySQL' => extension_loaded('pdo_mysql'),
    'OpenSSL' => extension_loaded('openssl'),
    'Mbstring' => extension_loaded('mbstring'),
    'Tokenizer' => extension_loaded('tokenizer'),
    'Ctype' => extension_loaded('ctype'),
    'JSON' => extension_loaded('json'),
    'Fileinfo' => extension_loaded('fileinfo'),
];

if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    foreach ($requirements as $name => $ok) {
        if (!$ok) { $errors[] = $name . ' sunucuda aktif değil.'; }
    }
    if (!is_file($sqlFile)) { $errors[] = 'SQL dosyası bulunamadı: database/sql/dw_ads_reporter_install.sql'; }
    if (!is_writable($appRoot)) { $errors[] = 'Proje ana dizini yazılabilir değil. .env oluşturmak için yazma izni gerekli.'; }
    foreach (['db_host','db_port','db_name','db_user','app_url','admin_name','admin_email','admin_password'] as $field) {
        if (trim(old($field)) === '') { $errors[] = $field . ' alanı zorunludur.'; }
    }
    if (!filter_var(old('admin_email'), FILTER_VALIDATE_EMAIL)) { $errors[] = 'Admin e-posta adresi geçerli değil.'; }
    if (strlen(old('admin_password')) < 6) { $errors[] = 'Admin şifresi en az 6 karakter olmalı.'; }

    if (!$errors) {
        try {
            $dsn = 'mysql:host=' . old('db_host') . ';port=' . old('db_port', '3306') . ';dbname=' . old('db_name') . ';charset=utf8mb4';
            $pdo = new PDO($dsn, old('db_user'), old('db_pass'), [
                PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
                PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
                PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES utf8mb4',
            ]);
            $statementCount = import_sql($pdo, $sqlFile);
            $messages[] = 'Veritabanı kuruldu. Çalıştırılan SQL adımı: ' . $statementCount;

            $stmt = $pdo->prepare('SELECT id FROM users WHERE email = ? LIMIT 1');
            $stmt->execute([old('admin_email')]);
            $passwordHash = password_hash(old('admin_password'), PASSWORD_BCRYPT);
            if ($stmt->fetch()) {
                $update = $pdo->prepare('UPDATE users SET name = ?, password = ?, updated_at = NOW() WHERE email = ?');
                $update->execute([old('admin_name'), $passwordHash, old('admin_email')]);
                $messages[] = 'Admin kullanıcısı güncellendi: ' . e(old('admin_email'));
            } else {
                $insert = $pdo->prepare('INSERT INTO users (name, email, password, email_verified_at, created_at, updated_at) VALUES (?, ?, ?, NOW(), NOW(), NOW())');
                $insert->execute([old('admin_name'), old('admin_email'), $passwordHash]);
                $messages[] = 'Admin kullanıcısı oluşturuldu: ' . e(old('admin_email'));
            }

            foreach (['storage/app', 'storage/framework/cache', 'storage/framework/sessions', 'storage/framework/views', 'storage/logs', 'bootstrap/cache'] as $dir) {
                $path = $appRoot . '/' . $dir;
                if (!is_dir($path)) { @mkdir($path, 0775, true); }
                if (!is_writable($path)) { $warnings[] = $dir . ' yazılabilir değil. 775/755 izinlerini kontrol edin.'; }
            }

            write_env($envFile, [
                'app_name' => old('app_name', 'DW Ads Reporter'),
                'app_key' => installer_random_key(),
                'app_debug' => isset($_POST['app_debug']),
                'app_url' => rtrim(old('app_url'), '/'),
                'db_host' => old('db_host'),
                'db_port' => old('db_port', '3306'),
                'db_name' => old('db_name'),
                'db_user' => old('db_user'),
                'db_pass' => old('db_pass'),
                'mail_host' => old('mail_host'),
                'mail_port' => old('mail_port', '587'),
                'mail_user' => old('mail_user'),
                'mail_pass' => old('mail_pass'),
                'mail_encryption' => old('mail_encryption', 'tls'),
                'mail_from_address' => old('mail_from_address', old('admin_email')),
                'mail_from_name' => old('mail_from_name', old('app_name', 'DW Ads Reporter')),
            ]);
            $messages[] = '.env dosyası yazıldı.';

            if (isset($_POST['run_composer'])) {
                if (!is_dir($appRoot . '/vendor')) {
                    run_command('composer install --no-dev --optimize-autoloader', $appRoot, $messages, $warnings);
                } else {
                    $messages[] = 'vendor klasörü bulundu, composer install atlandı.';
                }
            } elseif (!is_dir($appRoot . '/vendor')) {
                $warnings[] = 'vendor klasörü pakette yok. Uygulama açılmadan önce SSH/Terminal üzerinden composer install --no-dev --optimize-autoloader çalıştırılmalı veya sunucuda Composer seçeneği işaretlenmeli.';
            }

            if (is_dir($appRoot . '/vendor')) {
                run_command('php artisan optimize:clear', $appRoot, $messages, $warnings);
                run_command('php artisan storage:link', $appRoot, $messages, $warnings);
            }

            $messages[] = 'Kurulum tamamlandı. Güvenlik için install.php ve public/install.php dosyalarını silin.';
        } catch (Throwable $ex) {
            $errors[] = $ex->getMessage();
        }
    }
}

$defaultUrl = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off' ? 'https://' : 'http://') . ($_SERVER['HTTP_HOST'] ?? 'localhost');
$hasVendor = is_dir($appRoot . '/vendor');
?><!doctype html>
<html lang="tr">
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>DW Ads Reporter Kurulum</title>
    <style>
        :root{--bg:#f5f7fb;--card:#fff;--text:#111827;--muted:#6b7280;--brand:#ef5f86;--ok:#16a34a;--warn:#b45309;--danger:#dc2626;--border:#e5e7eb}*{box-sizing:border-box}body{margin:0;background:linear-gradient(135deg,#f8fafc,#eef2ff);font-family:Arial,Helvetica,sans-serif;color:var(--text)}.wrap{max-width:1120px;margin:40px auto;padding:0 18px}.hero{background:#111827;color:#fff;border-radius:18px;padding:28px;box-shadow:0 20px 45px rgba(15,23,42,.18)}.hero h1{margin:0 0 8px;font-size:28px}.hero p{margin:0;color:#d1d5db}.grid{display:grid;grid-template-columns:1fr 1fr;gap:18px;margin-top:18px}.card{background:var(--card);border:1px solid var(--border);border-radius:16px;padding:22px;box-shadow:0 12px 30px rgba(15,23,42,.08)}.full{grid-column:1/-1}h2{margin:0 0 14px;font-size:19px}.row{display:grid;grid-template-columns:1fr 1fr;gap:12px}.field{margin-bottom:12px}label{font-size:13px;font-weight:700;display:block;margin-bottom:6px}input,select{width:100%;border:1px solid var(--border);border-radius:10px;padding:12px 12px;font-size:14px;background:#fff}small{color:var(--muted)}.btn{border:0;border-radius:12px;background:var(--brand);color:#fff;padding:14px 20px;font-weight:800;cursor:pointer;font-size:15px}.btn:hover{filter:brightness(.96)}.status{padding:12px 14px;border-radius:12px;margin:8px 0;font-size:14px}.ok{background:#ecfdf5;color:#166534;border:1px solid #bbf7d0}.warn{background:#fffbeb;color:#92400e;border:1px solid #fde68a}.err{background:#fef2f2;color:#991b1b;border:1px solid #fecaca}.req{display:flex;justify-content:space-between;border-bottom:1px solid #f1f5f9;padding:9px 0}.badge{font-weight:800}.yes{color:var(--ok)}.no{color:var(--danger)}pre{white-space:pre-wrap;background:#0f172a;color:#e5e7eb;border-radius:12px;padding:12px;overflow:auto}.note{background:#fff7ed;border:1px solid #fed7aa;color:#9a3412;border-radius:14px;padding:14px;margin-top:16px}@media(max-width:800px){.grid,.row{grid-template-columns:1fr}.full{grid-column:auto}.wrap{margin:20px auto}.hero{border-radius:14px}}
    </style>
</head>
<body>
<div class="wrap">
    <div class="hero">
        <h1>DW Ads Reporter Kurulum</h1>
        <p>Veritabanı tablolarını oluşturur, .env dosyasını yazar ve ilk admin kullanıcısını hazırlar.</p>
    </div>

    <?php foreach ($errors as $error): ?><div class="status err"><?= e($error) ?></div><?php endforeach; ?>
    <?php foreach ($messages as $message): ?><div class="status ok"><?= $message ?></div><?php endforeach; ?>
    <?php foreach ($warnings as $warning): ?><div class="status warn"><?= $warning ?></div><?php endforeach; ?>

    <div class="grid">
        <div class="card">
            <h2>Sistem Kontrolü</h2>
            <?php foreach ($requirements as $name => $ok): ?>
                <div class="req"><span><?= e($name) ?></span><span class="badge <?= $ok ? 'yes' : 'no' ?>"><?= $ok ? 'OK' : 'Eksik' ?></span></div>
            <?php endforeach; ?>
            <div class="req"><span>SQL dosyası</span><span class="badge <?= is_file($sqlFile) ? 'yes' : 'no' ?>"><?= is_file($sqlFile) ? 'OK' : 'Eksik' ?></span></div>
            <div class="req"><span>vendor klasörü</span><span class="badge <?= $hasVendor ? 'yes' : 'no' ?>"><?= $hasVendor ? 'Var' : 'Yok' ?></span></div>
            <div class="note">Paket içinde vendor yoksa Laravel açılması için Composer gerekir. Bu kurulum SQL ve .env tarafını hazırlar.</div>
        </div>

        <form class="card" method="post">
            <h2>Uygulama</h2>
            <div class="field"><label>Uygulama Adı</label><input name="app_name" value="<?= e(old('app_name', 'DW Ads Reporter')) ?>"></div>
            <div class="field"><label>Site URL</label><input name="app_url" value="<?= e(old('app_url', $defaultUrl)) ?>"></div>
            <div class="field"><label><input type="checkbox" name="app_debug" value="1"<?= checked('app_debug', false) ?> style="width:auto"> Debug açık olsun</label></div>

            <h2>Veritabanı</h2>
            <div class="row">
                <div class="field"><label>DB Host</label><input name="db_host" value="<?= e(old('db_host', '127.0.0.1')) ?>"></div>
                <div class="field"><label>DB Port</label><input name="db_port" value="<?= e(old('db_port', '3306')) ?>"></div>
            </div>
            <div class="field"><label>DB Adı</label><input name="db_name" value="<?= e(old('db_name')) ?>"></div>
            <div class="row">
                <div class="field"><label>DB Kullanıcı</label><input name="db_user" value="<?= e(old('db_user')) ?>"></div>
                <div class="field"><label>DB Şifre</label><input type="password" name="db_pass" value="<?= e(old('db_pass')) ?>"></div>
            </div>

            <h2>İlk Admin</h2>
            <div class="row">
                <div class="field"><label>Ad Soyad</label><input name="admin_name" value="<?= e(old('admin_name', 'Datweb Admin')) ?>"></div>
                <div class="field"><label>E-posta</label><input type="email" name="admin_email" value="<?= e(old('admin_email')) ?>"></div>
            </div>
            <div class="field"><label>Şifre</label><input type="password" name="admin_password" value="<?= e(old('admin_password')) ?>"><small>En az 6 karakter.</small></div>

            <h2>SMTP</h2>
            <div class="row">
                <div class="field"><label>Host</label><input name="mail_host" value="<?= e(old('mail_host')) ?>"></div>
                <div class="field"><label>Port</label><input name="mail_port" value="<?= e(old('mail_port', '587')) ?>"></div>
            </div>
            <div class="row">
                <div class="field"><label>Kullanıcı</label><input name="mail_user" value="<?= e(old('mail_user')) ?>"></div>
                <div class="field"><label>Şifre</label><input type="password" name="mail_pass" value="<?= e(old('mail_pass')) ?>"></div>
            </div>
            <div class="row">
                <div class="field"><label>Şifreleme</label><select name="mail_encryption"><option value="tls">tls</option><option value="ssl">ssl</option><option value="">Yok</option></select></div>
                <div class="field"><label>Gönderici E-posta</label><input name="mail_from_address" value="<?= e(old('mail_from_address')) ?>"></div>
            </div>
            <div class="field"><label>Gönderici Adı</label><input name="mail_from_name" value="<?= e(old('mail_from_name', 'DW Ads Reporter')) ?>"></div>

            <div class="field"><label><input type="checkbox" name="run_composer" value="1"<?= checked('run_composer', false) ?> style="width:auto"> Sunucuda Composer varsa bağımlılıkları kurmayı dene</label></div>
            <button class="btn" type="submit">Kurulumu Başlat</button>
        </form>

        <div class="card full">
            <h2>Kurulumdan Sonra</h2>
            <p>Panel yolu: <strong>/admin</strong> — Portal yolu: <strong>/portal/login</strong></p>
            <p>Güvenlik için kurulum tamamlanınca <strong>install.php</strong> ve <strong>public/install.php</strong> dosyalarını silin.</p>
        </div>
    </div>
</div>
</body>
</html>
