<?php

namespace App\Console\Commands;

use Illuminate\Console\Command;
use App\Models\DnsZone;
use App\Services\PowerDNSService;

class SyncZonesToNameServers extends Command
{
    /**
     * The name and signature of the console command.
     *
     * @var string
     */
    protected $signature = 'zones:sync-to-nameservers {--zone= : Sincronizează doar o zonă specifică}';

    /**
     * The console command description.
     *
     * @var string
     */
    protected $description = 'Sincronizează zonele DNS către name servers-ii atribuiți';

    /**
     * Execute the console command.
     */
    public function handle()
    {
        $this->info('🔄 Începe sincronizarea zonelor către name servers...');
        
        // Obține zonele de sincronizat
        $query = DnsZone::with(['nameServer', 'records'])
            ->where('sync_to_powerdns', true)
            ->whereNotNull('name_server_id');
        
        if ($this->option('zone')) {
            $query->where('domain', $this->option('zone'));
        }
        
        $zones = $query->get();
        
        if ($zones->isEmpty()) {
            $this->warn('⚠️  Nu există zone de sincronizat!');
            return 0;
        }
        
        $this->info("📝 Găsite {$zones->count()} zone de sincronizat...\n");
        
        $bar = $this->output->createProgressBar($zones->count());
        $bar->start();
        
        $synced = 0;
        $errors = 0;
        
        foreach ($zones as $zone) {
            try {
                $nameServer = $zone->nameServer;
                
                if (!$nameServer) {
                    $this->newLine();
                    $this->warn("⚠️  Zona {$zone->domain} nu are name server atribuit!");
                    $bar->advance();
                    continue;
                }
                
                if (!$nameServer->is_active || $nameServer->status !== 'online') {
                    $this->newLine();
                    $this->warn("⚠️  Name server {$nameServer->name} nu este disponibil pentru {$zone->domain}!");
                    $bar->advance();
                    continue;
                }
                
                // Creează instanță PowerDNS pentru name server-ul specific
                $powerDNS = new PowerDNSService(
                    $nameServer->api_url,
                    $nameServer->api_key
                );
                
                $zoneName = $zone->domain . '.';
                
                // Verifică dacă zona există și șterge-o
                $existingZone = $powerDNS->getZone($zoneName);
                if ($existingZone && isset($existingZone['success']) && $existingZone['success']) {
                    $powerDNS->deleteZone($zoneName);
                }
                
                // Obține nameservers-ii configurați
                $nameservers = $nameServer->nameservers 
                    ? json_decode($nameServer->nameservers, true) 
                    : ['ns1.gazduiredns.ro.', 'ns2.gazduiredns.ro.'];
                
                // Creează zona
                $zoneData = [
                    'name' => $zoneName,
                    'kind' => $zone->type,
                    'nameservers' => $nameservers,
                ];
                
                $result = $powerDNS->createZone($zoneData);
                
                \Log::info('PowerDNS createZone result', [
                    'zone' => $zoneName,
                    'name_server' => $nameServer->name,
                    'result' => $result
                ]);
                
                if (!$result || !isset($result['success']) || !$result['success']) {
                    $errorMsg = 'Eroare la crearea zonei în PowerDNS';
                    if (isset($result['error'])) {
                        $errorMsg .= ': ' . $result['error'];
                    }
                    if (isset($result['status'])) {
                        $errorMsg .= ' (Status: ' . $result['status'] . ')';
                    }
                    throw new \Exception($errorMsg);
                }
                
                // Sincronizează înregistrările
                if ($zone->records->count() > 0) {
                    $groupedRecords = [];
                    
                    foreach ($zone->records as $record) {
                        $fullName = $record->name === '@' 
                            ? $zone->domain . '.' 
                            : $record->name . '.' . $zone->domain . '.';
                        
                        $key = $fullName . '|' . $record->type;
                        
                        if (!isset($groupedRecords[$key])) {
                            $groupedRecords[$key] = [
                                'name' => $fullName,
                                'type' => $record->type,
                                'ttl' => $record->ttl,
                                'records' => [],
                                'contents' => []
                            ];
                        }
                        
                        if (!in_array($record->content, $groupedRecords[$key]['contents'])) {
                            $content = $record->content;
                            
                            if ($record->type === 'MX') {
                                $priority = $record->priority ?? 10;
                                if (!str_ends_with($content, '.') && !filter_var($content, FILTER_VALIDATE_IP)) {
                                    $content .= '.';
                                }
                                $content = $priority . ' ' . $content;
                            } elseif (in_array($record->type, ['CNAME', 'NS', 'PTR', 'SRV'])) {
                                if (!str_ends_with($content, '.') && !filter_var($content, FILTER_VALIDATE_IP)) {
                                    $content .= '.';
                                }
                            }
                            
                            $groupedRecords[$key]['records'][] = [
                                'content' => $content,
                                'disabled' => false,
                            ];
                            $groupedRecords[$key]['contents'][] = $record->content;
                        }
                    }
                    
                    // Trimite înregistrările grupate
                    foreach ($groupedRecords as $rrset) {
                        $powerDNS->updateZone($zoneName, [
                            'rrsets' => [
                                [
                                    'name' => $rrset['name'],
                                    'type' => $rrset['type'],
                                    'ttl' => $rrset['ttl'],
                                    'changetype' => 'REPLACE',
                                    'records' => $rrset['records'],
                                ]
                            ]
                        ]);
                    }
                }
                
                $synced++;
                
            } catch (\Exception $e) {
                $this->newLine();
                $this->error("❌ Eroare la {$zone->domain}: {$e->getMessage()}");
                $errors++;
            }
            
            $bar->advance();
        }
        
        $bar->finish();
        
        // Rezumat
        $this->newLine(2);
        $this->info('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━');
        $this->info('📊 REZUMAT SINCRONIZARE:');
        $this->newLine();
        $this->info("  ✅ Sincronizate: {$synced}");
        if ($errors > 0) {
            $this->error("  ❌ Erori:        {$errors}");
        }
        $this->info('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━');
        
        $this->newLine();
        $this->info('✅ Sincronizare completă!');
        
        return 0;
    }
}
