<?php

namespace Bricksforge\ConditionalLogic\Group;

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

class Location
{

    public static function build_options()
    {
        $options = [];

        // Browser Language
        $options[] = [
            'key'   => 'bricksforge_location_browser_language',
            'label' => esc_html__('Browser Language', 'bricksforge'),
            'group' => 'group_bricksforge_location',
            'compare' => [
                'type'        => 'select',
                'options'     =>  [
                    '==' => esc_html__('Is', 'bricksforge'),
                    '!=' => esc_html__('Is not', 'bricksforge'),
                ],
                'placeholder' => esc_html__('Is', 'bricksforge'),
            ],
            'value'   => [
                'label' => esc_html__('Language Code', 'bricksforge'),
                'type'        => 'text',
                'placeholder' => esc_html__('en', 'bricksforge'),
            ],
        ];

        // Website Language
        $options[] = [
            'key'   => 'bricksforge_location_current_language',
            'label' => esc_html__('Website Language', 'bricksforge'),
            'group' => 'group_bricksforge_location',
            'compare' => [
                'type'        => 'select',
                'options'     =>  [
                    '==' => esc_html__('Is', 'bricksforge'),
                    '!=' => esc_html__('Is not', 'bricksforge'),
                ],
                'placeholder' => esc_html__('Is', 'bricksforge'),
            ],
            'value'   => [
                'label' => esc_html__('Language Code', 'bricksforge'),
                'type'        => 'text',
                'placeholder' => esc_html__('en', 'bricksforge'),
            ],
        ];

        // Country
        $options[] = [
            'key'   => 'bricksforge_location_country',
            'label' => esc_html__('Country (Geolocation)', 'bricksforge'),
            'group' => 'group_bricksforge_location',
            'compare' => [
                'type'        => 'select',
                'options'     =>  [
                    '==' => esc_html__('Is', 'bricksforge'),
                    '!=' => esc_html__('Is not', 'bricksforge'),
                ],
                'placeholder' => esc_html__('Is', 'bricksforge'),
            ],
            'value'   => [
                'label' => esc_html__('Country Code', 'bricksforge'),
                'type'        => 'text',
                'placeholder' => esc_html__('en', 'bricksforge'),
            ],
        ];

        return $options;
    }

    public static function result($condition)
    {
        $result = true;

        $compare = isset($condition['compare']) ? $condition['compare'] : '==';
        $user_value = isset($condition['value']) ? \bricks_render_dynamic_data($condition['value']) : '';

        switch ($condition['key']) {
            case 'bricksforge_location_browser_language':
                $user_value = strtolower($user_value);
                $browser_language = strtolower(substr($_SERVER['HTTP_ACCEPT_LANGUAGE'], 0, 2));

                if ($compare === '==') {
                    $result = $browser_language === $user_value;
                } else {
                    $result = $browser_language !== $user_value;
                }
                break;
            case 'bricksforge_location_country':
                $user_value = strtolower($user_value);
                $country_code = self::get_country_code();

                // If country detection failed, apply fail-safe logic
                // Allow filtering to customize behavior when detection fails
                if ($country_code === false || $country_code === 'unknown') {
                    // By default, return false for safety (don't show element when detection fails)
                    // This can be overridden with the filter
                    $result = apply_filters('bricksforge/element_conditions/location/failed_detection_result', false, $condition);
                    break;
                }

                if ($compare === '==') {
                    $result = $country_code === $user_value;
                } else {
                    $result = $country_code !== $user_value;
                }
                break;
            case 'bricksforge_location_current_language':
                $user_value = strtolower($user_value);

                // Default to WordPress locale
                $current_language = \get_locale();

                // If format en_US, extract en
                if (strpos($current_language, '_') !== false) {
                    $current_language = substr($current_language, 0, strpos($current_language, '_'));
                }

                // TranslatePress
                if (class_exists('TRP_Translate_Press')) {
                    global $TRP_LANGUAGE;
                    $current_language = isset($TRP_LANGUAGE) ? $TRP_LANGUAGE : $current_language;
                }
                // WPML
                elseif (defined('ICL_LANGUAGE_CODE')) {
                    $wpml_language = apply_filters('wpml_current_language', NULL);
                    $current_language = !empty($wpml_language) ? $wpml_language : $current_language;
                }
                // Polylang
                elseif (class_exists('Polylang') && function_exists('pll_current_language')) {
                    $current_language = pll_current_language();
                }

                // Perform comparison
                $current_language = strtolower($current_language);

                if ($compare === '==') {
                    $result = $current_language === $user_value;
                } else {
                    $result = $current_language !== $user_value;
                }
                break;
            default:
                break;
        }

        return $result;
    }

    /**
     * Get country code from IP address with caching and fallback providers
     * 
     * @param string|null $ip IP address to check (null = auto-detect)
     * @param bool $deep_detect Whether to check forwarded IP headers
     * @return string|false Country code (lowercase) or false on failure
     */
    public static function get_country_code($ip = NULL, $deep_detect = TRUE)
    {
        // Get IP address
        if (filter_var($ip, FILTER_VALIDATE_IP) === FALSE) {
            $ip = $_SERVER["REMOTE_ADDR"];
            if ($deep_detect) {
                if (filter_var(@$_SERVER['HTTP_X_FORWARDED_FOR'], FILTER_VALIDATE_IP))
                    $ip = $_SERVER['HTTP_X_FORWARDED_FOR'];
                if (filter_var(@$_SERVER['HTTP_CLIENT_IP'], FILTER_VALIDATE_IP))
                    $ip = $_SERVER['HTTP_CLIENT_IP'];
            }
        }

        // Validate IP
        if (!filter_var($ip, FILTER_VALIDATE_IP)) {
            return false;
        }

        // Skip private/local IPs
        if (!filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE)) {
            return false;
        }

        // Check cache (valid for 1 hour)
        $cache_key = 'bricksforge_geo_' . md5($ip);
        $cached = get_transient($cache_key);

        if ($cached !== false) {
            return $cached === 'failed' ? false : $cached;
        }

        // Try to get country code from multiple providers
        $country_code = false;

        // Provider 1: GeoPlugin (original)
        $country_code = self::get_country_from_geoplugin($ip);

        // Provider 2: ip-api.com (fallback, free tier allows 45 req/min)
        if ($country_code === false) {
            $country_code = self::get_country_from_ipapi($ip);
        }

        // Allow filtering of the result before caching
        $country_code = apply_filters('bricksforge/element_conditions/location/country_code', $country_code, $ip);

        // Cache the result
        if ($country_code !== false) {
            set_transient($cache_key, $country_code, HOUR_IN_SECONDS);
        } else {
            // Cache failures for 5 minutes to avoid hammering failed endpoints
            set_transient($cache_key, 'failed', 5 * MINUTE_IN_SECONDS);
        }

        return $country_code;
    }

    /**
     * Get country code from GeoPlugin API
     * 
     * @param string $ip IP address
     * @return string|false Country code or false on failure
     */
    private static function get_country_from_geoplugin($ip)
    {
        $response = wp_remote_get("http://www.geoplugin.net/json.gp?ip=" . $ip, [
            'timeout' => 3,
            'sslverify' => false
        ]);

        if (is_wp_error($response)) {
            error_log('Bricksforge GeoPlugin Error: ' . $response->get_error_message());
            return false;
        }

        $body = wp_remote_retrieve_body($response);
        $data = @json_decode($body);

        if ($data && isset($data->geoplugin_countryCode) && strlen(trim($data->geoplugin_countryCode)) === 2) {
            return strtolower($data->geoplugin_countryCode);
        }

        return false;
    }

    /**
     * Get country code from ip-api.com (fallback provider)
     * 
     * @param string $ip IP address
     * @return string|false Country code or false on failure
     */
    private static function get_country_from_ipapi($ip)
    {
        $response = wp_remote_get("http://ip-api.com/json/{$ip}?fields=status,countryCode", [
            'timeout' => 3,
            'sslverify' => false
        ]);

        if (is_wp_error($response)) {
            error_log('Bricksforge ip-api Error: ' . $response->get_error_message());
            return false;
        }

        $body = wp_remote_retrieve_body($response);
        $data = @json_decode($body);

        if ($data && isset($data->status) && $data->status === 'success' && isset($data->countryCode)) {
            return strtolower($data->countryCode);
        }

        return false;
    }
}
