import pandas as pd
import vega_datasets

from n6k_server.registry import data, defaults, rpc

defaults(selected_years=[2012, 2013, 2014, 2015])


@data()
def seattle_weather():
    return vega_datasets.data("seattle_weather")


@rpc()
def test_fn(limit: int = 10):
    return pd.DataFrame({"id": range(limit), "value": range(limit)})


@seattle_weather.rpc()
def weather_top(df, limit: int = 10):
    return df.head(limit)


@seattle_weather.view()
def max_temp_2015():
    return "SELECT MAX(temp_max) FROM db.seattle_weather WHERE year(date) = 2015"


@seattle_weather.view()
def max_temp_delta():
    return """
        SELECT MAX(CASE WHEN year(date)=2015 THEN temp_max END)
             - MAX(CASE WHEN year(date)=2014 THEN temp_max END)
        FROM db.seattle_weather
    """


@seattle_weather.view()
def min_temp_2015():
    return "SELECT MIN(temp_min) FROM db.seattle_weather WHERE year(date) = 2015"


@seattle_weather.view()
def min_temp_delta():
    return """
        SELECT MIN(CASE WHEN year(date)=2015 THEN temp_min END)
             - MIN(CASE WHEN year(date)=2014 THEN temp_min END)
        FROM db.seattle_weather
    """


@seattle_weather.view()
def max_precip_2015():
    return "SELECT MAX(precipitation) FROM db.seattle_weather WHERE year(date) = 2015"


@seattle_weather.view()
def max_precip_delta():
    return """
        SELECT MAX(CASE WHEN year(date)=2015 THEN precipitation END)
             - MAX(CASE WHEN year(date)=2014 THEN precipitation END)
        FROM db.seattle_weather
    """


@seattle_weather.view()
def min_precip_2015():
    return "SELECT MIN(precipitation) FROM db.seattle_weather WHERE year(date) = 2015"


@seattle_weather.view()
def min_precip_delta():
    return """
        SELECT MIN(CASE WHEN year(date)=2015 THEN precipitation END)
             - MIN(CASE WHEN year(date)=2014 THEN precipitation END)
        FROM db.seattle_weather
    """


@seattle_weather.view()
def max_wind_2015():
    return "SELECT MAX(wind) FROM db.seattle_weather WHERE year(date) = 2015"


@seattle_weather.view()
def max_wind_delta():
    return """
        SELECT MAX(CASE WHEN year(date)=2015 THEN wind END)
             - MAX(CASE WHEN year(date)=2014 THEN wind END)
        FROM db.seattle_weather
    """


@seattle_weather.view()
def min_wind_2015():
    return "SELECT MIN(wind) FROM db.seattle_weather WHERE year(date) = 2015"


@seattle_weather.view()
def min_wind_delta():
    return """
        SELECT MIN(CASE WHEN year(date)=2015 THEN wind END)
             - MIN(CASE WHEN year(date)=2014 THEN wind END)
        FROM db.seattle_weather
    """


@seattle_weather.view()
def most_common_weather():
    return "SELECT weather FROM db.seattle_weather GROUP BY weather ORDER BY count(*) DESC LIMIT 1"


@seattle_weather.view()
def least_common_weather():
    return "SELECT weather FROM db.seattle_weather GROUP BY weather ORDER BY count(*) ASC LIMIT 1"


@seattle_weather.derive()
def wind_daily(df):
    df = df.copy()
    df["year"] = df["date"].dt.year
    df["monthdate"] = pd.to_datetime(
        "2000-" + df["date"].dt.month.astype(str) + "-" + df["date"].dt.day.astype(str),
        format="%Y-%m-%d",
        errors="coerce",
    )
    df = df.dropna(subset=["monthdate"]).sort_values(["year", "monthdate"])
    df["avg_wind"] = df.groupby("year")["wind"].transform(lambda s: s.rolling(14, min_periods=1).mean())
    return df[["monthdate", "year", "avg_wind"]]


@seattle_weather.derive()
def temp_daily(df):
    df = df.copy()
    df["year"] = df["date"].dt.year
    df["monthdate"] = pd.to_datetime(
        "2000-" + df["date"].dt.month.astype(str) + "-" + df["date"].dt.day.astype(str),
        format="%Y-%m-%d",
        errors="coerce",
    )
    df = df.dropna(subset=["monthdate"]).sort_values(["year", "monthdate"])
    return df[["monthdate", "year", "temp_max", "temp_min"]]


@seattle_weather.derive()
def precip_by_month(df):
    df = df.copy()
    df["month"] = df["date"].dt.month
    df["year"] = df["date"].dt.year
    return df.groupby(["month", "year"])["precipitation"].sum().reset_index()
