"""
GeoIP middleware to restrict access to Saudi Arabia only.
Uses IP-based country detection.
"""
import requests
from flask import request, redirect, url_for, session
from functools import wraps


def get_country_from_ip(ip_address):
    """
    Get country code from IP address using multiple free APIs.
    Returns 'SA' for Saudi Arabia, or other country codes.
    Returns None if detection fails.
    """
    # Don't check localhost IPs
    if ip_address in ['127.0.0.1', 'localhost', '::1'] or ip_address.startswith('192.168.') or ip_address.startswith('10.'):
        return 'SA'  # Allow localhost for development

    # Try multiple APIs in order
    apis = [
        f'https://ipapi.co/{ip_address}/country/',
        f'http://ip-api.com/json/{ip_address}',
        f'https://api.ipify.org?format=json',  # Just to test connectivity
    ]

    for api_url in apis:
        try:
            response = requests.get(api_url, timeout=3)
            if response.status_code == 200:
                # ipapi.co returns plain text country code
                if 'ipapi.co' in api_url:
                    return response.text.strip().upper()
                # ip-api.com returns JSON
                elif 'ip-api.com' in api_url:
                    data = response.json()
                    if data.get('status') == 'success':
                        return data.get('countryCode', '').upper()
        except Exception as e:
            print(f"GeoIP lookup failed for {ip_address} using {api_url}: {e}")
            continue

    return None


def is_saudi_arabia_allowed():
    """
    Check if Saudi Arabia-only restriction is enabled.
    Returns True if restriction is disabled, or if user IP is from Saudi Arabia.
    """
    from app.models.features import SystemSetting

    # Check if geographic restriction is enabled
    geo_restriction = SystemSetting.get("saudi_only_access", default=False)
    if not geo_restriction:
        return True  # Restriction disabled, allow everyone

    # Check if user has already been verified
    if session.get('country_verified') == 'SA':
        return True

    # Get user IP - handle various proxy headers
    user_ip = None
    for header in ['X-Forwarded-For', 'X-Real-IP', 'CF-Connecting-IP', 'True-Client-IP']:
        ip = request.headers.get(header)
        if ip:
            user_ip = ip
            break

    if not user_ip:
        user_ip = request.remote_addr

    # Handle multiple IPs in X-Forwarded-For
    if ',' in str(user_ip):
        user_ip = str(user_ip).split(',')[0].strip()

    print(f"GeoIP Check: IP={user_ip}, Headers={dict(request.headers)}")  # Debug logging

    # Check country
    country = get_country_from_ip(user_ip)
    print(f"Detected country: {country}")  # Debug logging

    # Allow ONLY if country is Saudi Arabia
    if country == 'SA':
        session['country_verified'] = 'SA'  # Cache the verification
        return True

    # Block all other countries (no fail-open)
    return False


def require_saudi_arabia(f):
    """
    Decorator to restrict access to Saudi Arabia only.
    Apply to routes or use as middleware.
    """
    @wraps(f)
    def decorated_function(*args, **kwargs):
        if not is_saudi_arabia_allowed():
            from flask import render_template
            return render_template('errors/geoblocked.html'), 403
        return f(*args, **kwargs)
    return decorated_function
