<?php

namespace App\Console\Commands;

use Illuminate\Console\Command;
use App\Models\DnsZone;
use App\Models\NameServer;

class AssignNameServersToZones extends Command
{
    /**
     * The name and signature of the console command.
     *
     * @var string
     */
    protected $signature = 'zones:assign-nameservers {--force : Forțează reatribuirea pentru toate zonele}';

    /**
     * The console command description.
     *
     * @var string
     */
    protected $description = 'Atribuie automat name servers la zonele DNS care nu au unul atribuit';

    /**
     * Execute the console command.
     */
    public function handle()
    {
        $this->info('🔍 Începe atribuirea name servers la zone DNS...');
        
        // Obține toate name servers-urile active, ordonate după prioritate
        $nameServers = NameServer::active()->orderBy('priority')->get();
        
        if ($nameServers->isEmpty()) {
            $this->error('❌ Nu există name servers active în sistem!');
            return 1;
        }
        
        $this->info("📊 Găsite {$nameServers->count()} name servers active:");
        foreach ($nameServers as $ns) {
            $this->line("  - {$ns->name} (Prioritate: {$ns->priority}, Status: {$ns->status})");
        }
        
        // Obține zonele fără name server atribuit
        $query = DnsZone::query();
        
        if ($this->option('force')) {
            $zones = $query->get();
            $this->warn("⚠️  Mod FORCE activat - se vor reatribui TOATE zonele!");
        } else {
            $zones = $query->whereNull('name_server_id')->get();
        }
        
        if ($zones->isEmpty()) {
            $this->info('✅ Toate zonele au deja un name server atribuit!');
            return 0;
        }
        
        $this->info("\n📝 Găsite {$zones->count()} zone de procesat...\n");
        
        $bar = $this->output->createProgressBar($zones->count());
        $bar->start();
        
        $assigned = 0;
        $skipped = 0;
        $errors = 0;
        
        // Distribuie zonele uniform între name servers
        $nameServerIndex = 0;
        $nameServerCount = $nameServers->count();
        
        foreach ($zones as $zone) {
            try {
                // Verifică permisiunile planului utilizatorului
                $user = $zone->user;
                $plan = $user->plan ?? $user->resellerPlan;
                
                // Obține name servers-ii permisi pentru acest utilizator
                $allowedNameServers = [];
                if ($plan) {
                    $allowedNameServers = $plan->getAllowedNameServers();
                }
                
                // Filtrează name servers-ii disponibili
                $availableNameServers = $nameServers;
                if (!empty($allowedNameServers)) {
                    $availableNameServers = $nameServers->whereIn('id', $allowedNameServers);
                }
                
                if ($availableNameServers->isEmpty()) {
                    $this->newLine();
                    $this->warn("⚠️  Zona {$zone->domain} - utilizatorul nu are name servers permise în plan!");
                    $skipped++;
                    $bar->advance();
                    continue;
                }
                
                // Selectează name server folosind round-robin
                $nameServer = $availableNameServers->values()[$nameServerIndex % $availableNameServers->count()];
                
                // Atribuie nume server-ul
                $zone->name_server_id = $nameServer->id;
                $zone->save();
                
                $assigned++;
                $nameServerIndex++;
                
            } catch (\Exception $e) {
                $this->newLine();
                $this->error("❌ Eroare la zona {$zone->domain}: {$e->getMessage()}");
                $errors++;
            }
            
            $bar->advance();
        }
        
        $bar->finish();
        
        // Afișează rezumatul
        $this->newLine(2);
        $this->info('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━');
        $this->info('📊 REZUMAT ATRIBUIRE:');
        $this->newLine();
        $this->info("  ✅ Atribuite:  {$assigned}");
        if ($skipped > 0) {
            $this->warn("  ⚠️  Sărite:     {$skipped}");
        }
        if ($errors > 0) {
            $this->error("  ❌ Erori:      {$errors}");
        }
        $this->info('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━');
        
        // Afișează distribuția pe name servers
        $this->newLine();
        $this->info('📈 DISTRIBUȚIE PE NAME SERVERS:');
        foreach ($nameServers as $ns) {
            $count = DnsZone::where('name_server_id', $ns->id)->count();
            $this->line("  - {$ns->name}: {$count} zone");
        }
        
        $this->newLine();
        $this->info('✅ Atribuire completă!');
        
        return 0;
    }
}
