# -*- coding: utf-8 -*-
"""
/***************************************************************************
 Sewercalc
                                 A QGIS plugin
 Plugin para dimensionamento de redes coletoras de esgoto 
 Generated by Plugin Builder: http://g-sherman.github.io/Qgis-Plugin-Builder/
                              -------------------
        begin                : 2025-02-07
        git sha              : $Format:%H$
        copyright            : (C) 2025 by Wanderilo  Lima
        email                : Wanderilo Lima
 ***************************************************************************/

/***************************************************************************
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 ***************************************************************************/
"""

from PyQt5.QtCore import QVariant, QTimer
from qgis.PyQt.QtCore import QStandardPaths
from PyQt5.QtWidgets import QLabel
from qgis.utils import iface
from qgis.core import QgsProject, Qgis, QgsProcessingException, QgsRaster, QgsFeature, QgsGeometry, QgsField, QgsVectorLayer
import numpy as np
import os
import json
import time

from .Sewercalc_Add_colunas_funcao import Add_colunas
from .Sewercalc_Dimensionamento import calcular_parametros
from .Sewercalc_Informacoes import parametros, obter_db_camada, classificar_trechos, verificar_camadas
from .Sewercalc_Verifica_erros import  verificar_erro_pv, verificar_erro_rede
from .Sewercalc_Estilo import aplicar_estilo
from .Sewercalc_config_cx_txt import carregar_configuracoes, salvar_configuracoes, limpar_json
from .Sewercalc_Planilha import salvar_planilha
from .Sewercalc_Pontos_criticos import pontos_criticos
from .Sewercalc_Export_xml import criar_landxml
import time

# Variável global para armazenar os tempos
tempos_execucao = []

def iniciar_monitoramento():
    global tempos_execucao
    tempos_execucao = [("Início", time.time())]

def registrar_checkpoint(mensagem):
    tempos_execucao.append((mensagem, time.time()))

def imprimir_resultados():
    if not tempos_execucao:
        print("Monitoramento não foi iniciado")
        return
    
    print("\n=== TEMPO DE EXECUÇÃO ===")
    inicio_total = tempos_execucao[0][1]
    
    for i in range(1, len(tempos_execucao)):
        mensagem, tempo = tempos_execucao[i]
        tempo_decorrido = tempo - inicio_total
        tempo_segmento = tempo - tempos_execucao[i-1][1]
        
        print(f"[{tempo_decorrido:.4f}s] {mensagem}")
        print(f"   ⏱️ Tempo deste passo: {tempo_segmento:.4f}s")
    
    tempo_total = time.time() - inicio_total
    print(f"\n⏳ Tempo total: {tempo_total:.4f} segundos")
    
#-----------------------------------------------------------------------------------------------------------------
def dimensionar(planilha, xml, p_critico):
    inicio = time.time()
    iniciar_monitoramento()#**********************************************************************************************************************************************
    
    configuracoes = carregar_configuracoes()
    
    #------------------VERIFICAR EXISTENCIA DE CAMADAS-------------------------------
    if p_critico == "sim":
        camadas_verificar = ["PV", "REDE", "MDE"]
    else:
        camadas_verificar = ["PV", "REDE"]

    nao_encontradas = verificar_camadas(camadas_verificar)
    if nao_encontradas:
        mensagem = "Camadas não encontradas: " + ", ".join(nao_encontradas)
        iface.messageBar().pushMessage(
            "Erro", 
            mensagem,
            level=Qgis.Critical, 
            duration=10  
        )
        return

    #----------------------------------------------------------------
    
    camada_rede = configuracoes.get("camada_rede")
    camada_pv = configuracoes.get("camada_pv") 
    camada_mde = configuracoes.get("camada_mde")
    db_param = parametros()
    tabela_rede = obter_db_camada(camada_rede)
    tabela_pv = obter_db_camada(camada_pv)
    

    #verificar erros nas camadas----------------------------------------
    Erros_PV  = 0
    Erros_rede = 0

    Erros_PV = verificar_erro_pv(tabela_pv)
    Erros_rede = verificar_erro_rede(tabela_rede)

    if Erros_PV == 1 and Erros_rede == 1:
        mensagem = ("Execução interrompida: Há ausência de dados na camada dos PVs e da Rede Coletora.\n\n|VERIFIQUE E TENTE NOVAMENTE|")
        iface.messageBar().pushMessage(
            "Erro", 
            mensagem,
            level=Qgis.Critical, 
            duration=10  
        )
        return
    elif Erros_PV == 1:
        mensagem = ("Execução interrompida: Há ausência de dados na camada dos PVs.\n\n|VERIFIQUE E TENTE NOVAMENTE|")
        iface.messageBar().pushMessage(
            "Erro", 
            mensagem,
            level=Qgis.Critical, 
            duration=10  
        )
        return
    elif Erros_rede == 1:
        mensagem = ("Execução interrompida: Há ausência de dados na camada da Rede Coletora.\n\n|VERIFIQUE E TENTE NOVAMENTE|")
        iface.messageBar().pushMessage(
            "Erro", 
            mensagem,
            level=Qgis.Critical, 
            duration=10  
        )
        return

    
    tabela_rede = classificar_trechos(tabela_rede, tabela_pv) #CLASSIFICAÇÃO, SUPER IMPORTANTE ---------------------------------
    # -------------------------------
    pop_inicial = float(configuracoes.get("Edit_Pini", 0))
    pop_final = float(configuracoes.get("Edit_Pfim", 0))
    cons_per_capita = float(configuracoes.get("Edit_consumo", 0))
    k1 = float(configuracoes.get("Edit_k1", 0))
    k2 = float(configuracoes.get("Edit_k2", 0))
    coef_retorno = float(configuracoes.get("Edit_Retorno", 2))
    tx_inf = float(configuracoes.get("Edit_tx_infiltra", 0))
    compr = round(db_param.L,2)
    compr_T = round(db_param.LT,2)
    db_degraus = db_param.DN_tab
    db_DI = db_param.DI_tab

    #CALCULANDO VAZOES-------------------------------
    vazao_ini = round(((pop_inicial * cons_per_capita * k2 * coef_retorno) / 86400) + (compr * (tx_inf / 1000)), 3)  # l/s
    vazao_fim = round(((pop_final * cons_per_capita * k1 * k2 * coef_retorno) / 86400) + (compr * (tx_inf / 1000)), 3)  # l/s
    tx_contr_ini = round(vazao_ini / compr, 5)  # l/s*m
    tx_contr_fim = round(vazao_fim / compr, 5)  # l/s*m


    #--------------------------------------------------
    #ADICIONANDO COLUNA VAZÃO EM CADA PV NA TABELA DO DICIONARIO
    for feicao in tabela_pv.values():
        feicao['Q_INI'] = 0
        feicao['Q_FIM'] = 0
        feicao['PF'] = 0
        if feicao['CAT'] == "PS":
            feicao['RECOBR'] = float(configuracoes.get("Edit_R_min", 0))
        else :
            feicao['RECOBR'] = 0
    
    # -------------------------------------
    def encontrar_id(nome_pv):
        for id_pv, dados in tabela_pv.items():
            if dados['NOME'] == nome_pv:
                return id_pv
        return None
        
        
    #função para conversão dos dados Qvariant----------------------
    def to_float(value):
        if value is None:
            return 0.0
        elif isinstance(value, (int, float)):
            return float(value)
        elif isinstance(value, QVariant):
            if value.isNull():
                return 0.0
            py_value = value.value()  
            if isinstance(py_value, (int, float)):
                return float(py_value)
            else:
                raise ValueError(f"Não foi possível converter o QVariant: {value}")
        else:
            raise ValueError(f"Não foi possível converter o valor: {value}")


    registrar_checkpoint("Coletas das informações e verificação de erros das camadas e classificação dos trechos")#************************************************************************************************************
    Rmin = float(configuracoes.get("Edit_R_min", 0))
    T = float(configuracoes.get("Edit_Tensao", 0))
    n= float(configuracoes.get("Edit_manning", 0))
    
    # PERCORRENDO CADA TRECHO ##########################################################################################
    for feicao_id, col in tabela_rede.items():  
        
        
        L = col['L']
        Contrib = col['CONTRIB']

        pv_mont = col['PV_MONT']
        pv_jus = col['PV_JUS']

        id_pv_mont = encontrar_id(pv_mont)
        id_pv_jus = encontrar_id(pv_jus)

        Q_mont_ini = to_float(tabela_pv[id_pv_mont]['Q_INI'])
        Q_mont_fim = to_float(tabela_pv[id_pv_mont]['Q_FIM'])

        Q_jus_ini = to_float(tabela_pv[id_pv_jus]['Q_INI'])
        Q_jus_fim = to_float(tabela_pv[id_pv_jus]['Q_FIM'])

        Q_pont_mont_ini = to_float(tabela_pv[id_pv_mont]['Q_PONT_INI'])#-----------------------------------------------------
        Q_pont_mont_fim = to_float(tabela_pv[id_pv_mont]['Q_PONT_FIM'])

        #---------------INICIO DE PLANO-------------------------------
        if Contrib == "SIM":
            Q_tch_ini = tx_contr_ini * L
        '''elif Contrib == "NÃO":
            Q_tch_ini = 1.5'''
        
        Q_mont_ini = Q_mont_ini + Q_pont_mont_ini
        Q_jus_ini = Q_mont_ini + Q_tch_ini + Q_jus_ini

        tabela_pv[id_pv_jus]['Q_INI'] = round(Q_jus_ini,4)
        col['Q_TCH_INI'] = round(Q_tch_ini,4) #Q trecho inicio de plano
        col['Q_ACM_INI'] = round(Q_mont_ini + Q_tch_ini ,4) #Q acumulado trecho inicio de plano

        #--------------FIM DE PLANO-------------------------------
        if Contrib == "SIM":
            Q_tch_fim = tx_contr_fim * L #l/s
            
        Q_mont_fim = Q_mont_fim + Q_pont_mont_fim
        Q_jus_fim = Q_mont_fim + Q_tch_fim + Q_jus_fim #vazão jusante do pv
    
        tabela_pv[id_pv_jus]['Q_FIM'] = round(Q_jus_fim,4)
        col['Q_TCH_FIM'] = round(Q_tch_fim,4)
        col['Q_ACM_FIM'] = round(Q_mont_fim + Q_tch_fim,4)

        #--------------COTAS DE TOPO-------------------------------
        CTM =  to_float(tabela_pv[id_pv_mont]['CT'])
        CTJ =  to_float(tabela_pv[id_pv_jus]['CT'])

        col['CTM'] = round(CTM,3)
        col['CTJ'] = round(CTJ,3)

        #----------------------DIMENSIONAMENTO ---------------- 
        Qi = 1.5/1000 if col['Q_ACM_INI'] < 1.5 else col['Q_ACM_INI']/1000
        Qf = 1.5/1000 if col['Q_ACM_FIM'] < 1.5 else col['Q_ACM_FIM']/1000
        i = 0.0001 # chute inicial
        #RM = tabela_pv[id_pv_mont]['RECOBR']
        RM = tabela_pv[id_pv_mont]['PF'] - 0.150 #----alterada para igualar geratriz inferior (profundidade do pv menos o DN minimo)
        if RM < Rmin:
            RM = Rmin

        
        if RM < 0.6:
            print(f"Erro no trecho {col['NOME']}, com RM de {RM} ") # -------------------------------------APAGAR

        
        RJ_calc = CTJ - (CTM - RM - (L * i))
        if RJ_calc < Rmin :
            i = ((CTM + Rmin - CTJ - RM) / L )

        
        #-----------------------RESULTADOS-------------------------------------------
        resultados = calcular_parametros(Qi, Qf, i, n, CTM, CTJ, RM, Rmin, L, T, "D75", db_degraus)
                                        
        if resultados['RJ'] < 0.6:
            print(f"Erro no dimensionamento do trecho {col['NOME']}, com RJ de {resultados['RJ']} ") # -------------------------------------APAGAR
            
        VF = round(resultados['V_fim'],6)
        VC = round(resultados['Vc'],6)
        if  VF > VC:
            resultados = calcular_parametros(Qi, Qf, i, n, CTM, CTJ, RM, Rmin, L, T, "D50", db_degraus)

        #recobrimento______________________________________
        if tabela_pv[id_pv_jus]['RECOBR'] < resultados['RJ']:
            tabela_pv[id_pv_jus]['RECOBR'] = round(resultados['RJ'],3)

        #else:
            #tabela_pv[id_pv_jus]['RECOBR'] = round(tabela_pv[id_pv_jus]['RECOBR'],3)
            
            
            
        #Adicionando informações_________________________
        col['DIAM'] = round(resultados['D'],4)
        col['DN'] = resultados['DN']
        col['i'] = round(resultados['i'],6)
        col['Y_INI'] = round(resultados['y_ini'],6)
        col['Y_FIM'] = round(resultados['y_fim'],6)
        col['RH_INI']= round(resultados['Rh_ini'],6)
        col['RH_FIM']= round(resultados['Rh_fim'],6)
        col['VI'] = round(resultados['V_ini'],4)
        col['VF'] = round(resultados['V_fim'],4)
        col['VC'] = round(resultados['Vc'],4)
        col['T'] = round(resultados['T'],3)
        col['TIPO_CALC'] = resultados['Caract_calc']
        col['ESCOAM'] = resultados['Escoamento']

        #manipulando informações__PV_____________________
        #Prof_PVM  = tabela_pv[id_pv_mont]['RECOBR'] + (resultados['DN'])
        Prof_PVM  = RM + (resultados['DN'])
        Prof_PVJ  = tabela_pv[id_pv_jus]['RECOBR'] + (resultados['DN'])
        CFM = CTM - Prof_PVM #Cota de fundo montante  
        CFJ = CTJ - Prof_PVJ
        
        if tabela_pv[id_pv_mont]['PF'] < round(Prof_PVM,3):
            tabela_pv[id_pv_mont]['CTF'] = round(CFM,3)
            tabela_pv[id_pv_mont]['PF'] = round(Prof_PVM,3)
            
        if tabela_pv[id_pv_jus]['PF'] < Prof_PVJ:
            tabela_pv[id_pv_jus]['CTF'] = round(CFJ,3)
            tabela_pv[id_pv_jus]['PF'] = round(Prof_PVJ,3)

        #manipulando informações__REDE_____________________
        Prof_CM = RM + (resultados['DN'])  
        prof_CJ =  resultados['RJ'] + (resultados['DN'])
        CCM = CTM - Prof_CM  
        CCJ = CTJ - prof_CJ 

        col['CCM'] = round(CCM,3)
        col['PFM'] = round(Prof_CM,3)

        col['CCJ'] = round(CCJ,3)
        col['PFJ'] = round(prof_CJ,3)


    registrar_checkpoint("Cálculo de vazão e Dimensionamento")#************************************************************************************************************

    # PERCORRENDO CADA TRECHO ##########################################################################################  
    for feicao_id, col in tabela_rede.items():    

        pv_jus = col['PV_JUS']
        id_pv_jus = encontrar_id(pv_jus)
        
        #verificando Tubo de queda___________________________

        Prof_PVJ = tabela_pv[id_pv_jus]['PF']
        Prof_CJ = col['PFJ']
        Degrau =  round(Prof_PVJ - Prof_CJ,3)

        if col['DN']*1000 > 300:
            valor_degrau_DN = db_degraus.get(300) 
        else:
            valor_degrau_DN = db_degraus.get(col['DN']*1000)

        if Degrau >= valor_degrau_DN :
            col['TQ'] = "SIM"
            col['DG'] = Degrau #metros
            
            if 'TQ1' in tabela_pv[id_pv_jus]:
                if 'TQ2' in tabela_pv[id_pv_jus]:
                    tabela_pv[id_pv_jus]['TQ3'] = col['NOME']
                    tabela_pv[id_pv_jus]['DG_TQ3'] = Degrau
                else:
                    tabela_pv[id_pv_jus]['TQ2'] = col['NOME']
                    tabela_pv[id_pv_jus]['DG_TQ2'] = Degrau
            else:
                tabela_pv[id_pv_jus]['TQ1'] = col['NOME']
                tabela_pv[id_pv_jus]['DG_TQ1'] = Degrau
            
        else:
            col['TQ'] = "NÃO"
            col['DG'] = Degrau   

    #-------------------------------------------------------------
    # ADICIONANDO INFORMAÇÕES NO LAYER REDE ##########################################################################################

    Add_colunas(camada_rede, [
        ("DIAM", QVariant.Double, 10, 3),
        ("DN", QVariant.Double, 10, 3),
        ("i", QVariant.Double, 10, 6),
        ("Q_TCH_INI", QVariant.Double, 10, 4),
        ("Q_ACM_INI", QVariant.Double, 10, 4),
        ("Q_TCH_FIM", QVariant.Double, 10, 4),
        ("Q_ACM_FIM", QVariant.Double, 10, 4),
        ("PFM", QVariant.Double, 10, 3),
        ("PFJ", QVariant.Double , 10, 3),
        ("CTM", QVariant.Double, 10, 3),
        ("CTJ", QVariant.Double, 10, 3),
        ("T", QVariant.Double, 10,3),
        ("DG", QVariant.Double, 10, 3),
        ("TQ", QVariant.String, 10),
        ("VI", QVariant.Double, 10, 4),
        ("VF", QVariant.Double, 10, 4),
        ("VC", QVariant.Double, 10, 4),
        ("Y_INI", QVariant.Double, 10, 4),
        ("Y_FIM", QVariant.Double, 10, 4),
        ("Y_FIM", QVariant.Double, 10, 4),
        ("TIPO_CALC", QVariant.String, 10),
        ("ESCOAM", QVariant.String, 20)
    ])

    layer_rede = QgsProject.instance().mapLayer(camada_rede)
    layer_rede.startEditing()

    # Lista de colunas a serem atualizadas - Os mesmo nome da culuna é o do dicionário
    colunas = ['DN', 'i', 'PFM', 'PFJ', 'CTM', 'CTJ', 'T', 'DG', 'TQ', 'DIAM', 'Q_TCH_INI', 'Q_ACM_INI', 'Q_TCH_FIM', 'Q_ACM_FIM', 'VI', 'VF',
            'VC', 'Y_INI', 'Y_FIM', 'TIPO_CALC', 'ESCOAM']



    for trecho in layer_rede.getFeatures():
        id_trecho = trecho.id() 
        if id_trecho in tabela_rede:
            for coluna in colunas:
                trecho[coluna] = tabela_rede[id_trecho].get(coluna, None)
            layer_rede.updateFeature(trecho) 
    
    layer_rede.commitChanges()
    
    # ADICIONANDO INFORMAÇÕES NO LAYER PV ##########################################################################################           
        
    Add_colunas(camada_pv, [
        ("PF", QVariant.Double, 10, 3),
        ("CTF", QVariant.Double, 10, 3),
        ("TQ1", QVariant.String, 10),
        ("TQ2", QVariant.String, 10),
        ("TQ3", QVariant.String, 10),
        ("DG_TQ1", QVariant.Double, 10,3),
        ("DG_TQ2", QVariant.Double, 10,3),
        ("DG_TQ3", QVariant.Double, 10,3) ])

    layer_pv = QgsProject.instance().mapLayer(camada_pv)
    layer_pv.startEditing()

    # Lista de colunas a serem atualizadas - Os mesmo nome da culuna é o do dicionário
    colunas = ['PF', 'CTF', 'TQ1', 'TQ2', 'TQ3', 'DG_TQ1', 'DG_TQ2', 'DG_TQ3']

    for PV in layer_pv.getFeatures():
        id_PV = PV.id() 
        
        if id_PV in tabela_pv:
            geom = PV.geometry()
            point = geom.centroid().asPoint()
            tabela_pv[id_PV]['x'] = point.x()
            tabela_pv[id_PV]['y'] = point.y()
            
            for coluna in colunas:
                PV[coluna] = tabela_pv[id_PV].get(coluna, None)
            
            layer_pv.updateFeature(PV) 
                
    layer_pv.commitChanges()


    def converter_null(tabela):
        """Converte valores 'NULL' para None e QVariant para tipos Python padrão."""
        if isinstance(tabela, dict):
            return {chave: converter_null(valor) for chave, valor in tabela.items()}
        elif isinstance(tabela, list):
            return [converter_null(item) for item in tabela]
        elif isinstance(tabela, QVariant):  
            return tabela.toPyObject() if hasattr(tabela, "toPyObject") else str(tabela)
        elif tabela == "NULL":
            return None
        return tabela

    tabela_pv_convertido = converter_null(tabela_pv)
    tabela_rede_convertido = converter_null(tabela_rede)
    # Criando tabela para visualização de perfil ---------------------------------------------
    limpar_json("tabela_pv.json")
    limpar_json("tabela_rede.json")
    limpar_json("pontos_criticos.json")
    
    config_dir = QStandardPaths.writableLocation(QStandardPaths.AppDataLocation)
    os.makedirs(config_dir, exist_ok=True)  # Garante que o diretório existe
    
    # Salvar tabela PV
    pv_path = os.path.join(config_dir, "tabela_pv.json")
    pv_temp = pv_path + '.tmp'
    with open(pv_temp, 'w', encoding='utf-8') as f:
        json.dump(tabela_pv_convertido, f, indent=4, ensure_ascii=False)
    if os.path.exists(pv_temp):
        os.replace(pv_temp, pv_path)
        
    # Salvar tabela Rede
    rede_path = os.path.join(config_dir, "tabela_rede.json")
    rede_temp = rede_path + '.tmp'
    with open(rede_temp, 'w', encoding='utf-8') as f:
        json.dump(tabela_rede_convertido, f, indent=4, ensure_ascii=False)
    if os.path.exists(rede_temp):
        os.replace(rede_temp, rede_path)

    
    registrar_checkpoint("Adicionado informações nas camadas trecho e pv")#************************************************************************************************************
    #CRIANDO PLANILHA DE RESULTADOS ##################################################################################
    configuracoes.update({
    "L": compr,          
    "LT": compr_T,          
    "vazao_ini": vazao_ini,    
    "vazao_fim": vazao_fim})
    salvar_configuracoes(configuracoes)
    
    if planilha =="sim":
        caminho_planilha = salvar_planilha(tabela_rede, layer_rede)
    
    registrar_checkpoint("Planilha criada")#************************************************************************************************************  
    # CRIANDO ARQUIVO XML ##########################################################################################  
    
    if xml == "sim":
        crs = layer_rede.crs()
        EPSG = crs.postgisSrid()
        caminho_pv = layer_pv.source()
        pasta_salvar = os.path.dirname(caminho_pv)
        caminho_xml = criar_landxml(tabela_pv, tabela_rede, EPSG, pasta_salvar)
     
    registrar_checkpoint("Arquivo xml criado")#************************************************************************************************************
    # ANALISANDO PONTOS CRÍTICOS NA REDE ##########################################################################################  
    if p_critico == "sim":
        pontos_criticos(camada_rede, camada_mde, configuracoes, tabela_pv, tabela_rede)
    
    
    #FINALIZANDO -------------------------------------------------------------------------------------------------------------       
    aplicar_estilo(camada_pv, "Estilo03_PV.qml")
    aplicar_estilo(camada_rede, "Estilo03_REDE.qml")
    
    
    
    registrar_checkpoint("Pontos Críticos criado")#************************************************************************************************************  
    tempo_decorrido = time.time() - inicio
    
    link_style = "color: red; text-decoration: none;"
    if planilha.lower() == "sim" and xml.lower() == "sim":
        arquivo = os.path.basename(caminho_planilha)
        mensagem = f"""
        <b>Dimensionamento concluído em {tempo_decorrido:.2f}s!</b> | 
        Pasta dos arquivos XML e Planilha: <a href="file:///{caminho_planilha}" style="{link_style}">{arquivo}</a>
        """

    elif planilha.lower() == "sim" and xml.lower() == "nao":
        arquivo = os.path.basename(caminho_planilha)
        mensagem = f"""
        <b>Dimensionamento concluído em {tempo_decorrido:.2f}s!</b> | 
        Pasta da planilha salva: <a href="file:///{caminho_planilha}" style="{link_style}">{arquivo}</a>
        """

    elif planilha.lower() == "nao" and xml.lower() == "sim":
        arquivo = os.path.basename(caminho_xml)
        mensagem = f"""
        <b>Dimensionamento concluído em {tempo_decorrido:.2f}s!</b> | 
        Arquivo LandXML gerado: <a href="file:///{caminho_xml}" style="{link_style}">{arquivo}</a>
        """

    else:
        mensagem = f"""
        <b>Dimensionamento concluído em {tempo_decorrido:.2f}s!</b>
        """

    iface.messageBar().pushMessage(
        "",  # Título vazio
        mensagem, 
        level=Qgis.Success,
        duration=25
)
    
    imprimir_resultados()
    