import os
import json
import datetime
import glob
import random
from operator import itemgetter

import openmeteo_requests

import requests_cache
import pandas as pd
from retry_requests import retry


def get_webcam_array()->list:

    webcam_array=[]
    '''
		{
			"titulua":"Zarautz",
			"webcam_url":"https://58f14c0895a20.streamlock.net/camaramar/GIP_zarautz_169.stream/playlist.m3u8"
		},{
			"titulua":"Orio",
			"webcam_url":"https://58f14c0895a20.streamlock.net:443/camaramar/GIP_orio_169.stream/playlist.m3u8"
		}
	],
    '''
    f=glob.glob( "../dat/webcam/*/*.mp4" )
    f=sorted(f, reverse=True)

    wv={}
    for v in f:
        vd=v.split('/')
        if vd[-2] not in wv:
            wv[vd[-2]]=vd[-1]

    l = list(wv.items())
    random.shuffle(l)
    d_shuffled = dict(l)

    print("wv22222: ", d_shuffled )

    for k,v2 in dict(l).items():
        webcam_array.append({
            "titulua": k.capitalize(),
            "webcam_url": "http://localhost/tb30/eguraldia/dat/webcam/"+k+"/"+v2
        })
    print("GGGG:::: ", webcam_array )
    return webcam_array



def mapako_puntuak(openmeteo)->list :
    puntuak=[ x for x in herriak if "mapako_puntuak" in x['non'] ]
    t=[]
    for p in puntuak:
        t.append({
            "izena": p["id"],
            "titulua": p['titulua'],
            "tenperatura": openmeteo[ p['id'] ][0][2],
            "ikonoa": openmeteo[ p['id'] ][0][1]
		})

    return t

def eskubi_taulako_herriak(openmeteo)->list:
    puntuak=[ x for x in herriak if "eskubi_taulako_herriak" in x['non'] ]
    t=[]
    for p in puntuak:
        t.append({
            "titulua": p['titulua'],
            "tenperatura_max": openmeteo[ p['id'] ][1][2],
            "tenperatura_min": openmeteo[ p['id'] ][1][3]
		})

    return t
    
def probintzietako_datuak(openmeteo, probintzia)->tuple :
    puntuak=[ x for x in herriak if x['probintzia']==probintzia and "probintzietako_datuak" in x['non'] ]
    t=[]
    ikonoak={}
    
    for p in puntuak:
        t.append({
            "titulua": p['titulua'],
            "tenperatura_max": openmeteo[ p['id'] ][1][2],
            "tenperatura_min": openmeteo[ p['id'] ][1][3]
		})
        ikonoak[ openmeteo[ p['id'] ][2][1] ] = ikonoak.get( openmeteo[ p['id'] ][2][1] , 0) + 1

    ikonoak_sorted=sorted(ikonoak.items(), key=itemgetter(1), reverse=True)
    return  (ikonoak_sorted[0][0],t)

def eguraldia_osatu( openmeteo ):
    orain="Orain [" + openmeteo['baiona'][0][0].strftime("%H:%M")+']'
    gipuzkoa=probintzietako_datuak(openmeteo, 'gipuzkoa')
    bizkaia=probintzietako_datuak(openmeteo, 'bizkaia')
    araba=probintzietako_datuak(openmeteo, 'araba')
    nafarroa=probintzietako_datuak(openmeteo, 'nafarroa')
    lapurdi=probintzietako_datuak(openmeteo, 'lapurdi')
    behe_nafarroa=probintzietako_datuak(openmeteo, 'behe_nafarroa')
    zuberoa=probintzietako_datuak(openmeteo, 'zuberoa')

    eguraldia={
        "titulua":"Euskal Herria",
        "noizko_datuak": orain,
        "mapako_puntuak": mapako_puntuak(openmeteo),
        "eskubi_taulako_herriak":eskubi_taulako_herriak(openmeteo),
        "webcam_array":get_webcam_array(),
        "probintzietako_datuak":[
            {
            "izena":"gipuzkoa",
            "titulua":"Gipuzkoa",
            "noizko_datuak":orain,
            "ikonoa":gipuzkoa[0],
            "herriak":gipuzkoa[1]
            },
            {
            "izena":"bizkaia",
            "titulua":"Bizkaia",
            "noizko_datuak":orain,
            "ikonoa":bizkaia[0],
            "herriak":bizkaia[1]
            },
            {
            "izena":"araba",
            "titulua":"Araba",
            "noizko_datuak":orain,
            "ikonoa": araba[0],
            "herriak": araba[1]
            },
            {
            "izena":"nafarroa",
            "titulua":"Nafarroa",
            "noizko_datuak":orain,
            "ikonoa": nafarroa[0],
            "herriak": nafarroa[1]
            },
            {
            "izena":"lapurdi",
            "titulua":"Lapurdi",
            "noizko_datuak":orain,
            "ikonoa":lapurdi[0],
            "herriak":lapurdi[1]
            },
            {
            "izena":"behe_nafarroa",
            "titulua":"Behe Nafarroa",
            "noizko_datuak":orain,
            "ikonoa": behe_nafarroa[0],
            "herriak": behe_nafarroa[1]
            },
            {
            "izena":"zuberoa",
            "titulua":"Zuberoa",
            "noizko_datuak":orain,
            "ikonoa": zuberoa[0],
            "herriak": zuberoa[1]
            }

        ],
    }

    print("EGUralida:::: ", json.dumps(eguraldia) )

    with open('../dat/eguraldia.json', 'w', encoding='utf-8') as f:
        json.dump(eguraldia, f, ensure_ascii=False, indent=4)





'''

WMO Weather interpretation codes (WW)
Code     Description
0     Clear sky
1, 2, 3     Mainly clear, partly cloudy, and overcast
45, 48     Fog and depositing rime fog
51, 53, 55     Drizzle: Light, moderate, and dense intensity
56, 57     Freezing Drizzle: Light and dense intensity
61, 63, 65     Rain: Slight, moderate and heavy intensity
66, 67     Freezing Rain: Light and heavy intensity
71, 73, 75     Snow fall: Slight, moderate, and heavy intensity
77     Snow grains
80, 81, 82     Rain showers: Slight, moderate, and violent
85, 86     Snow showers slight and heavy
95 *     Thunderstorm: Slight or moderate
96, 99 *     Thunderstorm with slight and heavy hail

----------------------------------------------------------------

Códigos de interpretación meteorológica (WW) de la OMM
Código Descripción
0 Cielo despejado
1, 2, 3 Principalmente despejado, parcialmente nublado y cubierto
45, 48 Niebla y depósito de niebla de escarcha
51, 53, 55 Llovizna: Intensidad ligera, moderada y densa
56, 57 Llovizna helada: Intensidad ligera y densa
61, 63, 65 Lluvia: Intensidad leve, moderada y fuerte
66, 67 Lluvia helada: Intensidad ligera y fuerte
71, 73, 75 Caída de nieve: Intensidad leve, moderada y fuerte
77 granos de nieve
80, 81, 82 Chubascos de lluvia: leves, moderados y violentos
85, 86 Chubascos de nieve ligeros e intensos
95 * Tormenta: Leve o moderada
96, 99 * Tormenta con granizo leve y fuerte
'''
def ikono_aukera(weather_code)->str:
    inum=-1
    #print("----:", weather_code )
    if weather_code==0:
        inum="img/icons/1.svg"
    elif weather_code==1:
        inum="img/icons/2.svg" 
    elif weather_code==2:
        inum="img/icons/3.svg"
    elif weather_code==3:
        inum="img/icons/4.svg"
    #45, 48 Niebla y depósito de niebla de escarcha
    elif weather_code==45 or weather_code==48:
        inum="img/icons/15.svg"
    #51, 53, 55 Llovizna: Intensidad ligera, moderada y densa
    elif weather_code==51:
        inum="img/icons/5.svg"
    elif weather_code==53:
        inum="img/icons/5.svg"
    elif weather_code==55:
        inum="img/icons/5.svg" 
    #56, 57 Llovizna helada: Intensidad ligera y densa
    elif weather_code==56 or weather_code==57:
        inum="img/icons/7.svg"
    #61, 63, 65 Lluvia: Intensidad leve, moderada y fuerte
    elif weather_code==61:
        inum="img/icons/9.svg"
    elif weather_code==63:
        inum="img/icons/10.svg"
    elif weather_code==65:
        inum="img/icons/11.svg"
    #66, 67 Lluvia helada: Intensidad ligera y fuerte
    elif weather_code==66 or weather_code==67:
        inum="img/icons/12.svg"
    #71, 73, 75 Caída de nieve: Intensidad leve, moderada y fuerte
    #77 granos de nieve
    elif weather_code==71 or weather_code==73 or weather_code==75:
        inum="img/icons/13.svg"

    #80, 81, 82 Chubascos de lluvia: leves, moderados y violentos
    elif weather_code==80:
        inum="img/icons/6.svg"
    elif weather_code==81:
        inum="img/icons/6.svg"
    elif weather_code==82:
        inum="img/icons/11.svg"
    #85, 86 Chubascos de nieve ligeros e intensos
    elif weather_code==85:
        inum="img/icons/12.svg"
    elif weather_code==86:
        inum="img/icons/13.svg"
    #95 * Tormenta: Leve o moderada
    elif weather_code==86:
        inum="img/icons/24.svg"
    #96, 99 * Tormenta con granizo leve y fuerte
    elif weather_code==86:
        inum="img/icons/25.svg"

    if inum==-1:
        print("GIAZKIIIIIIIIIIII ", weather_code ) 
        os.sys.exit()
    return inum       





#############################################################
#   NAGUSIA
#############################################################
                
non=os.path.abspath(os.path.dirname(os.sys.argv[0]))
os.chdir(non)


herriak=[]
with open('./conf/herriak.json', 'r') as f:
    herriak = json.load(f)


params = {
    "latitude": [],
    "longitude": [],
    "daily": ["weather_code", "temperature_2m_max", "temperature_2m_min"],
    "current": ["weather_code", "temperature_2m"],
    "timezone": [],
    "start_date": datetime.date.today() + datetime.timedelta(days=1),
    "end_date": datetime.date.today() + datetime.timedelta(days=3)
    
}


for h in herriak:
    params["latitude"].append(h['lat'])
    params["longitude"].append(h['lon'])
    params["timezone"].append("Europe/Berlin")

 

# Setup the Open-Meteo API client with cache and retry on error
cache_session = requests_cache.CachedSession('.cache', expire_after = 3600)
retry_session = retry(cache_session, retries = 5, backoff_factor = 0.2)
openmeteo = openmeteo_requests.Client(session = retry_session)

# Make sure all required weather variables are listed here
# The order of variables in hourly or daily is important to assign them correctly below
url = "https://api.open-meteo.com/v1/meteofrance"
#url = "https://api.open-meteo.com/v1/forecast"


responses = openmeteo.weather_api(url, params=params)

openmeteo={}

for i in range(0, len(responses) ):
    response = responses[i]
    openmeteo[ herriak[i]['id'] ] =[]
    
    # Process daily data. The order of variables needs to be the same as requested.
    current = response.Current()
    current_temperature_2m = current.Variables(1).Value()
    current_weather_code = current.Variables(0).Value()

    openmeteo[ herriak[i]['id'] ].append([
        datetime.datetime.now(),
        ikono_aukera(current_weather_code),
        round(current_temperature_2m),
        round(current_temperature_2m)
    ])

    daily = response.Daily()
    daily_weather_code = daily.Variables(0).ValuesAsNumpy()
    daily_temperature_2m_max = daily.Variables(1).ValuesAsNumpy()
    daily_temperature_2m_min = daily.Variables(2).ValuesAsNumpy()

    daily_data = {"date": pd.date_range(
        start = pd.to_datetime(daily.Time(), unit = "s"),
        end = pd.to_datetime(daily.TimeEnd(), unit = "s"),
        freq = pd.Timedelta(seconds = daily.Interval()),
        closed = "left"
    )}
    #daily_data["weather_code"] = daily_weather_code
    #daily_data["temperature_2m_max"] = daily_temperature_2m_max
    #daily_data["temperature_2m_min"] = daily_temperature_2m_min
    daily_dataframe = pd.DataFrame(data = daily_data).to_dict()
    
    

    for index in range(0,len(daily_dataframe['date']) ):
        openmeteo[ herriak[i]['id'] ].append([
            daily_dataframe['date'][index].date(),
            ikono_aukera(daily_weather_code[index]),
            round(daily_temperature_2m_max[index]),
            round(daily_temperature_2m_min[index])
        ])


eguraldia_osatu(openmeteo)