<?php

declare(strict_types=1);

namespace App\Domain\Performance\Services;

use App\Domain\Account\Models\Account;
use App\Domain\Backup\Models\Backup;
use App\Domain\Database\Models\MysqlDatabase;
use App\Domain\Dns\Models\DnsZone;
use App\Domain\Domain\Models\Domain;
use App\Domain\Email\Models\EmailAccount;
use App\Domain\Ftp\Models\FtpUser;
use App\Domain\Ssl\Models\SslCertificate;
use App\Models\User;
use Illuminate\Support\Facades\Cache;

/**
 * Pahalı agreggate query'leri için cache layer.
 *
 * Dashboard, sayfa header'larındaki sayaçlar — 60 saniye cache.
 * Account/Domain CRUD'da invalidate().
 */
final class StatsCache
{
    private const TTL = 60; // seconds

    public function globalStats(): array
    {
        return Cache::remember('stats:global', self::TTL, fn () => [
            'users_total' => User::count(),
            'accounts_total' => Account::count(),
            'accounts_active' => Account::where('status', 'active')->count(),
            'accounts_suspended' => Account::where('status', 'suspended')->count(),
            'domains_total' => Domain::count(),
            'databases_total' => MysqlDatabase::count(),
            'email_accounts_total' => EmailAccount::count(),
            'ftp_accounts_total' => FtpUser::count(),
            'dns_zones_total' => DnsZone::count(),
            'ssl_certs_total' => SslCertificate::count(),
            'backups_total' => Backup::count(),
            'backups_size_bytes' => (int) Backup::sum('size_bytes'),
            'cached_at' => now()->toIso8601String(),
        ]);
    }

    public function accountStats(int $accountId): array
    {
        return Cache::remember("stats:account:{$accountId}", self::TTL, fn () => [
            'domains' => Domain::where('account_id', $accountId)->count(),
            'databases' => MysqlDatabase::where('account_id', $accountId)->count(),
            'email_accounts' => EmailAccount::where('account_id', $accountId)->count(),
            'ftp_accounts' => FtpUser::where('account_id', $accountId)->count(),
            'dns_zones' => DnsZone::where('account_id', $accountId)->count(),
            'backups' => Backup::where('account_id', $accountId)->count(),
            'cached_at' => now()->toIso8601String(),
        ]);
    }

    /**
     * Hesap yaratıldığında / silindiğinde çağır.
     */
    public function invalidateGlobal(): void
    {
        Cache::forget('stats:global');
    }

    public function invalidateAccount(int $accountId): void
    {
        Cache::forget("stats:account:{$accountId}");
    }

    public function invalidateAll(): void
    {
        $this->invalidateGlobal();
        // Account spesifik cache'leri pattern-based silmek için tag kullanabiliriz
        // (Redis store ile çalışır; array store ile tag yok). Phase 1: forget global yeterli.
    }
}
