<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;

class ResellerPlan extends Model
{
    use HasFactory;

    protected $fillable = [
        'name',
        'slug',
        'price',
        'max_clients',
        'dns_zones_per_client',
        'subdomains_per_client',
        'nameservers_per_client',
        'dns_queries_limit_per_client',
        'allowed_record_types',
        'allowed_nameservers',
        'allowed_templates',
        'is_active',
        'is_visible',
        'description',
        'dyndns_enabled',
        'dyndns_max_clients',
        'cloudflare_enabled',
        'cloudflare_max_zones',
    ];

    protected function casts(): array
    {
        return [
            'price' => 'decimal:2',
            'max_clients' => 'integer',
            'dns_zones_per_client' => 'integer',
            'subdomains_per_client' => 'integer',
            'nameservers_per_client' => 'integer',
            'dns_queries_limit_per_client' => 'integer',
            'allowed_record_types' => 'array',
            'allowed_nameservers' => 'array',
            'allowed_templates' => 'array',
            'is_active' => 'boolean',
            'is_visible' => 'boolean',
            'dyndns_enabled' => 'boolean',
            'dyndns_max_clients' => 'integer',
            'cloudflare_enabled' => 'boolean',
            'cloudflare_max_zones' => 'integer',
        ];
    }

    /**
     * Relația cu resellerii care au acest plan
     */
    public function resellers()
    {
        return $this->hasMany(User::class, 'reseller_plan_id');
    }

    /**
     * Verifică dacă planul este gratuit
     */
    public function isFree(): bool
    {
        return $this->price == 0;
    }

    /**
     * Verifică dacă planul este activ
     */
    public function isActive(): bool
    {
        return $this->is_active;
    }

    /**
     * Verifică dacă un tip de înregistrare DNS este permis
     */
    public function isRecordTypeAllowed(string $type): bool
    {
        if (empty($this->allowed_record_types)) {
            return true; // Toate tipurile sunt permise dacă nu sunt restricții
        }

        return in_array($type, $this->allowed_record_types);
    }

    /**
     * Returnează toate tipurile de înregistrări DNS permise
     */
    public function getAllowedRecordTypes(): array
    {
        if (empty($this->allowed_record_types)) {
            // Returnează toate tipurile suportate de PowerDNS
            return [
                'A', 'AAAA', 'AFSDB', 'ALIAS', 'CAA', 'CERT', 'CDNSKEY', 'CDS',
                'CNAME', 'DNSKEY', 'DNAME', 'DS', 'HINFO', 'KEY', 'LOC', 'MX',
                'NAPTR', 'NS', 'NSEC', 'NSEC3', 'NSEC3PARAM', 'OPENPGPKEY',
                'PTR', 'RP', 'RRSIG', 'SOA', 'SPF', 'SSHFP', 'SRV', 'TKEY',
                'TLSA', 'TSIG', 'TXT', 'URI'
            ];
        }

        return $this->allowed_record_types;
    }

    /**
     * Verifică dacă un name server este permis
     */
    public function isNameServerAllowed(int $nameServerId): bool
    {
        if (empty($this->allowed_nameservers)) {
            return true;
        }

        return in_array($nameServerId, $this->allowed_nameservers);
    }

    /**
     * Returnează lista de name servers permise
     */
    public function getAllowedNameServers(): array
    {
        if (empty($this->allowed_nameservers)) {
            return \App\Models\NameServer::where('is_active', true)->pluck('id')->toArray();
        }

        return $this->allowed_nameservers;
    }

    /**
     * Verifică dacă un template este permis
     */
    public function isTemplateAllowed(int $templateId): bool
    {
        if (empty($this->allowed_templates)) {
            return true;
        }

        return in_array($templateId, $this->allowed_templates);
    }

    /**
     * Returnează lista de templates permise
     */
    public function getAllowedTemplates(): array
    {
        if (empty($this->allowed_templates)) {
            return \App\Models\DnsTemplate::pluck('id')->toArray();
        }

        return $this->allowed_templates;
    }

    /**
     * Verifică dacă planul permite DynDNS
     */
    public function hasDynDns(): bool
    {
        return $this->dyndns_enabled;
    }

    /**
     * Verifică dacă un utilizator poate crea un client DynDNS
     */
    public function canCreateDynDnsClient(User $user): bool
    {
        if (!$this->dyndns_enabled) {
            return false;
        }

        $currentCount = $user->dynamicDnsClients()->count();
        return $currentCount < $this->dyndns_max_clients;
    }

    /**
     * Returnează numărul de clienți DynDNS rămași pentru utilizator
     */
    public function getRemainingDynDnsClients(User $user): int
    {
        if (!$this->dyndns_enabled) {
            return 0;
        }

        $currentCount = $user->dynamicDnsClients()->count();
        $remaining = $this->dyndns_max_clients - $currentCount;

        return max(0, $remaining);
    }

    /**
     * Verifică dacă planul permite Cloudflare
     */
    public function hasCloudflare(): bool
    {
        return $this->cloudflare_enabled;
    }

    /**
     * Verifică dacă planul permite conectarea unei noi zone la Cloudflare
     */
    public function canConnectCloudflareZone(User $user): bool
    {
        if (!$this->cloudflare_enabled) {
            return false;
        }

        // 0 înseamnă nelimitat
        if ($this->cloudflare_max_zones === 0) {
            return true;
        }

        $currentCount = \App\Models\CloudflareZone::whereHas('dnsZone', function($q) use ($user) {
            $q->where('user_id', $user->id);
        })->count();

        return $currentCount < $this->cloudflare_max_zones;
    }

    /**
     * Returnează numărul de zone Cloudflare rămase pentru utilizator
     */
    public function getRemainingCloudflareZones(User $user): int|string
    {
        if (!$this->cloudflare_enabled) {
            return 0;
        }

        if ($this->cloudflare_max_zones === 0) {
            return 'nelimitat';
        }

        $currentCount = \App\Models\CloudflareZone::whereHas('dnsZone', function($q) use ($user) {
            $q->where('user_id', $user->id);
        })->count();

        $remaining = $this->cloudflare_max_zones - $currentCount;

        return max(0, $remaining);
    }
}
