"""
CampoMAG fue desarrollado por:

William Huertas – wfhuertasg@gmail.com
Linda Maldonado - lkmaldonadoo999@gmail.com
"""

from qgis.core import QgsProject, QgsVectorLayer, QgsVectorLayerEditUtils, QgsFeature, QgsDataSourceUri
from qgis.PyQt.QtWidgets import QAction, QMenu, QMessageBox
import psycopg2

def cargar_a_BD(hostt, puerto, usuario, contra, nombre_db):
    # Conecta a la base de datos
    conn = psycopg2.connect(
        host=hostt,
        port=puerto,
        database=nombre_db,
        user=usuario,
        password=contra,
    )

    # Obtén un cursor
    cursor = conn.cursor()

    # Obtén el proyecto actual
    project = QgsProject.instance()

    # Obtén una lista de capas cargadas en QGIS
    layers = project.mapLayers().values()

    cursor.execute(
        "SELECT table_name FROM information_schema.tables WHERE table_schema='public' AND table_type = 'BASE TABLE' AND table_name <> 'spatial_ref_sys';")

    # guardo el nombre de las tablas en una lista
    lista = []
    for row in cursor:
        lista.append(row[0])

    # Itera sobre las capas
    for layer in layers:
        # Verifico que mi capa sea VectorLayer (shape o tabla)
        if isinstance(layer, QgsVectorLayer):
            # verifico si mi capa tiene o no registros
            if layer.featureCount() > 0:
                # Configuración de la conexión a la base de datos PostGIS
                uri = QgsDataSourceUri()
                # 'Host', 'Puerto', 'nombre_de_tu_base_de_datos', 'tu_usuario', 'tu_contraseña'
                uri.setConnection(hostt, puerto, nombre_db, usuario, contra)

                # Nombre de la tabla en PostGIS donde deseas guardar los datos
                nombre_tabla_postgis = layer.name()
                print(f'se han cargado datos para la capa: {nombre_tabla_postgis}\n')

                cursor.execute(
                    f"""
                SELECT table_name, column_name
                FROM information_schema.columns
                WHERE table_name = '{nombre_tabla_postgis}'
                AND udt_name = 'geometry';
                """
                )

                # Guardo los valores de la consulta (nombre de la tabla y nombre de la colum con geometria)
                lista2 = []
                for j in cursor:
                    lista2.append(j)

                # valido que mi capa exista en la base de datos
                if lista2 != []:
                    # Configurar la capa PostGIS
                    # nombre tabla, nombre de la colum con geometria
                    uri.setDataSource("", lista2[0][0], lista2[0][1])
                    capa_postgis = QgsVectorLayer(uri.uri(), lista2[0][0], 'postgres')

                    # Iniciar la edición en la capa PostGIS
                    capa_postgis.startEditing()

                    # Itera sobre las características y omite atributos específicos
                    for original_feature in layer.getFeatures():
                        # Crea una nueva característica y entrego los atributos de mi capa original
                        new_feature = QgsFeature(original_feature.fields())

                        # Configura la geometría de la nueva característica
                        new_feature.setGeometry(original_feature.geometry())

                        # Itera sobre los campos y atributos originales y omite algunos
                        ind = 0
                        for field in original_feature.fields():

                            if field.name() not in []:
                                new_feature.setAttribute(ind, original_feature[field.name()])
                                ind += 1

                        new_feature.deleteAttribute(0)

                        # Agrega la nueva característica a la capa PostGIS
                        capa_postgis.dataProvider().addFeatures([new_feature])

                    capa_postgis.commitChanges()
                else:
                    if layer.name() in lista:
                        print(f'se han cargado datos para la tabla: {nombre_tabla_postgis}\n')

                        uri.setDataSource("", layer.name(), '')
                        capa_postgis = QgsVectorLayer(uri.uri(), layer.name(), 'postgres')

                        # Iniciar la edición en la capa PostGIS
                        capa_postgis.startEditing()

                        # Itera sobre las características y omite atributos específicos
                        for original_feature in layer.getFeatures():
                            # Crea una nueva característica y entrego los atributos de mi capa original
                            new_feature = QgsFeature(original_feature.fields())

                            # Itera sobre los campos y atributos originales y omite algunos
                            ind = 0
                            for field in original_feature.fields():
                                if field.name() not in []:
                                    new_feature.setAttribute(ind, original_feature[field.name()])
                                    ind += 1

                            new_feature.deleteAttribute(0)

                            # Agrega la nueva característica a la capa PostGIS
                            capa_postgis.dataProvider().addFeatures([new_feature])

                        capa_postgis.commitChanges()

    # Cierra la conexión
    conn.close()

    QMessageBox.information(None, "Mensaje", f"La informacion a sido subida a la Base de datos {nombre_db}")