import ipaddress

from .exceptions import ValidationError


class LocationSlug(object):
    def __init__(self, slug):
        if not isinstance(slug, str) or not slug:
            raise ValidationError("slug must be a non-empty string")
        self.slug = slug


class LocationCoords(object):
    def __init__(self, lat, lon):
        try:
            lat_val = float(lat)
            lon_val = float(lon)
        except (TypeError, ValueError):
            raise ValidationError("lat and lon must be numbers")
        if lat_val < -90 or lat_val > 90:
            raise ValidationError("lat must be between -90 and 90")
        if lon_val < -180 or lon_val > 180:
            raise ValidationError("lon must be between -180 and 180")
        self.lat = lat_val
        self.lon = lon_val


class LocationIP(object):
    def __init__(self, ip):
        if not isinstance(ip, str) or not ip:
            raise ValidationError("ip must be a non-empty string")
        try:
            ipaddress.ip_address(ip)
        except ValueError:
            raise ValidationError("ip must be a valid IPv4 or IPv6 string")
        self.ip = ip


def location_to_params(location):
    if isinstance(location, LocationSlug):
        return {"slug": location.slug}
    if isinstance(location, LocationCoords):
        return {"lat": location.lat, "lon": location.lon}
    if isinstance(location, LocationIP):
        return {"ip": location.ip}
    raise ValidationError("location must be LocationSlug, LocationCoords, or LocationIP")
