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

# System modules
from datetime import datetime, timedelta

# Third-party modules
import numpy as np
from pyvantagepro import VantagePro2
from pyvantagepro.device import NoDeviceException

# Other templates
from ..utils import check
from ..utils.logger import log


class Meteo:
    def __init__(self, url):
        self.url = url
        self.error = None
        self.station = None

    @check.telnet_errors
    def connect(self):
        self.station = VantagePro2.from_url(self.url)

    @property
    def original(self):
        self.connect()

        if self.station:
            try:
                current = self.station.get_current_data()
                params = {k: current[k] for k in current.keys()}
            except BrokenPipeError as e:
                params = None
            except NoDeviceException:
                params = None

        else:
            params = None

        return params

    @property
    def data(self):
        params = self.original
        if not params:
            conv = None

        else:
            tempout = round((params['TempOut'] - 32) * 5. / 9, 1)
            humout = params['HumOut']
            dewpoint = round(tempout - ((100. - humout) / 5), 1)

            inches_to_mm = 25.4
            mph_to_kmh = 1.60934

            conv = {  # Come conversion in SI units
                "Datetime": params["Datetime"].isoformat()[:-7],
                # °F to °C
                "Temperature_first_floor": round((params['TempIn'] - 32) * 5. / 9, 1),
                "Humidity_first_floor": params["HumIn"],
                "Temperature_meteo_station": tempout,  # °F to °C
                "Humidity_meteo_station": humout,
                "Dewpoint": dewpoint,
                # inHg to hPa
                "Barometer": round(params["Barometer"] * 33.8638, 1),
                "Barometric_trend": params["BarTrend"],
                # mph to Km/h
                "Wind_speed": round(params["WindSpeed"] * mph_to_kmh, 1),
                # mph to Km/h
                "Wind_speed_last_10_min": round(params["WindSpeed10Min"] * mph_to_kmh, 1),
                "Wind_direction": params["WindDir"],
                "Rain_rate": params["RainRate"],
                "UV": params["UV"],
                "Solar_radiation": params["SolarRad"],
                "Rain_storm": params["RainStorm"] * inches_to_mm,
                "Storm_start_date": params["StormStartDate"],
                "Rain_day": params["RainDay"],
                "Rain_month": params["RainMonth"],
                "Rain_year": params["RainYear"],
                # inches to mm
                "ET_day": round(params["ETDay"] * inches_to_mm, 0),
                # inches to mm
                "ET_month": round(params["ETMonth"] * inches_to_mm, 0),
                # inches to mm
                "ET_year": round(params["ETYear"] * inches_to_mm, 0),
                "Battery_status": params["BatteryStatus"],
                "Battery_volts": round(params["BatteryVolts"], 2),
                "Forecast_icon": params["ForecastIcon"],
                "Forecast_rule_number": params["ForecastRuleNo"],
                "Sun_rise": params["SunRise"],
                "Sun_set": params["SunSet"],
            }

        return conv

    def summary(self):
        params0 = self.data
        print(f"Summary:")
        print(f"Datetime  {params0['Datetime']}")
        print(f"Dew Point {params0['Dewpoint']:.1f}°")
        print(f"TempIn    {params0['TempIn']:.1f}°")
        print(f"TempOut   {params0['TempOut']:.1f}°")
        print(f"HumIn     {params0['HumIn']}%")
        print(f"HumOut    {params0['HumOut']}%")
        print(f"WindSpeed {params0['WindSpeed']:.1f} km/h")
        print(f"Barometer {params0['Barometer']:.1f} hPa")

    @property
    def time(self):
        self.connect()
        current = self.station.gettime().isoformat()
        return current

    def synctime(self):
        self.connect()
        now = datetime.now()
        print(now)
        self.station.settime(now)

    def archive(self):
        now = datetime.now()
        now = datetime(year=now.year, month=now.month,
                       day=now.day, hour=now.hour)
        older = now - timedelta(days=4, hours=22)  # max 4 days, 22:00:00

        self.connect()
        archive = self.station.get_archives(older, now)  # takes some seconds
        params = {k: np.array([a[k] for a in archive])
                  for k in archive[0].keys()}

        return params


def main():

    now = datetime.now()
    now = datetime(year=now.year, month=now.month, day=now.day, hour=now.hour)
    older = now - timedelta(days=4, hours=22)  # max 4 days, 22:00:00

    m = Meteo("tcp:meteo.orsa.unige.net:5001")
    m.summary()

    # System modules
    import json
    print(f"All data:")
    print(json.dumps(m.data, indent=4))

    # params = m.archive() # takes some seconds
    # params = { k: np.array([a[k] for a in archive ]) for k in archive[0].keys() }

    # from matplotlib import pyplot as plt
    # params = m.archive() # takes some seconds
    # params = { k: np.array([a[k] for a in archive ]) for k in archive[0].keys() }

    # fig, axs = plt.subplots(2, 2)

    # date = params["Datetime"]

    # axs[0,0].title.set_text('Temperature out/in/dewpoint')
    # axs[0,0].plot(date, (params["TempOut"]-32)*5./9.)
    # axs[0,0].plot(date, (params["TempIn"]-32)*5./9.)
    # dewplot = ( (params['TempOut']-32)*5./9.) - ((100. - params['HumOut'])/5.)
    # axs[0,0].plot(date, dewplot)
    # axs[0,0].set(ylabel='°C')

    # axs[0,1].title.set_text('Humidity out/in')
    # axs[0,1].plot(date, params["HumOut"])
    # axs[0,1].plot(date, params["HumIn"])
    # axs[0,1].set(ylabel='%')

    # axs[1,0].title.set_text('Wind speed avg/hi')
    # axs[1,0].plot(date, params['WindAvg']*mph_to_kmh)
    # axs[1,0].plot(date, params['WindHi']*mph_to_kmh)
    # axs[1,0].set(ylabel='Km/h')

    # axs[1,1].title.set_text('Pressure')
    # axs[1,1].plot(date, params['Barometer']*33.8638)
    # axs[1,1].set(ylabel='hPa')

    # for ax in axs.flat:
    #     ax.set(xlabel='Date')

    # # # Hide x labels and tick labels for top plots and y ticks for right plots.
    # # for ax in axs.flat:
    # #     ax.label_outer()

    # plt.show()


if __name__ == "__main__":
    main()


#############################################################

# dic = ['Datetime', 'TempOut', 'TempOutHi', 'TempOutLow', 'RainRate', 'RainRateHi', 'Barometer', 'SolarRad', 'WindSamps', 'TempIn', 'HumIn', 'HumOut', 'WindAvg', 'WindHi', 'WindHiDir', 'WindAvgDir', 'UV', 'ETHour', 'SolarRadHi', 'UVHi', 'ForecastRuleNo']

# datadict = {
#     "Datetime": "date",
#     "TempOut": "outside temp (°F)",
#     "TempOutHi": "outside temp high (°F)",
#     "TempOutLow": "outside temp low (°F)",
#     "RainRate": "rainfall (clicks)", 1 click = 0.2mm?? "by stefano90"
#     "RainRateHi": "highest rain rate (clicks/hr)",
#     "Barometer": "barometer (inches Hg)",
#     "SolarRad": "average solar radiation (W/m^2)",
#     "WindSamps": "number of wind samples",
#     "TempIn": "insideTemp (°F)",
#     "HumIn": "inside humidity (%)",
#     "HumOut": "outside humidity (%)",
#     "WindAvg": "average wind speed (mph)",
#     "WindHi": "highest wind speed (mph)",
#     "WindHiDir": "highest wind direction (°)",
#     "WindAvgDir": "prevailing wind direction (°)",
#     "UV": "average uv index",
#     "ETHour": "accumulated et (in)", EvapoTranspiration (ET)
#     "SolarRadHi": "maximum solar radiation (W/m^2)",
#     "UVHi": "max uv",
#     "ForecastRuleNo": "forecast at end of period",
# }
