# -------------------------------------------------------------------------------- NOTEBOOK-CELL: CODE
# -*- coding: utf-8 -*-
import dataiku
import pandas as pd, numpy as np
from dataiku import pandasutils as pdu
import json

# -------------------------------------------------------------------------------- NOTEBOOK-CELL: CODE
from distribution_spatial_footprint.geographic_handling import (read_geo_point,
                                                                polygon_contains_geo_point,
                                                                compute_geodesic_distance)
from distribution_spatial_footprint.utils import compute_identifiers_combinations, label_isochrones_range_min
from dku_utils import get_current_project_and_variables

# -------------------------------------------------------------------------------- NOTEBOOK-CELL: CODE
# Read recipe inputs
locations_isochrones = dataiku.Dataset("locations_isochrones")
locations_isochrones_df = locations_isochrones.get_dataframe()

# -------------------------------------------------------------------------------- NOTEBOOK-CELL: CODE
project, variables = get_current_project_and_variables()
global_variables = variables["standard"]
isochrones_api_to_use = global_variables["isochrones_api_to_use"]
variables_open_route_service = global_variables[isochrones_api_to_use]
isochrones_range_min = global_variables["isochrones_range_min"]
isochrones_range_min = label_isochrones_range_min(isochrones_range_min)

# -------------------------------------------------------------------------------- NOTEBOOK-CELL: CODE
location_identifiers = list(locations_isochrones_df["location_identifier"])
n_locations = len(location_identifiers)
locations_isochrones_df["geo_point"] = locations_isochrones_df["geo_point"].apply(lambda x:read_geo_point(x))
geo_points = list(locations_isochrones_df["geo_point"])
locations_combinations = compute_identifiers_combinations(location_identifiers)

# -------------------------------------------------------------------------------- NOTEBOOK-CELL: CODE
df_locations_competition = pd.DataFrame(columns=["isochrone_type",
                                                 "location_identifier",
                                                 "in_isochrone_location_identifier",
                                                 "distance_between_locations"
                                                ])

for isochrone_type in isochrones_range_min:
    focus_isochrones = list(locations_isochrones_df[isochrone_type])
    locations_isochrones = {location:json.loads(isochrone)["geometry"]["coordinates"][0] for location, isochrone\
                            in zip(location_identifiers, focus_isochrones)}

    locations_geo_points = {location:geo_point for location, geo_point\
                            in zip(location_identifiers, geo_points)}

    for loop_index, current_location in enumerate(location_identifiers):
        print(f"isochrone_type : '{isochrone_type}' | Looking for location n° {loop_index+1}/{n_locations} competitors ...")
        current_location_isochrone = locations_isochrones[current_location]
        current_location_geo_point = locations_geo_points[current_location]
        locations_to_combine_with = locations_combinations[current_location]

        for distant_location in locations_to_combine_with:
            distant_location_geo_point = locations_geo_points[distant_location]
            current_isochrone_contains_distant_location = \
            polygon_contains_geo_point(current_location_isochrone, distant_location_geo_point)

            if current_isochrone_contains_distant_location:
                distance_between_locations = compute_geodesic_distance(current_location_geo_point, distant_location_geo_point, True)


                df_locations_competition = df_locations_competition.append(
                    {"isochrone_type":isochrone_type,
                     "location_identifier":current_location,
                     "in_isochrone_location_identifier":distant_location,
                     "distance_between_locations":distance_between_locations
                    },
                    ignore_index=True)

# -------------------------------------------------------------------------------- NOTEBOOK-CELL: CODE
df_locations_competition = locations_isochrones_df[["location_identifier"]].merge(df_locations_competition,
                             how="left",
                             on="location_identifier")

# -------------------------------------------------------------------------------- NOTEBOOK-CELL: CODE
df_locations_competition.sort_values(by="location_identifier", inplace=True)
df_locations_competition["isochrone_type"].fillna("no_competitors", inplace=True)

# -------------------------------------------------------------------------------- NOTEBOOK-CELL: CODE
locations_competition = dataiku.Dataset("locations_competition")
locations_competition.write_with_schema(df_locations_competition)