"""Module for finding public toilets around given coordinates."""
import logging

from ..overpass.overpass import Overpass, get_base_info
from ..structs.toilets import Toilets
from ..utils.bbox import create_bbox


# silence the overpass logger
logging.getLogger('Overpass').setLevel(level=logging.CRITICAL)

class ToiletsManager:
    """
    Manages the process of fetching and caching toilet information from 
    OpenStreetMap (OSM) based on a specified location and radius.

    This class is responsible for:
    - Fetching toilet data from OSM using Overpass API around a given set of 
      coordinates (latitude, longitude).
    - Using a caching strategy to optimize requests by saving and retrieving 
      data from a local cache.
    - Logging important events and errors related to data fetching.

    Attributes:
        logger (logging.Logger): Logger for the class to capture events.
        location (tuple[float, float]): Latitude and longitude representing the 
            location to search around.
        radius (int): The search radius in meters for finding nearby toilets.
        overpass (Overpass): The Overpass API instance used to query OSM.
    """
    logger = logging.getLogger(__name__)

    location: tuple[float, float]
    radius: int    # radius in meters


    def __init__(self, location: tuple[float, float], radius : int) -> None:

        self.radius = radius
        self.location = location

        # Setup the caching in the Overpass class.
        self.overpass = Overpass()


    def generate_toilet_list(self) -> list[Toilets] :
        """
        Generates a list of toilet locations by fetching data from OpenStreetMap (OSM) 
        around the given coordinates stored in `self.location`.

        Returns:
        list[Toilets]: A list of `Toilets` objects containing detailed information 
                       about the toilets found around the given coordinates.
        """
        bbox = create_bbox(self.location, self.radius)
        osm_types = ['node', 'way', 'relation']
        toilets_list = []

        query = Overpass.build_query(
            bbox = bbox,
            osm_types = osm_types,
            selector = '"amenity"="toilets"',
            out = 'ids center tags'
            )
        try:
            result = self.overpass.fetch_data_from_api(query_str=query)
        except Exception as e:
            self.logger.error(f"Error fetching toilets: {e}")
            return None

        toilets_list = self.to_toilets(result)

        return toilets_list


    def to_toilets(self, elements: list) -> list[Toilets]:
        """
        Parse the Overpass API result and extract landmarks.

        This method processes the JSON elements returned by the Overpass API and 
        extracts landmarks of types 'node', 'way', and 'relation'. It retrieves 
        relevant information such as name, coordinates, and tags, and converts them 
        into Landmark objects.

        Args:
        list (osm elements): The root element of the JSON response from Overpass API.
        elem_type (str): The type of landmark (e.g., node, way, relation).

        Returns:
        list[Landmark]: A list of Landmark objects extracted from the JSON data.
        """
        if elements is None :
            return []

        toilets_list = []
        for elem in elements:
            osm_type = elem.get('type')
            # Get coordinates and append them to the points list
            _, coords = get_base_info(elem, osm_type)
            if coords is None :
                continue

            toilets = Toilets(location=coords)

            # Extract tags as a dictionary
            tags = elem.get('tags')

            if 'wheelchair' in tags.keys() and tags['wheelchair'] == 'yes':
                toilets.wheelchair = True

            if 'changing_table' in tags.keys() and tags['changing_table'] == 'yes':
                toilets.changing_table = True

            if 'fee' in tags.keys() and tags['fee'] == 'yes':
                toilets.fee = True

            if 'opening_hours' in tags.keys() :
                toilets.opening_hours = tags['opening_hours']

            toilets_list.append(toilets)

        return toilets_list
