<?php
/**
 * Geolocation Service for the Simply English Assessment
 * Uses ipapi.co for country/city detection (no API key required for basic usage)
 */
class SEA_Geolocation {

    private static $instance = null;

    public static function instance() {
        if ( null === self::$instance ) {
            self::$instance = new self();
        }
        return self::$instance;
    }

    private function __construct() {}

    /**
     * Get location data for the given IP (or visitor IP if none provided)
     *
     * @param string $ip IP address to look up (optional)
     * @return array|WP_Error
     */
    public function get_location( $ip = '' ) {
        if ( empty( $ip ) ) {
            $ip = $this->get_client_ip();
        }

        $response = wp_remote_get( "https://ipapi.co/{$ip}/json/", [
            'timeout' => 5,
            'headers' => [
                'User-Agent' => 'Simply English Assessment Plugin',
            ],
        ] );

        if ( is_wp_error( $response ) ) {
            return $response;
        }

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

        if ( empty( $data ) || isset( $data['error'] ) ) {
            return new WP_Error(
                'geolocation_failed',
                __( 'Unable to retrieve location data.', 'simply-english-assessment' )
            );
        }

        return [
            'country_code'   => $data['country_code'] ?? '',
            'country_name'   => $data['country_name'] ?? '',
            'city'          => $data['city'] ?? '',
            'latitude'      => $data['latitude'] ?? '',
            'longitude'     => $data['longitude'] ?? '',
            'timezone'      => $data['timezone'] ?? '',
        ];
    }

    /**
     * Get the real client IP address, respecting common proxy headers
     *
     * @return string
     */
    private function get_client_ip() {
        $keys = [
            'HTTP_CLIENT_IP',
            'HTTP_X_FORWARDED_FOR',
            'HTTP_X_REAL_IP',
            'REMOTE_ADDR',
        ];

        foreach ( $keys as $key ) {
            if ( ! empty( $_SERVER[ $key ] ) ) {
                $ip = sanitize_text_field( $_SERVER[ $key ] );
                // In case of a comma-separated list (e.g., X-Forwarded-For), take the first IP
                $ip_parts = explode( ',', $ip );
                return trim( $ip_parts[0] );
            }
        }

        return '0.0.0.0';
    }

    /**
     * Check if the visitor is in Hong Kong or China
     *
     * @param array $location Location data from get_location()
     * @return bool
     */
    public function is_hk_or_cn( $location ) {
        $allowed_countries = [ 'HK', 'CN' ];
        return in_array( $location['country_code'], $allowed_countries );
    }

    /**
     * Get a friendly location message
     *
     * @param array $location Location data
     * @return string
     */
    public function get_location_message( $location ) {
        if ( $this->is_hk_or_cn( $location ) ) {
            return sprintf(
                __( 'You appear to be in %s, %s. Great! Our centres are available in Hong Kong and China.', 'simply-english-assessment' ),
                esc_html( $location['city'] ),
                esc_html( $location['country_name'] )
            );
        } else {
            return sprintf(
                __( 'You appear to be in %s, %s. Please note that our Simply English centres are primarily located in Hong Kong and China.', 'simply-english-assessment' ),
                esc_html( $location['city'] ),
                esc_html( $location['country_name'] )
            );
        }
    }
}