#!/usr/bin/env python3
# turismo.py

"""Datos de turismo"""

# Librerias generales
import logging
import sys
import time
import pathlib

# Librerias del proyecto
import math as ma
import numpy as np
import matplotlib.pyplot as plt

import requests
import json
import pandas as pd


# LOGGING - DEGUG - DEPURACION
global GLOG  # Variable global desactiva logging
GLOG = False  # Activa el logging
# GLOG = True  # Desactiva el logging
logging.basicConfig(
    format="%(asctime)s %(levelname)s:%(name)s: %(message)s",
    level=logging.INFO,  # DEBUG
    datefmt="%H:%M:%S",
    stream=sys.stderr,
)
logger = logging.getLogger(__name__)
logger.setLevel(logging.INFO)
logger.disabled = GLOG


# FUNCIONES

def download_url_json():
    ''' Descarga un fichero json de una url'''
    logger = logging.getLogger('__' + sys._getframe().f_code.co_name)
    logger.disabled = GLOG
    logger.info('Initium ->')
    # ******** codigo de la funcion *******
    path = 'data.json'  # data download file
    url = 'https://servicios.ine.es/wstempus/js/es/DATOS_TABLA/2074?tip=AM&'
    try:
        data = requests.get(url)
        output = json.loads(data.text)  # dict
        with open(path, 'w') as outfile:
            json.dump(output, outfile, sort_keys=False, indent=4)
    except:  # catch *all* exceptions
        logger.exception('Error: [{}]'.format(sys.exc_info()))
    return path


def transform_json_df(f, export=False):
    ''' Toma un fichero json (f) de entrada y
    devuelve un dataframe con las categorias seleccionadas'''
    logger = logging.getLogger('__' + sys._getframe().f_code.co_name)
    logger.disabled = GLOG
    logger.info('Initium ->')
    # ******** codigo de la funcion *******
    df0 = pd.DataFrame()
    try:
        # Reading the json as a dict
        with open(f, 'r', encoding='utf-8') as json_data:
            data = json.load(json_data)  # dict
        df = pd.DataFrame(data)
        #Datos: categorias
        df_categorias = df[['COD', 'Nombre']]
        categorias_all = df_categorias['COD'].tolist()
        #print(categorias_all)
        # Exporta el fichero de categorias
        path = 'd_categorias.xlsx'
        if export:
            df_categorias.to_excel(path, index = False)
        # Datos: Serie temporal
        #df_data = df['Data'].apply(pd.Series)
        df_data = pd.DataFrame(df.pop('Data').values.tolist())  # más rápido
        # Seleccionamos las categorias a procesar
        categorias = ['EOT1', 'EOT9', 'EOT17',  # Viajeros nacional
                      'EOT25', 'EOT33', 'EOT41',  # pernoctaciones nacional
                      'EOT1568', 'EOT1569', 'EOT1570',  # pernoctaciones cyl
                      'EOT1622', 'EOT1623']  # pernoctaciones zamora
        # Exportamos todas las categorias
        #categorias = categorias_all
        # Añadimos todas las categorias al dataframe df0
        for cat in categorias:
            i = df.index[df['COD'] == cat].tolist()[0]  # Saca el index
            print('Categoria: {}-{}-{}'.format(i,
                                               df.iloc[i, 0],
                                               df.iloc[i, 1]))
            df_cat = df_data.iloc[i, :]
            df_cat = pd.json_normalize(df_cat)
            df_cat['COD'] = df.iloc[i, 0]  # Añade el codigo
            df_cat['NOMBRE'] = df.iloc[i, 1]  # Añade el nombre
            frames = [df0, df_cat]  # Para concatenar todas las categorias
            df_cat = pd.concat(frames, join="outer").reset_index(drop=True)
            df0 = df_cat
        # Añadimos el PERIODO juntando dos columnas
        df0['PERIODO'] = df0['Anyo'].astype(
            str) + df0['T3_Periodo'].astype(str)
        # Exporta el fichero de pernoctaciones
        path = 'd_pernoctaciones.xlsx'
        if export:
            df0.to_excel(path, index = False)
    except:  # catch *all* exceptions
        logger.exception('Error: [{}]'.format(sys.exc_info()))

    print(df0.describe())
    print('Salida df0, len: {}, type: {}'.format(len(df0), type(df0)))

    return df0


def paint_df(df, titulo, cod1, cod2, cod3):
    ''' Pinta graficas de las categorias del df'''
    logger = logging.getLogger('__'+sys._getframe().f_code.co_name)
    logger.disabled = GLOG
    logger.info('Initium ->')
    # ******** codigo de la funcion *******

    df1 = df.loc[df['COD'] == cod1]
    df1 = df1[['PERIODO', 'Valor']]
    df1.set_index('PERIODO', inplace=True)
    df1 = df1.sort_values('PERIODO')
    x1 = df1.index.tolist()  # Valores de X
    y1 = df1['Valor'].tolist()  # Valores de y
    N = len(x1)
    xlabels = x1[0:N:12]  # Etiquetas 1 de cada 12
    # xlabels.append(x1[-1])  # Añade el último elemento de la lista

    df2 = df.loc[df['COD'] == cod2]
    df2 = df2[['PERIODO', 'Valor']]
    df2.set_index('PERIODO', inplace=True)
    df2 = df2.sort_values('PERIODO')
    x2 = df2.index.tolist()  # Valores de X
    y2 = df2['Valor'].tolist()  # Valores de y

    df3 = df1.merge(df2,  how='left', left_index=True, right_index=True)
    df3['Valor'] = df3['Valor_x'] - df3['Valor_y']
    x3 = df3.index.tolist()  # Valores de X
    y3 = df3['Valor'].tolist()  # Valores de y

    fig, ax = plt.subplots()

    ax = plt.grid(axis='y', color='red', linestyle='--', linewidth=0.5)
    ax = plt.plot(x1, y1, color='black', label='Totales')
    ax = plt.plot(x2, y2, color='red', label='Españoles')
    ax = plt.plot(x3, y3, color='blue',  label='Extranjeros')
    ax = plt.xticks(rotation=45, ha='right')
    ax = plt.xticks(ticks=xlabels, labels=xlabels)
    ax = plt.title('{} ({}-{})'.format(titulo, x1[0], x1[-1]))
    ax = plt.legend()

    plt.show()


def paint_df0(df):
    ''' Pinta graficas de las categorias del df'''
    logger = logging.getLogger('__'+sys._getframe().f_code.co_name)
    logger.disabled = GLOG
    logger.info('Initium ->')
    # ******** codigo de la funcion *******

    titulo = 'Viajeros_Pernoctaciones'
    # Data
    titulo1 = 'Nacional_Viajeros'
    # Total
    dft = df.loc[df['COD'] == 'EOT1']
    dft = dft[['PERIODO', 'Valor']]
    dft.set_index('PERIODO', inplace=True)
    # Nacional
    dfn = df.loc[df['COD'] == 'EOT9']
    dfn = dfn[['PERIODO', 'Valor']]
    dfn.set_index('PERIODO', inplace=True)
    # Extranjeros
    df1 = dft.merge(dfn,  how='left', left_index=True, right_index=True)
    df1['Valor_z'] = df1['Valor_x'] - df1['Valor_y']
    df1 = df1.sort_values('PERIODO')
    df1.set_axis(['Totales', 'Españoles', 'Extranjeros'], axis=1, inplace=True)
    x = df1.index.tolist()  # Valores de X

    titulo2 = 'Nacional_Pernoctaciones'
    # Total
    dft = df.loc[df['COD'] == 'EOT25']
    dft = dft[['PERIODO', 'Valor']]
    dft.set_index('PERIODO', inplace=True)
    # Nacional
    dfn = df.loc[df['COD'] == 'EOT33']
    dfn = dfn[['PERIODO', 'Valor']]
    dfn.set_index('PERIODO', inplace=True)
    # Extranjeros
    df2 = dft.merge(dfn,  how='left', left_index=True, right_index=True)
    df2['Valor_z'] = df2['Valor_x'] - df2['Valor_y']
    df2 = df2.sort_values('PERIODO')
    df2.set_axis(['Totales', 'Españoles', 'Extranjeros'], axis=1, inplace=True)

    titulo3 = 'Castilla_Leon_Pernoctaciones'
    # Total
    dft = df.loc[df['COD'] == 'EOT1568']
    dft = dft[['PERIODO', 'Valor']]
    dft.set_index('PERIODO', inplace=True)
    # Nacional
    dfn = df.loc[df['COD'] == 'EOT1569']
    dfn = dfn[['PERIODO', 'Valor']]
    dfn.set_index('PERIODO', inplace=True)
    # Extranjeros
    df3 = dft.merge(dfn,  how='left', left_index=True, right_index=True)
    df3['Valor_z'] = df3['Valor_x'] - df3['Valor_y']
    df3 = df3.sort_values('PERIODO')
    df3.set_axis(['Totales', 'Españoles', 'Extranjeros'], axis=1, inplace=True)

    titulo4 = 'Zamora_Pernoctaciones'
    # Total
    dft = df.loc[df['COD'] == 'EOT1622']
    dft = dft[['PERIODO', 'Valor']]
    dft.set_index('PERIODO', inplace=True)
    # Nacional
    dfn = df.loc[df['COD'] == 'EOT1623']
    dfn = dfn[['PERIODO', 'Valor']]
    dfn.set_index('PERIODO', inplace=True)
    # Extranjeros
    df4 = dft.merge(dfn,  how='left', left_index=True, right_index=True)
    df4['Valor_z'] = df4['Valor_x'] - df4['Valor_y']
    df4 = df4.sort_values('PERIODO')
    df4.set_axis(['Totales', 'Españoles', 'Extranjeros'], axis=1, inplace=True)

    # Plotting
    fig, ([ax1, ax2], [ax3, ax4]) = plt.subplots(2, 2, figsize=(12, 4))
    df1.plot(ax=ax1, lw=1,
             title='{} ({})'.format(titulo1, x[-1]))
    ax1.grid(axis='y', color='red', linestyle='--', linewidth=0.5)

    df2.plot(ax=ax2, lw=1,
             title='{} ({})'.format(titulo2, x[-1]))
    ax2.grid(axis='y', color='red', linestyle='--', linewidth=0.5)

    df3.plot(ax=ax3, lw=1,
             title='{} ({})'.format(titulo3, x[-1]))
    ax3.grid(axis='y', color='red', linestyle='--', linewidth=0.5)

    df4.plot(ax=ax4, lw=1,
             title='{} ({})'.format(titulo4, x[-1]))
    ax4.grid(axis='y', color='red', linestyle='--', linewidth=0.5)

    plt.show()
    fig.savefig("{}.png".format(titulo))


def grafica():
    ''' Describe la funcion aquí'''
    logger = logging.getLogger('__'+sys._getframe().f_code.co_name)
    logger.disabled = GLOG
    logger.info('')
    # ******** codigo de la funcion *******

    # Cálculo de los puntos x,y de la funcion
    x = np.arange(0, 4*np.pi, 0.1)  # Valores de X
    y = np.sin(x)  # Valores de la función seno
    # y = np.log(x)  # Valores de la función logaritmo neperiano

    # Dibuja el grafico
    plt.plot(x, y)
    # add title - titulo
    plt.title('Función SENO')
    # add x and y labels - etiquetas
    plt.xlabel('Eje x')
    plt.ylabel('Eje y')
    # Dibujamos la retícula
    plt.grid(True)
    plt.grid(color='red', linestyle='--', linewidth=1)
    plt.show()  # Muestra el gráfico

    return None

    # PROGRAMA PRINCIPAL


def main():
    ''' Funcion main '''
    try:
        # Bajamos el fichero json de la url
        f = 'data.json'
        #f = download_url_json()
        # Transformamos el fichero json a  df
        df = transform_json_df(f, export = True)
        '''
        paint_df0(df, 'Nacional. Viajeros', 'EOT1', 'EOT9', 'EOT17')
        paint_df(df, 'Nacional. Pernoctaciones', 'EOT25', 'EOT33', 'EOT41')
        paint_df(df, 'Castilla y León. Pernoctaciones',
                 'EOT1568', 'EOT1569', 'EOT1570')
        paint_df(df, 'Zamora. Pernoctaciones',
                 'EOT1622', 'EOT1623', '')
        '''
        #paint_df0(df)
    except:  # catch *all* exceptions
        logger.exception('Error: [{}]'.format(sys.exc_info()))


if __name__ == "__main__":
    start = time.perf_counter()
    assert sys.version_info >= (3, 7), "Script requires Python 3.7+."
    here = pathlib.Path(__file__).parent
    logger.info(here)
    logger.info('Initium novum')  # Inicio
    # ************************************
    main()
    # *************************************
    logger.info('Ave verum')  # Fin
    elapsed = time.perf_counter() - start
    logger.info(f"Program completed in {elapsed:0.5f} seconds.")
