"""
CampoMAG fue desarrollado por:

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

import psycopg2
import psycopg2.errorcodes
from psycopg2 import OperationalError

import subprocess
import os

from qgis.PyQt.QtCore import QSettings, QTranslator, QCoreApplication
from qgis.PyQt.QtGui import QIcon
from qgis.PyQt.QtWidgets import QAction, QMenu, QMessageBox
from qgis.utils import iface
from qgis.core import QgsProject, QgsLayerTreeGroup, QgsEditorWidgetSetup, QgsDataSourceUri, QgsVectorLayer

from PyQt5 import uic # de todas las librerias solo necesito en este caso la uic

def conexion(hostt, puerto, usuario, contra, nombre_db):
    # Conecta a PostgreSQL para crear la base de datos (asegúrate de reemplazar los valores con los tuyos)
    # Guarda los valores de los widgets de entrada de texto en las variables
    try:
        conexion = psycopg2.connect(
            database="postgres",
            user=str(usuario),
            password=str(contra),
            host=str(hostt),
            port=str(puerto)
        )

        # permite que cada consulta que se ejecute se confirme automaticamente
        conexion.autocommit = True

        # Crear una instancia del cursor para crear la base de datos
        cursor = conexion.cursor()

        # Nombre de la nueva base de datos y consulta SQL para crearla

        crear_db = f"CREATE DATABASE {nombre_db}"

        # Ejecuta la consulta para crear la nueva base de datos
        cursor.execute(crear_db)

        # Cierra el cursor y la conexión
        cursor.close()
        conexion.close()

        # me conecto a la base de datos que acabo de crear
        conexion = psycopg2.connect(
            database=str(nombre_db),
            user=str(usuario),
            password=str(contra),
            host=str(hostt),
            port=str(puerto)
        )

        conexion.autocommit = True

        # Crear una instancia del cursor para crear la base de datos
        cursor = conexion.cursor()

        cursor.execute("CREATE EXTENSION postgis;")

        # Ruta de la carpeta que contiene la geodatabase (GDB)
        gdb_folder = os.path.abspath(os.path.join(os.path.dirname(__file__), 'DataBase_schema'))
        # Nombre de la geodatabase
        gdb_name = 'BD_ANLA_MAGNA_NACIONAL.gdb'
        # Ruta completa de la geodatabase
        gdb_path = os.path.join(gdb_folder, gdb_name)

        # Define las rutas relativas a tus archivos y el comando GDAL.
        comando_gdal = [
            'ogr2ogr',
            '-f', 'PostgreSQL',
            f'PG:host={hostt} port={puerto} user={usuario} password={contra} dbname={nombre_db}',
            gdb_path,
            '-overwrite',
            '-progress',
            '--config', 'PG_USE_COPY', 'YES'
        ]

        # Ejecuta el comando GDAL desde Python.
        subprocess.run(comando_gdal, shell=True)

        cursor.execute("CREATE TABLE tab_fotos (key_Rel varchar (72), Foto varchar(100));")

        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])

        uri = QgsDataSourceUri()
        uri.setConnection(hostt, puerto, nombre_db, usuario, contra)


        for i in lista:
            cursor.execute(
                f"""
                SELECT table_name, column_name
                FROM information_schema.columns
                WHERE table_name = '{i}'
                AND udt_name = 'geometry';
                """
            )


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

            if lista2 != []:
                uri.setDataSource("public", lista2[0][0], lista2[0][1])
                vlayer = QgsVectorLayer(uri.uri(False), lista2[0][0], "postgres")

                # Obtener el índice del campo que quieres eliminar
                indice_ob = vlayer.fields().indexFromName("objectid")
                indice_long = vlayer.fields().indexFromName("shape_length")
                indice_area = vlayer.fields().indexFromName("shape_area")

                print(f"Nombre de la capa: {vlayer.name()}")

                # Verificar si el campo existe antes de intentar eliminarlo

                if indice_long != -1:
                    print(f'mi tabla {i} tiene length')
                    # Eliminar el campo
                    cursor.execute(
                        f"""
                        ALTER TABLE {i}
                        DROP shape_length;
                        """
                    )

                if indice_area != -1:
                    print(f'mi tabla {i} tiene area')
                    # Eliminar el campo
                    cursor.execute(
                        f"""
                        ALTER TABLE {i}
                        DROP shape_area;
                        """
                    )
                '''
                if indice_ob != -1:
                    print(f'mi tabla {i} tiene objectID')
                    # Eliminar el campo
                    cursor.execute(
                        f"""
                        ALTER TABLE {i}
                        DROP objectid;
                        """
                    )
                '''

            if i != 'tab_fotos':
                cursor.execute(
                    f"""
                    ALTER table {i}
                    ADD key_rel varchar(71);
                    """
                )

        # Cierra el cursor y la conexión
        cursor.close()
        conexion.close

        QMessageBox.information(None, "Mensaje", f"Se ha creado la base de datos {nombre_db} con el modelo MAG")

    except OperationalError as e:
        # Maneja los errores específicos de psycopg2
        if not hostt or not puerto or not usuario or not contra or not nombre_db:
            print("Todos los campos son obligatorios")
            QMessageBox.warning(None, "Mensaje", "Todos los campos son obligatorios")
        else:
            print("Error al conectarse a PostgreSQL:", str(e))
            QMessageBox.warning(None, "Mensaje", "Error al conectarse a PostgreSQL")
    except Exception as e:
        if e.pgcode == psycopg2.errorcodes.DUPLICATE_DATABASE:
            QMessageBox.warning(None, "Mensaje", f"{e}")
        else:
            QMessageBox.warning(None, "Mensaje", f"{e}")

