import mysql.connector
from mysql.connector import Error
import re
import datetime
import sys

def obtener_conexion():
    print(f"--- Control de Campos Ajenos ({datetime.date.today()}) ---")
    print("Por favor, introduce las credenciales de la Base de Datos:")
    host = input("Host (ej. localhost): ")
    user = input("Usuario: ")
    password = input("Contraseña: ")
    database = input("Nombre de la Base de Datos: ")
    
    try:
        conexion = mysql.connector.connect(
            host=host,
            user=user,
            password=password,
            database=database
        )
        if conexion.is_connected():
            print("\n[✓] Conexión establecida con éxito. Descargando estructura...")
            return conexion
    except Error as e:
        print(f"\n[X] Error al conectar a la base de datos: {e}")
        return None

def analizar_estructura(conexion):
    cursor = conexion.cursor(dictionary=True)
    
    # 1. Obtener todas las tablas existentes
    cursor.execute("SHOW TABLES")
    tablas_raw = cursor.fetchall()
    tablas = [list(t.values())[0] for t in tablas_raw]
    
    campos_sin_comentario = []
    alertas_por_nombre = []
    
    # Patrón para identificar posibles claves ajenas por convención de nombre
    patron_fk = re.compile(r'(_id|id_|cod_|_cod|_ref)$', re.IGNORECASE)

    for tabla in tablas:
        # 2. Consultar el diccionario de datos de las columnas
        cursor.execute(f"""
            SELECT COLUMN_NAME, COLUMN_COMMENT 
            FROM INFORMATION_SCHEMA.COLUMNS 
            WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = '{tabla}'
        """)
        columnas = cursor.fetchall()
        
        for col in columnas:
            nombre_col = col['COLUMN_NAME']
            comentario = col['COLUMN_COMMENT'].strip() if col['COLUMN_COMMENT'] else ""
            
            # Omitir la clave primaria de la propia tabla para evitar falsos positivos
            if nombre_col.lower() in ['id', f'id_{tabla}', f'{tabla}_id']:
                continue

            # Caso A: El campo carece de comentarios
            if not comentario:
                campos_sin_comentario.append((tabla, nombre_col))
                if patron_fk.search(nombre_col):
                    alertas_por_nombre.append((tabla, nombre_col, "Campo clave aparente sin comentar"))
            
            # Caso B: Tiene comentario, pero por nombre parece una relación y el comentario no nombra ninguna tabla
            else:
                if patron_fk.search(nombre_col):
                    menciona_tabla = any(t.lower() in comentario.lower() for t in tablas)
                    if not menciona_tabla:
                        alertas_por_nombre.append((tabla, nombre_col, f"Comentario actual: '{comentario}'"))

    cursor.close()
    conexion.close()
    
    # --- REPORTES Y ALERTAS ---
    print("\n==================================================")
    print("              REPORTE DE REVISIÓN                 ")
    print("==================================================")
    
    if campos_sin_comentario:
        print(f"\n[⚠️ ADVERTENCIA] Se encontraron {len(campos_sin_comentario)} campos generales sin comentarios:")
        for t, c in campos_sin_comentario:
            print(f"  - Tabla: '{t}' -> Campo: '{c}'")
    else:
        print("\n[✓] Todos los campos disponen de documentación básica.")

    if alertas_por_nombre:
        print("\n[❌ CRÍTICO] Campos con nomenclatura de clave ajena sin asignación de tabla en comentario:")
        for t, c, motivo in alertas_por_nombre:
            print(f"  - Tabla: '{t}' -> Campo: '{c}' ({motivo})")
        
        print("\n--------------------------------------------------")
        print("SOLICITUD DE ACCIÓN: Por favor, compruebe si la información descargada es correcta.")
        print("Corrija el diccionario de la base de datos añadiendo la relación en el comentario del campo.")
        print("--------------------------------------------------")
        sys.exit(1) # Finaliza con error para integración con Hooks
    else:
        print("\n[✓] ÉXITO: Estructura de claves ajenas por código validada correctamente.")
        sys.exit(0)

if __name__ == "__main__":
    db_conn = obtener_conexion()
    if db_conn:
        analizar_estructura(db_conn)