<?php
/**
 * GeoIP Handler for Foxblock
 * Supports MaxMind GeoLite2 database with API fallback
 */

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

class Foxblock_GeoIP
{
    private static $db_path = null;
    private static $reader = null;

    /**
     * Initialize GeoIP database path
     */
    public static function init()
    {
        self::$db_path = FOXBLOCK_PLUGIN_DIR . 'includes/GeoIP/GeoLite2-Country.mmdb';
    }

    /**
     * Get country code from IP address
     * 
     * @param string $ip IP address
     * @return string Country code (2 letters) or empty string
     */
    public static function get_country_code($ip)
    {
        // Check cache first
        $cache_key = 'foxblock_cc_' . md5($ip);
        $cached = get_transient($cache_key);
        
        if ($cached !== false) {
            return $cached;
        }

        $country_code = '';

        // Try local database first
        if (self::has_database()) {
            $country_code = self::lookup_local($ip);
        }

        // Fallback to API if local lookup failed
        if (empty($country_code)) {
            $country_code = self::lookup_api($ip);
        }

        // Cache result for 30 days
        if (!empty($country_code)) {
            set_transient($cache_key, $country_code, 30 * DAY_IN_SECONDS);
        }

        return $country_code;
    }

    /**
     * Check if GeoIP database exists
     * 
     * @return bool
     */
    public static function has_database()
    {
        return file_exists(self::$db_path);
    }

    /**
     * Lookup IP using local MaxMind database
     * 
     * @param string $ip IP address
     * @return string Country code or empty string
     */
    private static function lookup_local($ip)
    {
        try {
            // Check if GeoIP2 library is available (via Composer)
            if (class_exists('GeoIp2\Database\Reader')) {
                return self::lookup_with_geoip2($ip);
            }
            
            // Fallback: Try to use PHP's built-in geoip functions if available
            if (function_exists('geoip_country_code_by_name')) {
                $code = @geoip_country_code_by_name($ip);
                if ($code && strlen($code) === 2) {
                    return $code;
                }
            }
            
            // If no library available, return empty to use API fallback
            return '';
            
        } catch (Exception $e) {
            return '';
        }
    }

    /**
     * Lookup using GeoIP2 PHP library
     * 
     * @param string $ip IP address
     * @return string Country code or empty string
     */
    private static function lookup_with_geoip2($ip)
    {
        try {
            $reader = new \GeoIp2\Database\Reader(self::$db_path);
            $record = $reader->country($ip);
            $country_code = $record->country->isoCode;
            
            if ($country_code && strlen($country_code) === 2) {
                return $country_code;
            }
            
            return '';
        } catch (Exception $e) {
            return '';
        }
    }

    /**
     * Lookup IP using external API (fallback)
     * 
     * @param string $ip IP address
     * @return string Country code or empty string
     */
    private static function lookup_api($ip)
    {
        // Try ip-api.com first (free, no key required)
        $response = wp_remote_get('http://ip-api.com/json/' . $ip . '?fields=countryCode', array(
            'timeout' => 3,
        ));

        if (!is_wp_error($response)) {
            $body = wp_remote_retrieve_body($response);
            $data = json_decode($body, true);

            if (isset($data['countryCode'])) {
                return sanitize_text_field($data['countryCode']);
            }
        }

        // Fallback to ipapi.co (backup API)
        $response2 = wp_remote_get('https://ipapi.co/' . $ip . '/country/', array(
            'timeout' => 3,
        ));

        if (!is_wp_error($response2)) {
            $body = wp_remote_retrieve_body($response2);
            $country_code = trim($body);
            
            if (strlen($country_code) === 2 && ctype_alpha($country_code)) {
                return sanitize_text_field(strtoupper($country_code));
            }
        }

        return '';
    }

    /**
     * Get database info
     * 
     * @return array Database information
     */
    public static function get_database_info()
    {
        $info = array(
            'exists' => self::has_database(),
            'path' => self::$db_path,
            'size' => 0,
            'modified' => '',
        );

        if ($info['exists']) {
            $info['size'] = filesize(self::$db_path);
            $info['modified'] = date('Y-m-d H:i:s', filemtime(self::$db_path));
        }

        return $info;
    }

    /**
     * Download GeoLite2 database
     * Note: Requires MaxMind license key (free)
     * 
     * @param string $license_key MaxMind license key
     * @return array Result with success status and message
     */
    public static function download_database($license_key = '')
    {
        if (empty($license_key)) {
            return array(
                'success' => false,
                'message' => 'License key required. Get free key at https://www.maxmind.com/en/geolite2/signup'
            );
        }

        $download_url = 'https://download.maxmind.com/app/geoip_download?edition_id=GeoLite2-Country&license_key=' . $license_key . '&suffix=tar.gz';
        
        $temp_file = download_url($download_url);

        if (is_wp_error($temp_file)) {
            return array(
                'success' => false,
                'message' => 'Download failed: ' . $temp_file->get_error_message()
            );
        }

        // Extract and move database file
        // This requires additional implementation for tar.gz extraction
        
        return array(
            'success' => false,
            'message' => 'Manual installation required. Download from MaxMind and upload to: ' . self::$db_path
        );
    }
}

// Initialize on load
Foxblock_GeoIP::init();
