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

class Wtols_Geo_Blocking {

	private $options;

	public function __construct($options) {
		$this->options = $options;
		add_action('init', array($this, 'check_geo_block'), 1);
	}

	public function check_geo_block() {
		if (empty($this->options['enable_geo_blocking'])) {
			return;
		}

		$blocked_countries = isset($this->options['geo_blocked_countries']) ? (array)$this->options['geo_blocked_countries'] : array();
		if (empty($blocked_countries)) {
			return;
		}

		$block_type = isset($this->options['geo_block_type']) ? $this->options['geo_block_type'] : 'login'; // 'login' or 'all'
		
		$is_login_page = ( isset( $GLOBALS['pagenow'] ) && in_array( $GLOBALS['pagenow'], array( 'wp-login.php', 'wp-register.php' ) ) );

		if ($block_type === 'login' && !$is_login_page) {
			return; // Only block login page, but we are not on login page
		}

		$user_ip = $this->get_user_ip();
		if ($user_ip === '127.0.0.1' || $user_ip === '::1') {
			return; // Whitelist local
		}

		$country_code = $this->get_country_by_ip($user_ip);
		if ($country_code && in_array(strtoupper($country_code), $blocked_countries)) {
			$this->block_access();
		}
	}

	private function get_user_ip() {
		if (!empty($_SERVER['HTTP_CF_CONNECTING_IP'])) {
			return sanitize_text_field(wp_unslash($_SERVER['HTTP_CF_CONNECTING_IP']));
		} elseif (!empty($_SERVER['HTTP_CLIENT_IP'])) {
			return sanitize_text_field(wp_unslash($_SERVER['HTTP_CLIENT_IP']));
		} elseif (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) {
			return sanitize_text_field(wp_unslash($_SERVER['HTTP_X_FORWARDED_FOR']));
		} else {
			return isset($_SERVER['REMOTE_ADDR']) ? sanitize_text_field(wp_unslash($_SERVER['REMOTE_ADDR'])) : '0.0.0.0';
		}
	}

	private function get_country_by_ip($ip) {
		$transient_name = 'wtols_geo_' . md5($ip);
		$cached = get_transient($transient_name);
		if ($cached !== false) {
			return $cached;
		}

		// Use ip-api.com for lightweight resolution
		$response = wp_remote_get("http://ip-api.com/json/{$ip}?fields=countryCode");
		if (is_wp_error($response)) {
			return false;
		}

		$body = wp_remote_retrieve_body($response);
		$data = json_decode($body, true);

		if (isset($data['countryCode'])) {
			set_transient($transient_name, $data['countryCode'], 30 * DAY_IN_SECONDS);
			return $data['countryCode'];
		}

		return false;
	}

	private function block_access() {
		header('HTTP/1.1 403 Forbidden');
		header('Status: 403 Forbidden');
		$message = isset($this->options['geo_block_message']) ? $this->options['geo_block_message'] : 'Access Denied: Your country is blocked by the administrator.';
		wp_die(esc_html($message), 'Access Denied', array('response' => 403));
	}
}
