#!/usr/bin/env python3
# -*- coding: utf-8 -*-


import geopandas as gpd
import numpy as np
import pandas as pd


def get_community_areas_for_stations_v2(
    gdf, df, lat="Latitude", lon="Longitude", crs=4326
):
    cols_order = list(df) + list(gdf)
    polygons_contains = (
        gpd.sjoin(
            gdf,
            gpd.GeoDataFrame(
                df, geometry=gpd.points_from_xy(df[lon], df[lat]), crs=crs
            ),
            op="contains",
        )
        .reset_index(drop=True)
        .drop(columns=["index_right"])[cols_order]
    )
    # print(polygons_contains)
    return polygons_contains


def haversine(s_lat, s_lng, e_lat, e_lng):

    # approximate radius of earth in km
    R = 6373.0

    s_lat = s_lat * np.pi / 180.0
    s_lng = np.deg2rad(s_lng)
    e_lat = np.deg2rad(e_lat)
    e_lng = np.deg2rad(e_lng)

    d = (
        np.sin((e_lat - s_lat) / 2) ** 2
        + np.cos(s_lat) * np.cos(e_lat) * np.sin((e_lng - s_lng) / 2) ** 2
    )

    return 2 * R * np.arcsin(np.sqrt(d))


def get_distance(df, loc_cols_1, loc_cols_2, crs=4326, epsg=6345):
    gdf_start = gpd.GeoDataFrame(
        df[loc_cols_1],
        geometry=gpd.points_from_xy(df[loc_cols_1[1]], df[loc_cols_1[0]]),
        crs=crs,
    )
    gdf_feed = gpd.GeoDataFrame(
        df[loc_cols_2],
        geometry=gpd.points_from_xy(df[loc_cols_2[1]], df[loc_cols_2[0]]),
        crs=crs,
    )
    df["start_station_to_feed_km"] = (
        gdf_feed["geometry"]
        .to_crs(epsg=epsg)
        .distance(gdf_start["geometry"].to_crs(epsg=epsg))
    )
    df["start_station_to_feed_km"] = df["start_station_to_feed_km"] / 1_000
    df["start_station_to_feed_km_haversine"] = pd.Series(
        np.vectorize(haversine)(*[df[c] for c in loc_cols_1 + loc_cols_2]),
        index=df.index,
    )
    return df
