import numpy as np
from pvlib.location import lookup_altitude
from docs.pyeto import fao

def et0(irradiance, T, Tmax, Tmin, RHmin, RHmax, WS, JJulien, latitude, longitude):
    """
    Calculate the daily reference evapotranspiration [ml/day] w.r.t. Penman-Monteith formula.

    Parameters
    ----------
    irradiance : array_like
        Daily global horizontal irradiance [MJ/m2/day].

    T : array_like
        Mean daily air temperature at 2 m height [deg Celsius].

    Tmax : array_like
        Maximum air temperature at 2 m height [deg Celsius].

    Tmin : array_like
        Minimum air temperature at 2 m height [deg Celsius].

    RHmin : array_like
        Minimum daily relative humidity [%].

    RHmax : array_like
        Maximum daily relative humidity [%].

    WS : array_like
        Wind speed at 10 m height [m s-1].

    JJulien : array_like
        Julian day.

    latitude : array_like
        Latitude in °.

    longitude : array_like
        Longitude in °.
        
    Returns
    -------
    array_like
        Reference evapotranspiration (ETo) from a hypothetical grass reference surface [mm day-1].
    """

    latRad = (latitude * np.pi) / 180
    ### VPD, SVP

    svp_tmax = fao.svp_from_t(Tmax)
    svp_tmin = fao.svp_from_t(Tmin)
    svp = fao.svp_from_t(T)
    avp = fao.avp_from_rhmin_rhmax(svp_tmin, svp_tmax, RHmin, RHmax)
    delta_svp = fao.delta_svp(T)

    ### IR

    #sol_rad = irradiance * 36 / 10000   #Conversion W/m2 en MJ/m2/day
    sol_rad = irradiance 

    ### Radiation Nette

    sol_dec = fao.sol_dec(JJulien)
    sunset_hour_angle = fao.sunset_hour_angle(latRad, sol_dec)
    inv_dist_earth_sun = fao.inv_rel_dist_earth_sun(JJulien)

    et_rad = fao.et_rad(latRad, sol_dec, sunset_hour_angle, inv_dist_earth_sun)

    T_kelvin = T + 273.15
    Tmin_kelvin = Tmin + 273.15
    Tmax_kelvin = Tmax + 273.15

    altitude = np.array(lookup_altitude(latitude, longitude))

    cs_rad = fao.cs_rad(altitude, et_rad)

    net_out_lw_rad = fao.net_out_lw_rad(Tmin_kelvin, Tmax_kelvin, sol_rad, cs_rad, avp)

    net_in_sol_rad = fao.net_in_sol_rad(sol_rad, 0.2)

    net_rad = fao.net_rad(net_in_sol_rad, net_out_lw_rad)

    atm_pressure = fao.atm_pressure(altitude)

    psy = fao.psy_const_of_psychrometer(2, atm_pressure)

    ws_2m = fao.wind_speed_2m(WS, 10)

    et0 = fao.fao56_penman_monteith(net_rad, T_kelvin, ws_2m, svp, avp, delta_svp, psy)

    return et0


def gdd(Tmin, Tmax, Tbase):
    """
    Calculate the Growing Degree Days [Degrees Celsius].

    Parameters
    ----------
    Tmax : float or numpy array
        Maximum daily air temperature [deg Celsius].

    Tmin : float or numpy array
        Minimum daily air temperature [deg Celsius].

    Tbase : float or numpy array
        Base crop temperature (corresponding to zero vegetation) [deg Celsius].

    Returns
    -------
    float
        Growing Degree Days [deg Celsius].
    """

    return ((Tmax + Tmin) / 2) - Tbase


def gelif(Tmin, Tfrost):
    """
    Define if the day is a frosting day.

    Parameters
    ----------
    Tmin : float or numpy array
        Minimum daily air temperature [deg Celsius].

    Tfrost : float
        Crop frost temperature (depends on the crop and phenophase) [deg Celsius].

    Returns
    -------
    bool
        True if it's a frosting day, else False.
    """

    if Tmin > Tfrost:
        is_forst = False
    elif Tmin <= Tfrost:
        is_forst = True

    return is_forst


def vpd(T, RH):
    """
    Compute deficit vapor pressure.

    Parameters
    ----------
    T : float or numpy array
        Mean timestep air temperature [deg Celsius].

    RH : float or numpy array
        Mean timestep relative humidity [unitless %].

    Returns
    -------
    float or numpy array
        Vapor pressure deficit (VPD).
    """

    VPS = 0.6108 * np.exp((17.27 * T) / (T + 237.3))
    VPD = VPS * (1 - RH / 100)

    return VPD