import simplekml
import requests
import base64

from urllib.parse import urlparse


class Picarta:
    def __init__(self, api_token, url="https://picarta.ai/classify", top_k=10):
        self.api_token = api_token
        self.url = url
        self.top_k = top_k
        self.headers = {"Content-Type": "application/json"}

    def is_valid_url(self, input_str):
        try:
            result = urlparse(input_str)
            return all([result.scheme, result.netloc])
        except ValueError:
            return False

    def read_image(self, image_path):
        with open(image_path, "rb") as image_file:
            return base64.b64encode(image_file.read()).decode("utf-8")

    def _create_kml(self, gps_bbox):
        """Generate a KML file from the bounding box coordinates."""
        if not gps_bbox or "bbox" not in gps_bbox:
            raise ValueError("Invalid bbox format in the response.")

        bbox = gps_bbox["bbox"]
        coordinates = [
            (bbox["top_left"]["lon"], bbox["top_left"]["lat"]),
            (bbox["top_right"]["lon"], bbox["top_right"]["lat"]),
            (bbox["bottom_right"]["lon"], bbox["bottom_right"]["lat"]),
            (bbox["bottom_left"]["lon"], bbox["bottom_left"]["lat"]),
            (bbox["top_left"]["lon"], bbox["top_left"]["lat"]),  # Closing the loop
        ]

        # Create KML file
        kml = simplekml.Kml()
        kml.newpolygon(name="Bounding Box", outerboundaryis=coordinates).style.polystyle.color = "40FFFFFF"  # 25% opacity white
        kml.newpolygon(name="Bounding Box", outerboundaryis=coordinates).style.linestyle.color = "FFFFFFFF"  # White outline
        kml.newpolygon(name="Bounding Box", outerboundaryis=coordinates).style.linestyle.width = 2

        # Add center point
        center = gps_bbox.get("center", {})
        if center:
            kml.newpoint(coords=[(center["lon"], center["lat"])])

        return kml

    def localize(
        self,
        img_path,
        top_k=None,
        center_latitude=None,
        center_longitude=None,
        radius=None,
        aerial_image=False,
        camera_altitude=None,
    ):
        if self.is_valid_url(img_path):
            image_data = img_path
        else:
            image_data = self.read_image(img_path)

        payload = {
            "TOKEN": self.api_token,
            "IMAGE": image_data,
            "Center_LATITUDE": center_latitude,
            "Center_LONGITUDE": center_longitude,
            "RADIUS": radius,
        }

        if aerial_image:
            payload["CAMERA_ALTITUDE"] = camera_altitude
        else:
            payload["TOP_K"] = top_k if top_k is not None else self.top_k

        response = requests.post(self.url, headers=self.headers, json=payload)

        if response.status_code == 200:
            json_response = response.json()

            if aerial_image==False:
                return json_response
            elif aerial_image==True:
                kml_file = self._create_kml(json_response)
                return json_response, kml_file
        else:
            response.raise_for_status()
