#!/usr/bin/env python3
# turismo_download.py

"""Descarga de Datos de turismo"""

# Librerias generales
import logging
import sys
import time
import pathlib

# Librerias del proyecto

import requests
import json
import pandas as pd
import numpy as np
import sqlite3
from datetime import datetime


# 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 y serie temporal'''
    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']]
        column_names = ['COD', 'CATEGORIA']
        df_categorias = df_categorias.set_axis(column_names, axis = 1) # Cambia el nombre de las columnas
        # Elimino texto redundante
        df_categorias['CATEGORIA'] = df_categorias['CATEGORIA'].replace({' Total categorías.':''}, regex = True)
        df_categorias['CATEGORIA'] = df_categorias['CATEGORIA'].replace({' Dato base.':''}, regex = True)
        # Quito los blancos de los nombres de la columnas                  
        df_categorias.columns = df_categorias.columns.str.strip()
        # Quito los blancos del inicio y del final de todos los datos de la tabla.
        df_categorias[df_categorias.columns] = df_categorias.apply(lambda x: x.str.strip())                     
        # Divido la columna en varias
        df_categorias_expand = df_categorias['CATEGORIA'].str.split('.', expand = True)
        # Tomo las tres primeras columnas
        df_categorias_expand = df_categorias_expand.iloc[:,[0,1,2]]
        # Renombro las columnas
        df_categorias_expand.columns = ['NACIONAL', 'VIAJEROS', 'TOTAL']
        # Concateno la columna dividida con el df original
        df_categorias = pd.concat([df_categorias, df_categorias_expand], axis = 1).reset_index(drop=True)
        # Quito los blancos del inicio y del final de todos los datos de la tabla.
        #df_categorias['VIAJEROS'] = df_categorias['VIAJEROS'].str.strip()
        df_categorias[df_categorias.columns] = df_categorias.apply(lambda x: x.str.strip()) 
        # Variable con todos los codigosde categorias
        categorias_all = df_categorias['COD'].tolist()
        # 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
        
        categorias = categorias_all # Todas las categorias
        
        # Añadimos 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
            df_cat = df_cat.sort_values('Fecha')
            df_cat['VALOR_12'] = df_cat['Valor'].shift(12)
            df_cat['VALOR_VAR12'] = round((df_cat['Valor']-df_cat['VALOR_12'])*100/df_cat['VALOR_12'],2)
            df_cat.replace([np.inf, -np.inf, '',np.nan], 0, inplace = True)
            # Añadimos el PERIODO juntando dos columnas
            df_cat['PERIODO'] = df_cat['Anyo'].astype(str) + df_cat['T3_Periodo'].astype(str)
            frames = [df0, df_cat]  # Para concatenar todas las categorias
            df_cat = pd.concat(frames, join="outer").reset_index(drop=True)
            df0 = df_cat
        df0 = df0[['Fecha','PERIODO', 'Anyo','T3_Periodo','Valor', 'VALOR_12', 'VALOR_VAR12', 'COD', 'NOMBRE']]
        column_names = ['FECHA', 'PERIODO','ANYO', 'MES', 'VALOR','VALOR_12', 'VALOR_VAR12', 'COD', 'CATEGORIA']
        df0 = df0.set_axis(column_names, axis = 1) # Cambia el nombre de las columnas
        df0['CATEGORIA'] = df0['CATEGORIA'].replace({' Total categorías.':''}, regex = True)
        df0['CATEGORIA'] = df0['CATEGORIA'].replace({' Dato Base.':''}, regex = True)
        df0 = df0.sort_values(by = ['COD','FECHA'], ascending = [False, False])
        #df0['VALOR_12'] = df0['VALOR'].shift(12)
        #df0['VALOR_VAR12'] = round((df0['VALOR']-df0['VALOR_12'])*100/df0['VALOR_12'],2)
        #df0['PERIODO'] = pd.to_datetime(df0.index)
        #df0['PERIODO'] = df0['FECHA'].apply(lambda x: calendario(x)[7])
        #df0.replace([np.inf, -np.inf], 0, inplace = True)
        print(df0.dtypes)
        # Añadimos el PERIODO juntando dos columnas
        # df0['PERIODO'] = df0['Anyo'].astype(str).str.split('.',1)[0] + df0['T3_Periodo'].astype(str)
        # Exporta el fichero de pernoctaciones
        path = 'd_turismo.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, df_categorias
    

def carga_df_bd (df, bd = '/var/www/html/lartica/db.sqlite3', tabla = 'TURISMO_00'):
    ''' Carga el dataframe en tabla de la bd.sqlite3 '''
    
    logger = logging.getLogger('__' + sys._getframe().f_code.co_name)
    logger.disabled = False
    
    try:
         
        logger.info(tabla)
        con = sqlite3.connect(bd) # Conexión
        #cur = con.cursor() # Cursor
        df.to_sql(tabla, con, if_exists = "replace") # df to bd
        con.close() # Cierre de conexion

    except:  # catch *all* exceptions
        logger.exception('Error: [{}]'.format(sys.exc_info()))
    


# 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, df_categorias = transform_json_df(f, export = True)
        # Carga el dataframe en la tabla TURISMO_OO de la db.sqlite3
        carga_df_bd (df, bd = '/var/www/html/lartica/db.sqlite3', tabla = 'Turismo')
        carga_df_bd (df_categorias, bd = '/var/www/html/lartica/db.sqlite3', tabla = 'TurismoCategoria')
  
    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.")
