import pandas as pd
from .geographic_handling import create_wkt_geo_point

def _check_tags(tags):
    if tags is None:
        raise ValueError("Tags not specified")

def collect_points_of_interest_in_overpass_geometry(request_session, overpass_geometry, tags, poi_types, **kwargs):
    overpass_url = "http://overpass-api.de/api/interpreter"
    _check_tags(tags)
    tags = [t.strip().lower() for t in tags]
    tags = [t for t in tags if len(t) > 0]
    tags = set(tags) # deduplicate
    overpass_query = "[out:json];("
    
    if len(tags) > 0:
        
        for t in tags:
            if "node" in poi_types :
                overpass_query += 'node'+'['+t+']'+overpass_geometry+';'
            if "way" in poi_types:
                overpass_query +='way'+'['+t+']'+overpass_geometry+';'
        overpass_query = overpass_query+')'+';out center;'
    
    else:
        overpass_query = overpass_query[:-1]+overpass_geometry+';out center;'

    response = request_session.post(overpass_url, data=overpass_query)
    response_status_code = response.status_code
    
    try:
        data = response.json()
        
    except Exception as e :
        log_message = "Exception met ! | Query response status code was : '{}' | Exceptions args are : '{}' | "\
        .format(response_status_code, e.args)
        
        for key, value in kwargs.items():
            log_message+="{} : {} | ".format(key, value)
        
        log_message+= "output response will be empty"
        print(log_message)
        data = {}
        
    return data, response_status_code

def from_poi_collection_to_pandas(poi_collection, poi_belonging_location, points_of_interest_schema):
    poi_collection_nodes = []
    poi_collection_ways = []

    for poi in poi_collection :
        if poi['type'] == 'node':
            poi_collection_nodes.append(poi)
        elif poi['type'] == 'way':
            poi_collection_ways.append(poi)

    #POIs nodes management :
    df_poi_collection_nodes = pd.DataFrame(poi_collection_nodes)
    some_nodes_collected = (len(df_poi_collection_nodes)>0)

    if not some_nodes_collected:
        df_poi_collection_nodes = pd.DataFrame(columns=points_of_interest_schema)
        df_poi_collection_nodes["poi_geo_point"] = ""

    else:
        nodes_geo_points = []
        for latitude, longitude in \
        zip(df_poi_collection_nodes["lat"], df_poi_collection_nodes["lon"]):
            if not pd.isnull(latitude):
                nodes_geo_points.append(create_wkt_geo_point(longitude, latitude))
            else:
                nodes_geo_points.append(None)
        df_poi_collection_nodes["poi_geo_point"] = nodes_geo_points

    #POIs ways management :
    df_poi_collection_ways = pd.DataFrame(poi_collection_ways)
    some_ways_collected = (len(df_poi_collection_ways)>0)
    if not some_ways_collected:
        df_poi_collection_ways = pd.DataFrame(columns=points_of_interest_schema)
        df_poi_collection_ways["poi_geo_point"] = ""

    else:
        ways_geo_points = []
        ways_center_latitudes = []
        ways_center_longitudes = []
        for poi_center in df_poi_collection_ways["center"]:
            if not pd.isnull(poi_center):
                latitude_to_add = poi_center["lat"]
                longitude_to_add = poi_center["lon"]
                ways_geo_points.append(create_wkt_geo_point(longitude_to_add, latitude_to_add))

            else:
                latitude_to_add = None
                longitude_to_add = None
                ways_geo_points.append(None)
            ways_center_latitudes.append(latitude_to_add)
            ways_center_longitudes.append(longitude_to_add)
        df_poi_collection_ways["lat"] = ways_center_latitudes
        df_poi_collection_ways["lon"] = ways_center_longitudes
        df_poi_collection_ways["poi_geo_point"] = ways_geo_points

    #Wrapup :
    json_keys_columns_mapping = {"id":"poi_id", "lat":"poi_lat", "lon":"poi_lon",
                                 "center":"poi_center", "nodes":"poi_nodes", "type":"poi_type"}
    for key in json_keys_columns_mapping.keys():
        column_name = json_keys_columns_mapping[key]
        if some_nodes_collected:
            df_poi_collection_nodes.rename({key:column_name}, axis=1, inplace=True)
        if some_ways_collected:
            df_poi_collection_ways.rename({key:column_name}, axis=1, inplace=True)

    df_poi_collection = df_poi_collection_nodes.append(df_poi_collection_ways)
    df_poi_collection["poi_belonging_location"] = poi_belonging_location
    return df_poi_collection