import json
from datetime import datetime

import pandas as pd
import requests

# api
base_url = "https://archive-api.open-meteo.com/v1/archive"

cmap = {
    "temperature_2m": "t_air",
    "relative_humidity_2m": "rh",
    "precipitation": "rain",
    "shortwave_radiation": "ghi",
    "wind_speed_10m": "ws",
    "et0_fao_evapotranspiration": "eto",
}


def fetch(latitude, longitude, date_beg, date_end):
    """Fetch time series for given location on remote server

    Args:
        latitude (float): [deg] latitude of place
        longitude (float): [deg] longitude of place
        date_beg (datetime): First date, included
        date_end (datetime): End date, included

    Returns:
        (pd.DataFrame, dict): date, header
    """
    params = {
        "latitude": latitude,
        "longitude": longitude,
        "start_date": date_beg.date().isoformat(),
        "end_date": date_end.date().isoformat(),
        "wind_speed_unit": "ms",
        "hourly": list(cmap.keys())
    }

    # fetch
    response = requests.get(url=base_url, params=params, verify=True, timeout=30.00)

    cnt = response.content
    data = json.loads(cnt)
    if "hourly" not in data:
        raise UserWarning(data)

    df = pd.DataFrame(data["hourly"])
    df = df.rename(columns=cmap | {'time': 'date'})
    df["date"] = pd.to_datetime(df["date"])

    # format header
    units = {name_norm: data["hourly_units"][name] for name, name_norm in cmap.items()}
    assert units["ghi"] == "W/m²"
    units["ghi"] = "W.m-2"
    assert units["ws"] == "m/s"
    units["ws"] = "m.s-1"
    assert units["rain"] == "mm"
    units["rain"] = "mm.h-1"
    assert units["eto"] == "mm"
    units["eto"] = "mm.h-1"

    header = {name: f"[{unit}]" for name, unit in units.items()}
    header["date"] = "[utc] see https://open-meteo.com/en/docs/historical-weather-api"
    header["latitude"] = f"[deg] {latitude:.6f}"
    header["longitude"] = f"[deg] {longitude:.6f}"

    return df.set_index("date"), header
