<?php

namespace App\Console\Commands;

use App\Core\Registrar\RegistrarManager;
use App\Models\Tld;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\Log;

class SyncTldsFromRegistrarCommand extends Command
{
    /**
     * The name and signature of the console command.
     *
     * @var string
     */
    protected $signature = 'tlds:sync-from-registrar
                            {--registrar= : Sync from a specific registrar only}
                            {--dry-run : Show changes without applying them}';

    /**
     * The console command description.
     *
     * @var string
     */
    protected $description = 'Sync TLD grace/redemption periods and fees from registrar modules';

    /**
     * Execute the console command.
     */
    public function handle(RegistrarManager $registrarManager): int
    {
        $this->info('Starting TLD sync from registrars...');
        $dryRun = $this->option('dry-run');

        if ($dryRun) {
            $this->warn('DRY RUN MODE - No changes will be saved');
        }

        $specificRegistrar = $this->option('registrar');
        $modules = $registrarManager->getAll();
        $totalSynced = 0;
        $totalUpdated = 0;
        $totalErrors = 0;

        if (empty($modules)) {
            $this->warn('No registrar modules found.');

            return Command::SUCCESS;
        }

        foreach ($modules as $name => $module) {
            // Filter by specific registrar if provided
            if ($specificRegistrar && strtolower($name) !== strtolower($specificRegistrar)) {
                continue;
            }

            if (! $module->isActive()) {
                $this->line("Skipping inactive registrar: {$name}");

                continue;
            }

            $this->info("Syncing TLDs from registrar: {$name}");

            try {
                $result = $module->getDomainPricings([]);

                if (! isset($result['status']) || $result['status'] !== 'success') {
                    $errorMsg = $result['message'] ?? 'Unknown error';
                    $this->warn("  Failed to fetch pricings from {$name}: {$errorMsg}");
                    $totalErrors++;

                    continue;
                }

                $pricings = $result['data']['pricings'] ?? [];

                if (empty($pricings)) {
                    $this->line("  No pricings returned from {$name}");

                    continue;
                }

                foreach ($pricings as $tldName => $pricing) {
                    $tldRecord = Tld::where('tld', $tldName)
                        ->orWhere('tld', '.' . $tldName)
                        ->first();

                    if (! $tldRecord) {
                        continue;
                    }

                    $totalSynced++;

                    // Check for lifecycle-related fields
                    $changes = [];

                    if (isset($pricing['grace_period']) && $pricing['grace_period'] != $tldRecord->grace_period) {
                        $changes['grace_period'] = [
                            'old' => $tldRecord->grace_period,
                            'new' => $pricing['grace_period'],
                        ];
                    }

                    if (isset($pricing['grace_period_fee']) && $pricing['grace_period_fee'] != $tldRecord->grace_period_fee) {
                        $changes['grace_period_fee'] = [
                            'old' => $tldRecord->grace_period_fee,
                            'new' => $pricing['grace_period_fee'],
                        ];
                    }

                    if (isset($pricing['redemption_period']) && $pricing['redemption_period'] != $tldRecord->redemption_period) {
                        $changes['redemption_period'] = [
                            'old' => $tldRecord->redemption_period,
                            'new' => $pricing['redemption_period'],
                        ];
                    }

                    if (isset($pricing['redemption_period_fee']) && $pricing['redemption_period_fee'] != $tldRecord->redemption_period_fee) {
                        $changes['redemption_period_fee'] = [
                            'old' => $tldRecord->redemption_period_fee,
                            'new' => $pricing['redemption_period_fee'],
                        ];
                    }

                    if (empty($changes)) {
                        continue;
                    }

                    $totalUpdated++;

                    if ($dryRun) {
                        $this->line("  Would update {$tldRecord->tld}:");
                        foreach ($changes as $field => $values) {
                            $this->line("    {$field}: {$values['old']} -> {$values['new']}");
                        }
                    } else {
                        $updateData = [];
                        foreach ($changes as $field => $values) {
                            $updateData[$field] = $values['new'];
                        }

                        $tldRecord->update($updateData);

                        $this->line("  Updated {$tldRecord->tld}:");
                        foreach ($changes as $field => $values) {
                            $this->line("    {$field}: {$values['old']} -> {$values['new']}");
                        }

                        Log::info('TLD sync: updated lifecycle fields', [
                            'tld' => $tldRecord->tld,
                            'registrar' => $name,
                            'changes' => $changes,
                        ]);
                    }
                }
            } catch (\Exception $e) {
                $this->error("  Error syncing from {$name}: {$e->getMessage()}");
                $totalErrors++;

                Log::error('TLD sync: registrar fetch failed', [
                    'registrar' => $name,
                    'error' => $e->getMessage(),
                ]);
            }
        }

        $this->newLine();
        $this->info('TLD sync completed:');
        $this->info("  TLDs checked: {$totalSynced}");
        $this->info("  TLDs updated: {$totalUpdated}");

        if ($totalErrors > 0) {
            $this->warn("  Errors: {$totalErrors}");
        }

        return Command::SUCCESS;
    }
}
