<?php
if (!defined('ABSPATH')) {
    exit;
}

class VMO_DNS_Detector {

    private static $cache = array();

    /**
     * Initialize AJAX hooks.
     */
    public static function init() {
        add_action('wp_ajax_vmo_detect_dns_host', array(__CLASS__, 'ajax_detect_dns_host'));
    }

    /**
     * AJAX Handler for DNS detection.
     */
    public static function ajax_detect_dns_host() {
        check_ajax_referer('vmo_consultation_nonce', 'security');
        
        if (!current_user_can('manage_options')) {
            wp_send_json_error(array('message' => 'Unauthorized'));
        }

        $domain = isset($_POST['domain']) ? sanitize_text_field(wp_unslash($_POST['domain'])) : '';
        if (empty($domain)) {
            $domain = parse_url(get_site_url(), PHP_URL_HOST);
        }

        $result = self::detect($domain);
        wp_send_json_success($result);
    }

    /**
     * Inspect the domain's NS records to determine the DNS host.
     *
     * @param string $domain
     * @return array{domain:string,host_type:string,nameservers:array,reason:string,detected_at:int}
     */
    public static function detect($domain) {
        $normalized = self::normalize_domain($domain);
        $result = array(
            'domain' => $normalized,
            'host_type' => $normalized ? 'unknown' : '',
            'nameservers' => array(),
            'reason' => $normalized ? 'DNS host could not be determined.' : 'Domain was not provided.',
            'detected_at' => time()
        );

        if ($normalized === '') {
            return $result;
        }

        if (isset(self::$cache[$normalized]) && (time() - self::$cache[$normalized]['detected_at'] < 300)) {
            return self::$cache[$normalized];
        }

        if (!function_exists('dns_get_record')) {
            $result['reason'] = 'dns_get_record() is not available on this host, so DNS automation readiness cannot be detected automatically.';
            return self::$cache[$normalized] = $result;
        }

        try {
            $records = dns_get_record($normalized, DNS_NS);
        } catch (\Throwable $e) {
            $result['reason'] = 'Resolving nameservers failed: ' . $e->getMessage();
            return self::$cache[$normalized] = $result;
        }

        if (!is_array($records) || empty($records)) {
            $result['reason'] = 'No nameservers were returned; DNS host may be private or misconfigured.';
            return self::$cache[$normalized] = $result;
        }

        $nameservers = array();
        $host_type = 'unknown';
        foreach ($records as $record) {
            if (empty($record['target'])) {
                continue;
            }
            $ns = strtolower(rtrim($record['target'], '.'));
            if (!$ns) {
                continue;
            }
            $nameservers[] = $ns;
            if (strpos($ns, 'cloudflare') !== false) {
                $host_type = 'cloudflare';
                break;
            }
            if (strpos($ns, 'googledomains') !== false || strpos($ns, '.google.com') !== false) {
                $host_type = 'google_cloud_dns';
                break;
            }
            if (strpos($ns, 'godaddy') !== false) {
                $host_type = 'godaddy';
                break;
            }
            if (strpos($ns, 'azure-dns') !== false) {
                $host_type = 'azure_dns';
                break;
            }
            if (strpos($ns, 'digitalocean') !== false) {
                $host_type = 'digitalocean';
                break;
            }
        }

        $nameservers = array_values(array_unique($nameservers));
        $result['nameservers'] = $nameservers;
        $result['host_type'] = $host_type;
        $result['reason'] = self::build_reason($host_type, $nameservers);
        $result['detected_at'] = time();

        self::$cache[$normalized] = $result;
        return $result;
    }

    private static function build_reason($host_type, array $nameservers) {
        if ($host_type === 'cloudflare') {
            return 'Nameservers resolve to Cloudflare. That provider blocks outside DNS automation, so the wizard must collect existing inboxes.';
        }
        if ($host_type === 'google_cloud_dns') {
            return 'Nameservers are operated by Google Domains / Cloud DNS. DNS automation must be skipped for this tenant.';
        }
        if ($host_type === 'godaddy') {
            return 'Nameservers point to GoDaddy. Auto-provisioning is unavailable because GoDaddy does not expose DNS APIs to the plugin.';
        }
        if ($host_type === 'azure_dns') {
            return 'Nameservers point to Azure DNS. Use the existing-mailbox path because DNS automation is blocked.';
        }
        if ($host_type === 'digitalocean') {
            return 'Nameservers point to DigitalOcean. Auto-DNS is unavailable, so request customer-managed inboxes.';
        }
        if (!empty($nameservers)) {
            return 'Detected nameservers: ' . implode(', ', $nameservers) . '. DNS automation is disabled; continue with manual mailbox setup.';
        }
        return 'DNS host could not be determined; default to manual mailbox capture.';
    }

    private static function normalize_domain($domain) {
        $domain = strtolower(trim((string) $domain));
        if ($domain === '') {
            return '';
        }
        $domain = preg_replace('#^https?://#', '', $domain);
        $domain = preg_replace('#^www\.#', '', $domain);
        $domain = preg_replace('#[/?#].*0', '', $domain);
        return trim($domain, '.');
    }
}

// Initialize hooks
VMO_DNS_Detector::init();
