# my_profile.py
import sys
import os
import shutil
import requests
import paramiko
from ftplib import FTP
import json
from dotenv import load_dotenv
# Cargar las variables de entorno desde el archivo .env

#load_dotenv('/var/www/html/api/crm/configuraciones/.env')
# Obtener la ruta absoluta del script (crm/)
script_dir = os.path.dirname(os.path.abspath(__file__))  # Directorio del script
crm_dir = os.path.dirname(script_dir)  # Sube un nivel hasta crm
env_path = os.path.join(crm_dir, "configuraciones", ".env")  # Ahora sí apunta bien

load_dotenv(env_path)




# Agrega la ruta absoluta al sys.path
sys.path.append('/var/www/html/config')

from cnxpdo import get_connection

from datetime import datetime
import hashlib


def consultarAreas():
    conexionBD = get_connection()
    if conexionBD is None:
        return {"success": 0, "message": "Error de conexión"}

    try:
        query = "SELECT * FROM empleados_areas"
        cursor = conexionBD.cursor(dictionary=True)
        cursor.execute(query)
        areas = cursor.fetchall()

        cursor.close()
        conexionBD.close()
        

        if areas:
            return {
                "success": 1,
                "message": "Áreas encontradas",
                "data": areas
            }
        else:
            return {
                "success": 0,
                "message": "Error al buscar las áreas"
            }

    except Exception as e:
        cursor.close()
        conexionBD.close()
        
        return {
            "success": 0,
            "message": f"Error: {str(e)}"
        }

def insertarArea(data):
    conexionBD = get_connection()
    if conexionBD is None:
        return {"success": 0, "message": "Error de conexión"}

    try:
        area = data.get("area")
        descripcion = data.get("descripcion")

        query = """
            INSERT INTO empleados_areas (area, descripcion) 
            VALUES (%s, %s)
        """
        cursor = conexionBD.cursor()
        cursor.execute(query, (area, descripcion))
        conexionBD.commit()

        cursor.close()
        conexionBD.close()

        return {
            "success": 1,
            "message": "Área insertada",
            "data": data
        }

    except Exception as e:
        cursor.close()
        conexionBD.close()
        return {
            "success": 0,
            "message": f"Error: {str(e)}"
        }

def actualizarArea(id, data):
    conexionBD = get_connection()
    if conexionBD is None:
        return {"success": 0, "message": "Error de conexión"}

    try:
        area = data.get("area")
        descripcion = data.get("descripcion")

        query = """
            UPDATE empleados_areas
            SET area = %s, descripcion = %s
            WHERE id = %s
        """
        cursor = conexionBD.cursor()
        cursor.execute(query, (area, descripcion, id))
        conexionBD.commit()

        cursor.close()
        conexionBD.close()
        data['id'] = id  # Agregar el ID al diccionario 'data'

        return {
            "success": 1,
            "message": "Área actualizada",
            "data": data
        }

    except Exception as e:
        cursor.close()
        conexionBD.close()
        return {
            "success": 0,
            "message": f"Error: {str(e)}",
            "data": []
        }

def eliminarArea(id):
    conexionBD = get_connection()
    if conexionBD is None:
        return {"success": 0, "message": "Error de conexión"}

    try:
        idArea = id

        # Verificar si el área está asociada a algún cargo en la tabla correspondiente
        query = """
            SELECT COUNT(*) as count 
            FROM empleados_cargos 
            WHERE idArea = %s
        """
        cursor = conexionBD.cursor()
        cursor.execute(query, (idArea,))
        count = cursor.fetchone()[0]

        if count > 0:
            cursor.close()
            conexionBD.close()
            return {
                "success": 0,
                "message": "No se puede eliminar el área porque tiene cargos asociados"
            }
        else:
            # Eliminar el área de la tabla empleados_areas
            query = """
                DELETE FROM empleados_areas 
                WHERE id = %s
            """
            cursor.execute(query, (idArea,))
            conexionBD.commit()

            cursor.close()
            conexionBD.close()

            return {
                "success": 1,
                "message": "Área eliminada correctamente"
            }

    except Exception as e:
        cursor.close()
        conexionBD.close()
        return {
            "success": 0,
            "message": f"Error: {str(e)}"
        }

#------------------ CARGOS ------------------
def consultarCargos():
    conexionBD = get_connection()
    if conexionBD is None:
        return {"success": 0, "message": "Error de conexión"}

    try:
        query = """
            SELECT ec.*, ea.area AS nomarea
            FROM empleados_cargos ec
            LEFT JOIN empleados_areas ea ON ea.id = ec.idArea
        """
        cursor = conexionBD.cursor(dictionary=True)
        cursor.execute(query)
        cargos = cursor.fetchall()

        cursor.close()
        conexionBD.close()
        
        

        if cargos:
            return {
                "success": 1,
                "message": "Cargos encontrados",
                "data": cargos
            }
        else:
            return {
                "success": 0,
                "message": "Error al buscar los cargos",
                "data": []
            }
    

    except Exception as e:
        cursor.close()
        conexionBD.close()
        return {
            "success": 0,
            "message": f"Error: {str(e)}"
        }

def consultarCargosByAreas(idArea):
    conexionBD = get_connection()
    if conexionBD is None:
        return {"success": 0, "message": "Error de conexión"}

    try:
        query = """
            SELECT ec.*, ea.area AS nomarea
            FROM empleados_cargos ec
            LEFT JOIN empleados_areas ea ON ea.id = ec.idArea
            WHERE ec.idArea = %s
        """
        cursor = conexionBD.cursor(dictionary=True)
        cursor.execute(query, (idArea,))
        cargos = cursor.fetchall()

        cursor.close()
        conexionBD.close()

        if cargos:
            return {
                "success": 1,
                "message": "Cargos encontrados",
                "data": cargos
            }
        else:
            return {
                "success": 0,
                "message": "Error al buscar los cargos"
            }

    except Exception as e:
        cursor.close()
        conexionBD.close()
        return {
            "success": 0,
            "message": f"Error: {str(e)}"
        }

def insertarCargo(data):
    conexionBD = get_connection()
    if conexionBD is None:
        return {"success": 0, "message": "Error de conexión"}

    try:
        cargo = data.get("cargo")
        descripcion = data.get("descripcion")
        idArea = data.get("idArea")

        # Insertar el cargo en la base de datos
        query = """
            INSERT INTO empleados_cargos (cargo, descripcion, idArea)
            VALUES (%s, %s, %s)
        """
        cursor = conexionBD.cursor(dictionary=True)  # Asegúrate de que el cursor devuelva diccionarios
        cursor.execute(query, (cargo, descripcion, idArea))
        conexionBD.commit()

        # Obtener el área asociada al cargo insertado
        query = "SELECT * FROM empleados_areas WHERE id = %s"
        cursor.execute(query, (idArea,))
        nomarea = cursor.fetchone()

        if nomarea:
            data['nomarea'] = nomarea['area']  # Ahora puedes usar claves de diccionario

        cursor.close()
        conexionBD.close()

        return {
            "success": 1,
            "message": "Cargo insertado",
            "data": data
        }

    except Exception as e:
        cursor.close()
        conexionBD.close()
        return {
            "success": 0,
            "message": f"Error: {str(e)}"
        }

def actualizarCargo(id, data):
    try:
        conexionBD = get_connection()
        if conexionBD is None:
            return {
                'success': False,
                'message': 'Error de conexión'
            }

        # Obtener los valores del diccionario 'data'
        cargo = data['cargo']
        descripcion = data['descripcion']
        idArea = data['idArea']

        # Preparar la consulta SQL para actualizar el cargo
        query = """
            UPDATE empleados_cargos
            SET cargo = %s, descripcion = %s, idArea = %s
            WHERE id = %s
        """
        cursor = conexionBD.cursor()
        cursor.execute(query, (cargo, descripcion, idArea, id))

        # Confirmar los cambios
        conexionBD.commit()

        # Consultar el área correspondiente al idArea
        query_area = "SELECT area FROM empleados_areas WHERE id = %s"
        cursor.execute(query_area, (idArea,))
        nomarea = cursor.fetchone()  # Obtener solo el primer resultado

        # Si se encuentra el área, agregar el nombre al diccionario 'data'
        if nomarea:
            data['nomarea'] = nomarea[0]  # Acceder al valor 'area'

        cursor.close()
        conexionBD.close()
        data['id'] = id  # Agregar el ID al diccionario 'data'
        

        return {
            'success': True,
            'message': 'Cargo actualizado',
            'data': data
        }

    except Exception as e:
        return {
            'success': False,
            'message': f'Error: {str(e)}'
        }



def eliminarCargos(id):
    conexionBD = get_connection()
    if conexionBD is None:
        return {"success": 0, "message": "Error de conexión"}

    try:
        idCargo = id

        # Verificar si el cargo está asociado a algún empleado
        query = """
            SELECT COUNT(*) as count
            FROM empleados
            WHERE id_cargo = %s
        """
        cursor = conexionBD.cursor()
        cursor.execute(query, (idCargo,))
        count = cursor.fetchone()[0]

        if count > 0:
            cursor.close()
            conexionBD.close()
            return {
                "success": 0,
                "message": "No se puede eliminar el cargo porque tiene empleados asociados"
            }
        else:
            # Eliminar el cargo de la tabla empleados_cargos
            query = """
                DELETE FROM empleados_cargos
                WHERE id = %s
            """
            cursor.execute(query, (idCargo,))
            conexionBD.commit()

            cursor.close()
            conexionBD.close()

            return {
                "success": 1,
                "message": "Cargo eliminado correctamente"
            }

    except Exception as e:
        cursor.close()
        conexionBD.close()
        return {
            "success": 0,
            "message": f"Error: {str(e)}"
        }

#------------------ MY PERFIL ------------------

def actualizarMyPerfil(id, data):
    conexionBD = get_connection()
    if conexionBD is None:
        return {"success": 0, "message": "Error de conexión"}

    try:
        nombres = data.get("nombres")
        apellidos = data.get("apellidos")
        tipo_doc = data.get("tipo_doc")
        documento = data.get("documento")
        correo_corporativo = data.get("correo_corporativo")
        correo_alterno = data.get("correo_alterno")
        telefono = data.get("telefono")
        direccion = data.get("direccion")
        status = data.get("status")

        query = """
            UPDATE empleados
            SET nombres = %s, apellidos = %s, tipo_doc = %s, documento = %s, correo_corporativo = %s,
                correo_alterno = %s, telefono = %s, direccion = %s, status = %s
            WHERE id = %s
        """
        cursor = conexionBD.cursor()
        cursor.execute(query, (nombres, apellidos, tipo_doc, documento, correo_corporativo,
                               correo_alterno, telefono, direccion, status, id))
        conexionBD.commit()

        cursor.close()
        conexionBD.close()

        return {
            "success": 1,
            "message": "Perfil actualizado",
            "data": data
        }

    except Exception as e:
        cursor.close()
        conexionBD.close()
        return {
            "success": 0,
            "message": f"Error: {str(e)}",
            "data": []
        }

def actualizarContraseña(idUser, data):
    conexionBD = get_connection()
    if conexionBD is None:
        return {"success": 0, "message": "Error de conexión"}

    try:
        pass_ = data.get("newPassword")

        # Actualizar la contraseña del usuario
        query = """
            UPDATE usuarios
            SET pass = %s
            WHERE id = %s
        """
        cursor = conexionBD.cursor()
        cursor.execute(query, (pass_, idUser))
        conexionBD.commit()

        # Dejar logs de la actualización de la contraseña
        fecha_hora = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
        evento = 'Actualización de contraseña'
        query_log = """
            INSERT INTO logs_login (id_usuario, fecha_hora, evento)
            VALUES (%s, %s, %s)
        """
        cursor.execute(query_log, (idUser, fecha_hora, evento))
        conexionBD.commit()

        # Limpiar la contraseña temporal
        query_update_temp = """
            UPDATE usuarios
            SET passtemp = ''
            WHERE id = %s
        """
        cursor.execute(query_update_temp, (idUser,))
        conexionBD.commit()

        cursor.close()
        conexionBD.close()

        return {
            "success": 1,
            "message": "Contraseña actualizada",
            "data": data
        }

    except Exception as e:
        cursor.close()
        conexionBD.close()
        return {
            "success": 0,
            "message": f"Error: {str(e)}",
            "data": []
        }




def limpiarArchivo(idEmp):
    try:
        carpeta = f'/var/www/html/crm/assets/img/employee/{idEmp}/'
        print(f"[INFO] Verificando archivos en {carpeta}")

        if os.path.isdir(carpeta):
            archivos = os.listdir(carpeta)

            for archivo in archivos:
                ruta_completa = os.path.join(carpeta, archivo)
                if os.path.isfile(ruta_completa):
                    try:
                        os.remove(ruta_completa)
                        print(f"[SUCCESS] Archivo eliminado: {archivo}")
                    except Exception as e:
                        print(f"[ERROR] No se pudo borrar {archivo}: {str(e)}")
        else:
            print(f"[WARNING] La carpeta {carpeta} no existe.")

    except Exception as e:
        print(f"[ERROR] Error en limpiarArchivo: {str(e)}")

def updateFoto(idEmp, data):
    try:
        conexionBD = get_connection()
        if not conexionBD:
            return {'success': False, 'message': 'Error de conexión a la base de datos'}

        if 'profile_picture' not in data or 'file_name' not in data or 'file_type' not in data:
            return {'success': False, 'message': 'Faltan datos para procesar la imagen.'}

        profile_picture = data['profile_picture']
        file_name = f"{idEmp}{data['file_name']}"
        file_type = data['file_type']

        allowed_image_types = ['image/jpeg', 'image/png', 'image/jpg']
        if file_type not in allowed_image_types:
            return {'success': False, 'message': 'Formato de imagen no permitido.'}

        # ================================
        # 📌 Configuración SFTP con clave privada
        # ================================
        sftp_server = os.getenv('ftp_server')
        sftp_user_name = os.getenv('ftp_user_name')
        pem_key_path = os.getenv('ftp_private_key_path')
        update_folder = os.getenv('Update_foto')  # Ej: '/var/www/html/assets/img/employee/'

        if not all([sftp_server, sftp_user_name, pem_key_path, update_folder]):
            return {'success': False, 'message': 'Variables de entorno incompletas para conexión SFTP.'}

        remote_folder = f"{update_folder}{idEmp}/"
        remote_file_path = f"{remote_folder}{file_name}"

        transport, sftp = None, None

        try:
            print(f"🔐 [SFTP] Conectando a {sftp_server} con clave privada en {pem_key_path}")
            key = paramiko.RSAKey.from_private_key_file(pem_key_path)
            transport = paramiko.Transport((sftp_server, 22))
            transport.connect(username=sftp_user_name, pkey=key)
            sftp = paramiko.SFTPClient.from_transport(transport)

            # Verificar o crear carpeta remota
            try:
                sftp.chdir(remote_folder)
            except IOError:
                path_parts = remote_folder.strip('/').split('/')
                current_path = '/'
                for part in path_parts:
                    if part:
                        current_path += f"{part}/"
                        try:
                            sftp.chdir(current_path)
                        except IOError:
                            sftp.mkdir(current_path)
                            sftp.chmod(current_path, 0o2777)
                            sftp.chdir(current_path)

            # Eliminar imagen anterior del empleado
            try:
                for archivo in sftp.listdir(remote_folder):
                    if archivo.startswith(str(idEmp)):
                        sftp.remove(f"{remote_folder}{archivo}")
            except Exception:
                pass

            # Subir imagen nueva
            profile_picture.file.seek(0)
            sftp.putfo(profile_picture.file, remote_file_path)
            sftp.chmod(remote_file_path, 0o644)

        except Exception as e:
            return {'success': False, 'message': f'Error en la conexión o carga SFTP: {e}'}

        finally:
            if sftp:
                sftp.close()
            if transport:
                transport.close()

        # ================================
        # 📌 Actualizar Base de Datos
        # ================================
        app_url = os.getenv('URL_IMG', '').rstrip('/')
        if not app_url:
            return {'success': False, 'message': 'Variable de entorno URL_IMG no configurada.'}

        imagen_url = f"{app_url}/assets/img/employee/{idEmp}/{file_name}"

        try:
            cursor = conexionBD.cursor()
            query = "UPDATE empleados SET imagen = %s WHERE id = %s"
            cursor.execute(query, (imagen_url, idEmp))
            conexionBD.commit()

            return {
                'success': True,
                'message': 'Perfil actualizado correctamente.',
                'data': {'imagen': imagen_url}
            }

        except Exception as e:
            return {'success': False, 'message': f'Error al actualizar la base de datos: {e}'}

        finally:
            if cursor:
                cursor.close()
            if conexionBD:
                conexionBD.close()

    except Exception as e:
        return {'success': False, 'message': f'Error general: {str(e)}'}

# ------------------ Logs login ------------------

def consultarLogsLogin(idUser):
    conexionBD = get_connection()
    if conexionBD is None:
        return {
            'success': 0,
            'message': 'Error de conexión'
        }

    try:
        # Consulta SQL para obtener los logs de login
        query = "SELECT * FROM logs_login WHERE id_usuario = %s"
        cursor = conexionBD.cursor(dictionary=True)
        cursor.execute(query, (idUser,))
        logs = cursor.fetchall()

        cursor.close()
        conexionBD.close()

        if logs:
            return {
                'success': 1,
                'message': 'Logs login encontrados',
                'data': logs
            }
        else:
            return {
                'success': 0,
                'message': 'Error al buscar los logs login'
            }

    except Exception as e:
        cursor.close()
        conexionBD.close()
        return {
            'success': 0,
            'message': f"Error: {str(e)}"
        }
