<?php

declare(strict_types=1);

namespace App\Http\Controllers\Admin;

use App\Domain\Domain\Models\Domain;
use App\Domain\Email\Services\DeliverabilityChecker;
use App\Domain\Ssl\Models\SslCertificate;
use App\Domain\Ssl\Services\AutoSslManager;
use App\Domain\Sysapi\Contracts\SysapiBridge;
use App\Http\Controllers\Controller;
use App\Jobs\ProvisionAutoSslJob;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Carbon;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Schema;
use Inertia\Inertia;
use Inertia\Response;

/**
 * Admin SSL/AutoSSL Manager (WHM SSL/TLS Status + AutoSSL muadili).
 *
 * Veri kaynakları:
 *   - `ssl_certificates` tablosu — issued cert metadata
 *   - `audit_log` (action LIKE 'ssl.%') — recent events feed
 *   - sysapi `cert-issue`, `cert-renew`, `cert-revoke` — job ProvisionAutoSslJob ile dispatch
 *
 * Mock data ÜRETMEZ. Boş tablo varsa empty state gösterir.
 */
class SslManagerController extends Controller
{
    public function __construct(
        private readonly SysapiBridge $sysapi,
        private readonly AutoSslManager $autoSsl,
    ) {}

    public function index(Request $request): Response
    {
        $settings = DB::table('autossl_settings')
            ->orderBy('category')
            ->orderBy('key')
            ->get();

        $grouped = collect($settings)->groupBy('category');

        $certificates = DB::table('ssl_certificates as c')
            ->leftJoin('domains as d', 'd.id', '=', 'c.domain_id')
            ->leftJoin('accounts as a', 'a.id', '=', 'd.account_id')
            ->select(
                'c.*',
                'd.name as domain_name',
                'a.username as account_username',
            )
            ->orderBy('c.expires_at')
            ->get();

        foreach ($certificates as $cert) {
            $cert->days_until_expiry = $cert->expires_at
                ? (int) Carbon::parse($cert->expires_at)->diffInDays(now(), false)
                : null;
        }

        $now = now();
        $stats = [
            'total' => $certificates->count(),
            'valid' => $certificates->filter(fn ($c) => $c->days_until_expiry !== null && $c->days_until_expiry < -30)->count(),
            'expiring_soon' => $certificates->filter(fn ($c) => $c->days_until_expiry !== null && $c->days_until_expiry >= -30 && $c->days_until_expiry < 0)->count(),
            'expired' => $certificates->filter(fn ($c) => $c->days_until_expiry !== null && $c->days_until_expiry >= 0)->count(),
            'failed' => $certificates->filter(fn ($c) => ($c->status ?? '') === 'error')->count(),
        ];

        // ── Recent events — audit_log'dan gerçek SSL event'leri ────────────
        $recent_events = DB::table('audit_log')
            ->where('action', 'LIKE', 'ssl.%')
            ->orderByDesc('created_at')
            ->limit(30)
            ->get()
            ->map(function ($row) {
                $metadata = $row->metadata ? json_decode($row->metadata, true) : [];
                $action = (string) $row->action;

                // ssl.issued → "issued", ssl.renewed → "renewed", vb.
                $eventType = str_starts_with($action, 'ssl.')
                    ? substr($action, 4)
                    : 'unknown';

                return [
                    'id' => $row->id,
                    'timestamp' => Carbon::parse($row->created_at)->format('Y-m-d H:i:s'),
                    'domain' => $metadata['domain'] ?? $metadata['domain_name'] ?? '—',
                    'event' => $eventType,
                    'provider' => $metadata['provider'] ?? $metadata['issuer'] ?? 'letsencrypt',
                    'message' => $metadata['message'] ?? $metadata['error'] ?? ($row->outcome === 'success' ? 'OK' : 'Hata'),
                ];
            });

        return Inertia::render('Admin/Ssl/Index', compact(
            'grouped',
            'certificates',
            'stats',
            'recent_events',
        ));
    }

    public function update(Request $request): RedirectResponse
    {
        $request->validate([
            'settings' => ['required', 'array'],
        ]);

        $validKeys = DB::table('autossl_settings')->pluck('data_type', 'key')->toArray();

        foreach ($request->input('settings', []) as $key => $value) {
            if (! array_key_exists($key, $validKeys)) {
                continue;
            }

            $serialized = match ($validKeys[$key]) {
                'boolean' => $value ? '1' : '0',
                'integer' => (string) (int) $value,
                default => (string) $value,
            };

            DB::table('autossl_settings')
                ->where('key', $key)
                ->update(['value' => $serialized, 'updated_at' => now()]);
        }

        return back()->with('success', 'AutoSSL ayarları güncellendi.');
    }

    /**
     * Hatalı tüm sertifikalar için ProvisionAutoSslJob kuyruğa atar.
     */
    public function renewAll(Request $request): RedirectResponse
    {
        $failedCerts = DB::table('ssl_certificates as c')
            ->join('domains as d', 'd.id', '=', 'c.domain_id')
            ->where('c.status', 'error')
            ->select('c.id as cert_id', 'd.id as domain_id', 'd.name as domain_name')
            ->get();

        $dispatched = 0;
        foreach ($failedCerts as $row) {
            try {
                ProvisionAutoSslJob::dispatch((int) $row->domain_id);

                DB::table('ssl_certificates')
                    ->where('id', $row->cert_id)
                    ->update(['status' => 'renewing', 'updated_at' => now()]);

                DB::table('audit_log')->insert([
                    'user_id' => auth()->id(),
                    'action' => 'ssl.renew_queued',
                    'target_type' => 'ssl_certificate',
                    'target_id' => $row->cert_id,
                    'outcome' => 'success',
                    'metadata' => json_encode(['domain' => $row->domain_name, 'reason' => 'renew_all']),
                    'created_at' => now(),
                ]);
                $dispatched++;
            } catch (\Throwable $e) {
                Log::warning('ssl.renew_all_failed', [
                    'cert_id' => $row->cert_id,
                    'error' => $e->getMessage(),
                ]);
            }
        }

        return back()->with('success', "Tüm başarısız sertifikalar yenileme kuyruğuna alındı ({$dispatched} sertifika).");
    }

    /**
     * Tek sertifika için renew dispatch — domain üzerinden ProvisionAutoSslJob.
     */
    public function renew(Request $request, int $certificateId): RedirectResponse
    {
        $cert = DB::table('ssl_certificates')->where('id', $certificateId)->first();
        if (! $cert) {
            return back()->with('error', 'Sertifika bulunamadı.');
        }

        try {
            ProvisionAutoSslJob::dispatch((int) $cert->domain_id);

            DB::table('ssl_certificates')
                ->where('id', $certificateId)
                ->update(['status' => 'renewing', 'updated_at' => now()]);

            $domainName = DB::table('domains')->where('id', $cert->domain_id)->value('name');
            DB::table('audit_log')->insert([
                'user_id' => auth()->id(),
                'action' => 'ssl.renew_queued',
                'target_type' => 'ssl_certificate',
                'target_id' => $certificateId,
                'outcome' => 'success',
                'metadata' => json_encode(['domain' => $domainName, 'reason' => 'manual']),
                'created_at' => now(),
            ]);
        } catch (\Throwable $e) {
            return back()->with('error', "Yenileme kuyruğa eklenemedi: {$e->getMessage()}");
        }

        return back()->with('success', 'Sertifika yenileme kuyruğa eklendi.');
    }

    /**
     * Sertifika revoke — sysapi `cert-revoke` ile gerçek acme.sh çağrısı.
     */
    public function revoke(Request $request, int $certificateId): RedirectResponse
    {
        $cert = DB::table('ssl_certificates')
            ->where('ssl_certificates.id', $certificateId)
            ->leftJoin('domains', 'domains.id', '=', 'ssl_certificates.domain_id')
            ->select('ssl_certificates.*', 'domains.name as domain_name')
            ->first();

        if (! $cert) {
            return back()->with('error', 'Sertifika bulunamadı.');
        }

        if (empty($cert->domain_name)) {
            return back()->with('error', 'Bağlı domain bulunamadı.');
        }

        try {
            $result = $this->sysapi->run('cert-revoke', [
                'domain' => $cert->domain_name,
            ], timeoutSeconds: 60);

            if ($result->failed()) {
                Log::warning('ssl.revoke_sysapi_failed', [
                    'cert_id' => $certificateId,
                    'domain' => $cert->domain_name,
                    'stderr' => $result->stderr,
                ]);
                return back()->with('warning', 'Acme revoke başarısız, DB satırı yine de iptal işaretlendi: '.$result->stderr);
            }

            DB::table('ssl_certificates')
                ->where('id', $certificateId)
                ->update([
                    'status' => 'revoked',
                    'last_error' => 'Admin tarafından iptal edildi.',
                    'updated_at' => now(),
                ]);

            DB::table('audit_log')->insert([
                'user_id' => auth()->id(),
                'action' => 'ssl.revoked',
                'target_type' => 'ssl_certificate',
                'target_id' => $certificateId,
                'outcome' => 'success',
                'metadata' => json_encode(['domain' => $cert->domain_name, 'message' => 'Admin tarafından iptal edildi']),
                'created_at' => now(),
            ]);
        } catch (\Throwable $e) {
            return back()->with('error', "Revoke hatası: {$e->getMessage()}");
        }

        return back()->with('success', "Sertifika iptal edildi: {$cert->domain_name}");
    }

    public function resetSettings(Request $request): RedirectResponse
    {
        $rows = DB::table('autossl_settings')->get();

        foreach ($rows as $row) {
            DB::table('autossl_settings')
                ->where('id', $row->id)
                ->update(['value' => $row->default_value, 'updated_at' => now()]);
        }

        return back()->with('success', 'AutoSSL varsayılana sıfırlandı.');
    }

    /**
     * "Run AutoSSL Now" — admin paneli butonu.
     */
    public function runAutoSslNow(Request $request): RedirectResponse
    {
        $validated = $request->validate([
            'domain_id' => ['nullable', 'integer', 'exists:domains,id'],
        ]);

        if (! empty($validated['domain_id'])) {
            ProvisionAutoSslJob::dispatch($validated['domain_id']);

            return back()->with('success', 'AutoSSL job kuyruğa eklendi.');
        }

        $count = 0;
        Domain::query()
            ->where('ssl_enabled', true)
            ->where('status', \App\Domain\Domain\Enums\DomainStatus::Active)
            ->chunk(100, function ($domains) use (&$count) {
                foreach ($domains as $domain) {
                    ProvisionAutoSslJob::dispatch($domain->id);
                    $count++;
                }
            });

        return back()->with('success', "AutoSSL toplu çalıştırma kuyruğa eklendi ({$count} domain).");
    }

    // ─────────────────────────────────────────────────────────────────────
    // Phase 1 Epic 9.6 — Admin AutoSSL Manager (cPanel "Manage AutoSSL")
    // ─────────────────────────────────────────────────────────────────────

    /**
     * AutoSSL Manager ana sayfa — tum cert tablosu + LE rate-limit indicator.
     */
    public function autoSslIndex(Request $request): Response
    {
        $filters = [
            'status' => $request->string('status')->toString() ?: null,
            'expiring' => $request->string('expiring')->toString() ?: null,
            'search' => $request->string('search')->toString() ?: null,
            'auto_renew' => $request->has('auto_renew') ? (bool) $request->boolean('auto_renew') : null,
        ];

        $hasTrackingCols = Schema::hasColumn('ssl_certificates', 'rate_limited_until');

        $query = DB::table('ssl_certificates as c')
            ->leftJoin('domains as d', 'd.id', '=', 'c.domain_id')
            ->leftJoin('accounts as a', 'a.id', '=', 'd.account_id')
            ->whereNull('c.deleted_at')
            ->where(function ($q) {
                $q->where('c.is_san_secondary', false)
                  ->orWhereNull('c.is_san_secondary');
            });

        $select = [
            'c.id', 'c.domain_id', 'c.issuer', 'c.challenge', 'c.common_name',
            'c.alt_names', 'c.issued_at', 'c.expires_at', 'c.status',
            'c.last_error', 'c.last_renewal_attempt_at', 'c.auto_renew',
            'd.name as domain_name', 'a.username as account_username',
        ];
        if ($hasTrackingCols) {
            $select[] = 'c.renewal_attempt_count';
            $select[] = 'c.last_renewal_error';
            $select[] = 'c.rate_limited_until';
        }
        $query->select($select);

        if (! empty($filters['status'])) {
            if ($filters['status'] === 'rate_limited' && $hasTrackingCols) {
                $query->whereNotNull('c.rate_limited_until')
                      ->where('c.rate_limited_until', '>', now());
            } else {
                $query->where('c.status', $filters['status']);
            }
        }
        if (! empty($filters['search'])) {
            $needle = '%'.$filters['search'].'%';
            $query->where(function ($q) use ($needle) {
                $q->where('d.name', 'LIKE', $needle)
                  ->orWhere('c.common_name', 'LIKE', $needle);
            });
        }
        if (! empty($filters['expiring'])) {
            $days = (int) $filters['expiring'];
            if (in_array($days, [30, 60, 90], true)) {
                $query->whereNotNull('c.expires_at')
                      ->where('c.expires_at', '<=', now()->addDays($days));
            }
        }
        if ($filters['auto_renew'] !== null) {
            $query->where('c.auto_renew', $filters['auto_renew']);
        }

        $rows = $query->orderBy('c.expires_at')->get();

        $now = now();
        $sevenDaysAgo = $now->copy()->subDays(7);

        $certificates = $rows->map(function ($c) use ($now, $hasTrackingCols) {
            $daysUntil = null;
            if (! empty($c->expires_at)) {
                $daysUntil = (int) $now->copy()->diffInDays(Carbon::parse($c->expires_at), false);
            }
            $rateLimitedUntil = $hasTrackingCols ? ($c->rate_limited_until ?? null) : null;
            $isRateLimited = $rateLimitedUntil !== null
                && Carbon::parse($rateLimitedUntil)->isFuture();

            return [
                'id' => $c->id,
                'domain_id' => $c->domain_id,
                'domain_name' => $c->domain_name,
                'account_username' => $c->account_username,
                'common_name' => $c->common_name,
                'issuer' => $c->issuer,
                'challenge' => $c->challenge,
                'status' => $c->status,
                'auto_renew' => (bool) $c->auto_renew,
                'issued_at' => $c->issued_at,
                'expires_at' => $c->expires_at,
                'days_until_expiry' => $daysUntil,
                'last_renewal_attempt_at' => $c->last_renewal_attempt_at,
                'last_error' => $c->last_error,
                'last_renewal_error' => $hasTrackingCols ? ($c->last_renewal_error ?? null) : null,
                'renewal_attempt_count' => $hasTrackingCols ? (int) ($c->renewal_attempt_count ?? 0) : 0,
                'rate_limited_until' => $rateLimitedUntil,
                'is_rate_limited' => $isRateLimited,
                'has_problem' => $isRateLimited
                    || ($hasTrackingCols && ! empty($c->last_renewal_error))
                    || $c->status === 'error',
            ];
        })->values();

        // Failed son 7 gun — le_rate_limit_events varsa oradan, yoksa cert.last_renewal_attempt_at
        $failedLast7d = 0;
        if (Schema::hasTable('le_rate_limit_events')) {
            $failedLast7d = (int) DB::table('le_rate_limit_events')
                ->where('event_type', 'failed')
                ->where('occurred_at', '>=', $sevenDaysAgo)
                ->count();
        } else {
            $failedLast7d = $certificates->where('status', 'error')
                ->filter(fn ($c) => $c['last_renewal_attempt_at']
                    && Carbon::parse($c['last_renewal_attempt_at'])->gte($sevenDaysAgo))
                ->count();
        }

        $stats = [
            'total' => $certificates->count(),
            'active' => $certificates->where('status', 'active')->count(),
            'expiring_30d' => $certificates->filter(
                fn ($c) => $c['days_until_expiry'] !== null
                    && $c['days_until_expiry'] >= 0
                    && $c['days_until_expiry'] <= 30
            )->count(),
            'expired' => $certificates->filter(
                fn ($c) => $c['days_until_expiry'] !== null && $c['days_until_expiry'] < 0
            )->count(),
            'failed_last_7d' => $failedLast7d,
            'rate_limited' => $certificates->where('is_rate_limited', true)->count(),
        ];

        $serverRateLimit = $this->autoSsl->getServerRateLimitStatus();

        return Inertia::render('Admin/Ssl/AutoSslManager', [
            'certificates' => $certificates,
            'stats' => $stats,
            'server_rate_limit' => $serverRateLimit,
            'filters' => $filters,
        ]);
    }

    /**
     * Tek cert detay — SAN listesi, RBL check, recent events.
     */
    public function autoSslShow(int $id): Response
    {
        $cert = SslCertificate::with('domain.account')->findOrFail($id);

        // SAN satirlari (ayni primary cert'in SAN'lari)
        $sans = SslCertificate::query()
            ->where('parent_cert_id', $cert->id)
            ->orWhere(function ($q) use ($cert) {
                $q->where('domain_id', $cert->domain_id)
                  ->where('id', '!=', $cert->id);
            })
            ->whereNull('deleted_at')
            ->get(['id', 'common_name', 'status', 'expires_at', 'is_san_secondary']);

        // Recent LE events (son 30 gun, en yenisi onde)
        $recentEvents = collect();
        if (Schema::hasTable('le_rate_limit_events') && $cert->domain) {
            $recentEvents = DB::table('le_rate_limit_events')
                ->where('domain', mb_strtolower($cert->domain->name))
                ->where('occurred_at', '>=', now()->subDays(30))
                ->orderByDesc('occurred_at')
                ->limit(50)
                ->get();
        }

        $domainRateLimit = $cert->domain
            ? $this->autoSsl->getDomainRateLimitStatus($cert->domain->name)
            : null;

        return Inertia::render('Admin/Ssl/AutoSslShow', [
            'cert' => [
                'id' => $cert->id,
                'common_name' => $cert->common_name,
                'alt_names' => $cert->alt_names ?? [],
                'issuer' => $cert->issuer,
                'challenge' => $cert->challenge,
                'status' => $cert->status?->value,
                'issued_at' => $cert->issued_at?->toIso8601String(),
                'expires_at' => $cert->expires_at?->toIso8601String(),
                'auto_renew' => (bool) $cert->auto_renew,
                'last_error' => $cert->last_error,
                'last_renewal_error' => $cert->last_renewal_error ?? null,
                'last_renewal_attempt_at' => $cert->last_renewal_attempt_at?->toIso8601String(),
                'renewal_attempt_count' => (int) ($cert->renewal_attempt_count ?? 0),
                'rate_limited_until' => $cert->rate_limited_until?->toIso8601String(),
                'chain' => $cert->chain,
                'domain' => $cert->domain ? [
                    'id' => $cert->domain->id,
                    'name' => $cert->domain->name,
                    'account' => $cert->domain->account?->username,
                ] : null,
            ],
            'sans' => $sans,
            'recent_events' => $recentEvents,
            'domain_rate_limit' => $domainRateLimit,
        ]);
    }

    /**
     * Force-renew tek cert. ?bypass_rate_check=1 ile LE limit bypass edilebilir.
     */
    public function forceRenew(Request $request, int $id): RedirectResponse
    {
        $cert = SslCertificate::findOrFail($id);
        $bypass = (bool) $request->boolean('bypass_rate_check');

        $result = $this->autoSsl->forceRenew($cert, $bypass);

        DB::table('audit_log')->insert([
            'user_id' => auth()->id(),
            'action' => $result['success'] ? 'ssl.force_renewed' : 'ssl.force_renew_failed',
            'target_type' => 'ssl_certificate',
            'target_id' => $id,
            'outcome' => $result['success'] ? 'success' : 'failure',
            'metadata' => json_encode([
                'cert_id' => $id,
                'common_name' => $cert->common_name,
                'bypass_rate_check' => $bypass,
                'message' => $result['message'],
            ]),
            'created_at' => now(),
        ]);

        if ($result['skipped']) {
            return back()->with('warning', $result['message']);
        }

        return $result['success']
            ? back()->with('success', $result['message'])
            : back()->with('error', $result['message']);
    }

    /**
     * Auto-renew bayragini toggle et.
     */
    public function toggleAutoRenew(Request $request, int $id): RedirectResponse
    {
        $cert = SslCertificate::findOrFail($id);
        $cert->auto_renew = ! $cert->auto_renew;
        $cert->save();

        DB::table('audit_log')->insert([
            'user_id' => auth()->id(),
            'action' => 'ssl.auto_renew_toggled',
            'target_type' => 'ssl_certificate',
            'target_id' => $id,
            'outcome' => 'success',
            'metadata' => json_encode([
                'common_name' => $cert->common_name,
                'new_value' => $cert->auto_renew,
            ]),
            'created_at' => now(),
        ]);

        $label = $cert->auto_renew ? 'aktif' : 'pasif';

        return back()->with('success', "Otomatik yenileme {$label} edildi: {$cert->common_name}");
    }

    /**
     * Toplu force renew — admin secimi, "ONAYLA" stringi gereklidir.
     * Rate-limited domain'ler atlanir.
     */
    public function bulkRenew(Request $request): RedirectResponse
    {
        $validated = $request->validate([
            'cert_ids' => ['required', 'array', 'min:1', 'max:200'],
            'cert_ids.*' => ['integer', 'exists:ssl_certificates,id'],
            'confirmation' => ['required', 'string'],
            'bypass_rate_check' => ['nullable', 'boolean'],
        ]);

        if (mb_strtoupper(trim($validated['confirmation'])) !== 'ONAYLA') {
            return back()->with('error', 'Toplu yenileme onayi icin "ONAYLA" yazmalisin.');
        }

        $bypass = (bool) ($validated['bypass_rate_check'] ?? false);

        $summary = ['renewed' => 0, 'failed' => 0, 'skipped' => 0, 'details' => []];

        $certs = SslCertificate::with('domain')
            ->whereIn('id', $validated['cert_ids'])
            ->get();

        foreach ($certs as $cert) {
            $result = $this->autoSsl->forceRenew($cert, $bypass);

            if ($result['skipped']) {
                $summary['skipped']++;
            } elseif ($result['success']) {
                $summary['renewed']++;
            } else {
                $summary['failed']++;
            }

            $summary['details'][] = [
                'cert_id' => $cert->id,
                'common_name' => $cert->common_name,
                'status' => $result['success'] ? 'renewed' : ($result['skipped'] ? 'skipped' : 'failed'),
                'message' => $result['message'],
            ];
        }

        DB::table('audit_log')->insert([
            'user_id' => auth()->id(),
            'action' => 'ssl.bulk_renew',
            'target_type' => 'ssl_certificate',
            'target_id' => null,
            'outcome' => $summary['failed'] === 0 ? 'success' : 'partial',
            'metadata' => json_encode([
                'count' => $certs->count(),
                'renewed' => $summary['renewed'],
                'failed' => $summary['failed'],
                'skipped' => $summary['skipped'],
                'bypass_rate_check' => $bypass,
            ]),
            'created_at' => now(),
        ]);

        return back()->with(
            'success',
            "Toplu yenileme tamamlandi: {$summary['renewed']} basarili, "
            ."{$summary['failed']} basarisiz, {$summary['skipped']} atlandi (rate-limit)."
        );
    }

    /**
     * Domain'i RBL listelerinde sorgula — cert issuance'i bloke eden DNS sorunlarini gosterir.
     */
    public function checkRbl(int $id, DeliverabilityChecker $checker): RedirectResponse
    {
        $cert = SslCertificate::with('domain')->findOrFail($id);

        if (! $cert->domain) {
            return back()->with('error', 'Domain bulunamadi.');
        }

        try {
            // DeliverabilityChecker::checkRbl() sunucu IP'sini sorgular —
            // SSL issuance icin de uygun: spam-listed IP'lerden cert almak zor.
            $rbl = $checker->checkRbl();
            $ptr = $checker->checkPtr();

            $listed = $rbl['listed_count'] ?? 0;

            DB::table('audit_log')->insert([
                'user_id' => auth()->id(),
                'action' => 'ssl.rbl_checked',
                'target_type' => 'ssl_certificate',
                'target_id' => $id,
                'outcome' => 'success',
                'metadata' => json_encode([
                    'domain' => $cert->domain->name,
                    'listed_count' => $listed,
                    'server_ip' => $rbl['server_ip'] ?? null,
                ]),
                'created_at' => now(),
            ]);

            $msg = "RBL kontrol tamamlandi: {$listed} listede goruldu. PTR: ".
                ($ptr['valid'] ? 'OK' : 'PROBLEM');

            return $listed > 0
                ? back()->with('warning', $msg.' — kara listede.')
                : back()->with('success', $msg);
        } catch (\Throwable $e) {
            return back()->with('error', "RBL kontrolu basarisiz: {$e->getMessage()}");
        }
    }
}
