<?php

namespace App\Console\Commands;

use App\Models\DnsRecord;
use App\Models\Instance;
use App\Models\MonitoringTarget;
use App\Support\ProvisioningSettings;
use Illuminate\Console\Command;

/**
 * What changing the instance zone would touch, before anything is touched.
 *
 * The zone is one setting, and changing it silently re-addresses every
 * instance: `subdomain` holds only the label, and every caller composes
 * `label.zone` at read time. So the moment the setting changes, the console,
 * the portal, the acceptance checks and the mails all name an address that
 * does not resolve — while the DNS records, the certificates and Nextcloud's
 * trusted_domains still hold the old one.
 *
 * Harmless with no instances, which is exactly why it is worth doing now. This
 * says which it is.
 */
class CheckDnsZone extends Command
{
    protected $signature = 'clupilot:check-zone {zone? : the zone you are considering}';

    protected $description = 'Report what a change of the instance DNS zone would affect';

    public function handle(): int
    {
        $current = ProvisioningSettings::dnsZone();
        $target = (string) ($this->argument('zone') ?? '');

        $this->line('');
        $this->line("  Current zone:  <options=bold>{$current}</>");
        $this->line('  Proposed zone: '.($target !== '' ? "<options=bold>{$target}</>" : '<comment>none given</comment>'));
        $this->line('');

        $instances = Instance::query()
            ->whereIn('status', ['active', 'provisioning', 'cancellation_scheduled'])
            ->get();

        if ($instances->isEmpty()) {
            $this->info('  No instances in service. The zone can be changed with nothing to migrate.');
            $this->line('');

            return self::SUCCESS;
        }

        $this->warn("  {$instances->count()} instance(s) are addressed under the current zone.");
        $this->line('');
        $this->line('  Each of these carries the old name in places this setting does NOT reach:');
        $this->line('');

        $records = DnsRecord::query()->whereIn('instance_id', $instances->pluck('id'))->count();
        $targets = MonitoringTarget::query()->whereIn('instance_id', $instances->pluck('id'))->count();
        $verified = $instances->filter(fn (Instance $i) => $i->domainIsVerified())->count();

        $this->table(['What', 'Count', 'Consequence of changing the zone'], [
            ['DNS records (dns_records.fqdn)', $records, 'still point the OLD name at the host'],
            ['Monitoring targets', $targets, 'keep watching the old URL and report down'],
            ['TLS certificates', $instances->count(), 'issued for the old name; the new one has none'],
            ['Nextcloud trusted_domains', $instances->count(), 'rejects the new name until rewritten'],
            ['Instances on their own domain', $verified, 'unaffected — they are served at custom_domain'],
        ]);

        $this->line('');
        $this->line('  A change now is a migration with an outage, not a setting. Either do it');
        $this->line('  before the first customer, or plan it as a maintenance window.');
        $this->line('');

        return self::SUCCESS;
    }
}
