<?php

if (!defined('ABSPATH')) {
    exit;
}

/**
 * Domain allow-list checking for Gocars Online updates.
 *
 * Uses a JSON file in the GitHub repo:
 *   https://raw.githubusercontent.com/go-creations/gocars-online/main/domains.json
 *
 * Structure:
 * [
 *   "client1.com",
 *   "*.gocreations.info",
 *   "specific.client.gr"
 * ]
 */

/**
 * Get the current site's host (domain).
 *
 * @return string|null
 */
function gocars_get_current_domain() {
    $home_url = home_url();
    $host = wp_parse_url($home_url, PHP_URL_HOST);
    return $host ?: null;
}

/**
 * Fetch and parse the allowed domains JSON file from GitHub.
 *
 * @param GocarsConfig $config
 * @param bool $force_refresh Whether to bypass cache and fetch fresh data
 * @return array List of allowed domains (strings). Empty array on error.
 */
function gocars_fetch_allowed_domains(GocarsConfig $config, $force_refresh = false) {
    // Require GitHub token to fetch from private repo.
    if (!$config->has('AUTH_TOKEN_GITHUB')) {
        return array();
    }

    $cache_key = 'gocars_allowed_domains_cache';
    
    // Use cache unless force refresh is requested
    if (!$force_refresh) {
        $cached = get_transient($cache_key);
        if ($cached !== false) { // allow empty array cache too
            return is_array($cached) ? $cached : array();
        }
    }

    $url = 'https://raw.githubusercontent.com/go-creations/gocars-config/main/domains.json';

    $response = wp_remote_get($url, array(
        'headers' => array(
            'Authorization' => 'token ' . $config->get('AUTH_TOKEN_GITHUB'),
            'User-Agent'    => 'Gocars-Online-Plugin',
        ),
        'timeout' => 10,
    ));

    if (is_wp_error($response)) {
        error_log('Gocars: Error fetching domains.json - ' . $response->get_error_message());
        return array();
    }

    $code = wp_remote_retrieve_response_code($response);
    if ($code !== 200) {
        error_log('Gocars: Error fetching domains.json - HTTP ' . $code);
        return array();
    }

    $body = wp_remote_retrieve_body($response);
    if (empty($body)) {
        error_log('Gocars: domains.json is empty');
        return array();
    }

    $data = json_decode($body, true);
    if (!is_array($data)) {
        error_log('Gocars: domains.json is not valid JSON');
        return array();
    }

    // Parse the correct JSON structure: {"allowed": [...]}
    if (!isset($data) || !is_array($data)) {
        error_log('Gocars: domains.json array');
        return array();
    }

    // Normalize domains: trim, lowercase, remove empty.
    $allowed = array();
    foreach ($data as $domain) {
        $domain = trim(strtolower((string) $domain));
        $domain = preg_replace('/^www\./', '', $domain); // Remove www prefix
        if ($domain !== '') {
            $allowed[] = $domain;
        }
    }
    
    $allowed = array_unique($allowed);
    set_transient($cache_key, $allowed, 6 * HOUR_IN_SECONDS);

    return $allowed;
}

/**
 * Check if a domain matches an allowed pattern.
 * Supports wildcards like *.gocreations.info
 *
 * @param string $domain        Current domain to check
 * @param string $pattern       Pattern from allow-list (may contain *)
 * @return bool
 */
function gocars_domain_matches_pattern($domain, $pattern) {
    
    // Exact match
    if ($domain === $pattern) {
        return true;
    }
    
    // Wildcard match: *.example.com
    if (strpos($pattern, '*') !== false) {
        // Convert wildcard pattern to regex
        // Escape dots, then replace * with regex equivalent
        $regex = preg_quote($pattern, '/');           // Escape everything
        $regex = str_replace('\*', '[^.]+', $regex);  // Replace escaped * with one subdomain segment
        $regex = '/^' . $regex . '$/i';               // Wrap as full match, case-insensitive
        
        if (preg_match($regex, $domain)) {
            return true;
        }
    }
    
    return false;
}

/**
 * Get detailed domain authorization status.
 *
 * @param GocarsConfig $config
 * @param bool $force_refresh Whether to bypass cache and fetch fresh data
 * @return array Status array with 'status' and 'domain' keys
 */
function gocars_domain_is_allowed(GocarsConfig $config, $force_refresh = false) {
    
    $current_domain = gocars_get_current_domain();
    if (empty($current_domain)) {
        return false;
    }

    $current_domain = preg_replace('/^www\./', '', strtolower($current_domain));

    $allowed_domains = gocars_fetch_allowed_domains($config, $force_refresh);
    if (empty($allowed_domains)) {
        // Strict mode: no data -> not allowed.
        return false;
    }

    // Check each pattern in the allow-list
    foreach ($allowed_domains as $pattern) {
        if (gocars_domain_matches_pattern($current_domain, $pattern)) {
            return true;
        }
    }
    
    return false;
}
