"""Main app methods."""
import logging

from django.conf import settings
from django.contrib.gis.geoip2 import GeoIP2, GeoIP2Exception
from geoip2.models import City

from typing import Union, Tuple, Optional
import pycountry

from main import models

logger = logging.getLogger(__name__)


def site_url(schema, subdomain, domain):
    return f'{schema}://{subdomain}.{domain}'


def get_user_ip(request):
    """Get user ip from request."""
    META = request.META
    x_forwarded_for = META.get('HTTP_X_FORWARDED_FOR')
    if x_forwarded_for:
        ip = x_forwarded_for.split(',')[0]
    else:
        ip = META.get('REMOTE_ADDR')
    return ip


def determine_country_code(request):
    """Determine country code."""
    META = request.META
    country_code = META.get('X-GeoIP-Country-Code',
                            META.get('HTTP_X_GEOIP_COUNTRY_CODE'))
    if isinstance(country_code, str):
        return country_code.lower()


def determine_country_name(request):
    """Determine country name."""
    META = request.META
    return  META.get('X-GeoIP-Country-Name',
                     META.get('HTTP_X_GEOIP_COUNTRY_NAME'))


def determine_coordinates(request):
    META = request.META
    longitude = META.get('X-GeoIP-Longitude',
                         META.get('HTTP_X_GEOIP_LONGITUDE'))
    latitude = META.get('X-GeoIP-Latitude',
                        META.get('HTTP_X_GEOIP_LATITUDE'))
    try:
        return float(longitude), float(latitude)
    except (TypeError, ValueError):
        return None, None


def determine_user_site_url(country_code):
    """Determine user's site url."""
    try:
        if country_code is None:
            raise ValueError
        # search localized site
        site = models.SiteSettings.objects.filter(
            country__code=country_code).first()
        # search default site
        if not site:
            site = models.SiteSettings.objects.filter(default_site=True).first()
            if not site:
                raise ValueError
    except Exception:
        return site_url(schema=settings.SCHEMA_URI,
                        subdomain=settings.DEFAULT_SUBDOMAIN,
                        domain=settings.SITE_DOMAIN_URI)
    else:
        return site.site_url


def determine_user_city(request):
    META = request.META
    city = META.get('X-GeoIP-City',
                    META.get('HTTP_X_GEOIP_CITY'))
    return city


def determine_subdivision(
        country_alpha2_code: str,
        subdivision_code: Union[str, int]
) -> pycountry.Subdivision:
    """
    :param country_alpha2_code:  country code according to ISO 3166-1 alpha-2 standard
    :param subdivision_code: subdivision code according to ISO 3166-2 without country code prefix
    :return: subdivision
    """
    iso3166_2_subdivision_code = f'{country_alpha2_code}-{subdivision_code}'
    return pycountry.subdivisions.get(code=iso3166_2_subdivision_code)
