#extract 5 most recent full dataset and save to local full folder
#https://www.google.com/search?q=python+a+wraper+funciton+contain+mutiple+funciton+one+of+them+are+async%2C+shoud+I+change+all+to+async&sca_esv=286534660d0b6d5d&sxsrf=ANbL-n7fW0CbBRJfM3_-4kYhR-v9W0SuXA%3A1772733943664&ei=98WpaeGjKMih5NoPmaao4Q8&biw=2124&bih=1015&ved=0ahUKEwih-_jHrImTAxXIEFkFHRkTKvwQ4dUDCBE&uact=5&oq=python+a+wraper+funciton+contain+mutiple+funciton+one+of+them+are+async%2C+shoud+I+change+all+to+async&gs_lp=Egxnd3Mtd2l6LXNlcnAiZHB5dGhvbiBhIHdyYXBlciBmdW5jaXRvbiBjb250YWluIG11dGlwbGUgZnVuY2l0b24gb25lIG9mIHRoZW0gYXJlIGFzeW5jLCBzaG91ZCBJIGNoYW5nZSBhbGwgdG8gYXN5bmNI3wdQAFjKBXAAeACQAQCYAWugAe8EqgEDNi4xuAEDyAEA-AEBmAIAoAIAmAMA4gMFEgExIECSBwCgB_IdsgcAuAcAwgcAyAcAgAgA&sclient=gws-wiz-serp
import asyncio
from ._imports import *

#function to call api and get json data, handle erro 
async def submit_wind_history_job(lat, lon, start=None, end=None):
    '''
    Submit parameter to gis web API to get wind data and status 
    Parameters
    ----------
    lat : float 
                Latitude.
    lon : float 
                Longitude.
    start1 : str 
                start datetime in yyyy-MM-dd.
    end1 : str 
                end datetime in yyyy-MM-dd.
    Returns
    ----------
    data : dict 
                data returned in json.
    status : str 
                job status.
    Examples
    ----------
    data, status = submit_wind_history_job(lat, lon, '2022-01-01', '2022-11-17')
    '''
    data = dict()
    status = 'error'
    try:
        SERVICE_BASE = "https://gisdev.amica.com/arcgis/rest/services/GPTools/GetWindHistory/GPServer/GetWindHistory"
        url = f"{SERVICE_BASE}/execute"
        params = {
        "f": "json",
        # Adjust param names to match the REST page:
        # Examples shown; rename if your tool uses "latitude/longitude" or "Point" instead.
        "Latitude": lat,
        "Longitude": lon,
        "BeginDT": start,
        "EndDT": end
    }
        r = requests.post(url, data=params, verify=True, timeout=60)  #SSL set False for testing
        r.raise_for_status()
        data = r.json()
        status = 'success'
        return data, status
    except Exception as e:
        print(f"Error occurred: {e}")
        return data, e
    
#get wind event data into dataframe
def get_dataframe_from_wind_data(data, job_status):
    '''
    get wind event data into dataframe
    Parameters
    ----------
    data : dict 
                data returned in json.
    job_status : str 
                job status.
    Returns
    ----------
    df : pd.DataFrame 
                dataframe with wind event data.
    Examples
    ----------
    df = get_dataframe_from_wind_data(data)
    '''
    df = pd.DataFrame()
    if job_status == 'success':
        row = []
        try:
            for event in data['results'][0]['value']['events']:
                timestamp = event.get('date')
                wind_speed = event.get('WindSpeed')    
                row.append({
                    'timestamp': timestamp,
                    'wind_speed': wind_speed        
                })
            df = pd.DataFrame(row)
        except Exception as e:
            print(f"Error occurred while processing data: {e}")
            print(data)
            raise e
    return df

def get_wind_speed_value_from_ref_df(ref_df, search_date):
    '''
    function that use the ref df to get data 
    Parameters
    ----------
    ref_df : pd.DataFrame 
                reference dataframe with wind event data.
    
    search_date : str 
                start datetime in yyyy-MM-dd.    
    Returns
    ----------
    wind_speed_value : int
                wind speed.
    Examples
    ----------
    wind_speed_value = get_wind_speed_value_from_ref_df(ref_df, search_date)
    '''
    if ref_df.empty:
        return None
    wind_speed_value = None
    mask = (ref_df['timestamp'] == search_date)
    filtered_df = ref_df.loc[mask, ['timestamp', 'wind_speed']]
    if not filtered_df.empty:
        wind_speed_value = filtered_df.iloc[0]['wind_speed'] 
    return wind_speed_value

async def get_wind_data(lat, lon, start=None, end=None, search_date='2022-01-29'):
    '''
    wrapper function to get wind data 
    Parameters
    ----------
    lat : float 
                Latitude.
    lon : float 
                Longitude.
    start : str 
                start datetime in yyyy-MM-dd.
    end : str 
                end datetime in yyyy-MM-dd.
    Returns
    ----------
    wind_speed_value : int
                wind speed.
    Examples
    ----------
    wind_speed_value = get_wind_data(lat, lon, '2022-01-01', '2022-11-17', '2022-01-29')
    '''
    if pd.to_datetime(search_date).year <2020:
        return None
    try:
        data, status = await submit_wind_history_job(lat, lon, start=start, end=end)
        await asyncio.sleep(1)
        df = get_dataframe_from_wind_data(data, status)
        wind_speed_value = get_wind_speed_value_from_ref_df(df, search_date)
    except Exception as e:
        #print(f"Error occurred in get_wind_data: {e}")
        wind_speed_value = None

    return wind_speed_value

async def get_wind_dataframe(df):    
    #df['wind_speed'] = await asyncio.gather(*(get_wind_data(x, y, z, z1, z2) for x, y, z, z1, z2 in df[['GEO_Y', 'GEO_X', 'start', 'end', 'search_date']].itertuples(index=False)))
    df['wind_speed'] = await asyncio.gather(*(get_wind_data(x, y, z, z1, z2) for x, y, z, z1, z2 in zip(df['GEO_Y'], df['GEO_X'],  df['LOSS_DT'], df['LOSS_DT'], df['LOSS_DT'])))
    return df