import json
from datetime import datetime
import hashlib
import sys
import os
import base64
import smtplib
import ssl
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
import pytz
from html import escape
from typing import List, Dict, Any

sys.path.append("/var/www/html/config")

from cnxpdo import get_connection
from dotenv import load_dotenv

# Cargar las variables de entorno desde el archivo .env
# load_dotenv('/var/www/html/api/crm/configuraciones/.env')

""" 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)


# Obtener las variables de entorno
hostname = os.getenv('SMTP_HOST')
port = int(os.getenv('SMTP_PORT'))
username = os.getenv('SMTP_USER')
password = os.getenv('SMTP_PASS')
appUrl = os.getenv('APP_URL')
appName = os.getenv('APP_NAME')
senderName = os.getenv('SMTP_NOTIFY') """


def cargar_configuracion_smtp():
    # Obtener la ruta del .env
    script_dir = os.path.dirname(
        os.path.abspath(__file__)
    )  # Directorio del script actual
    crm_dir = os.path.dirname(script_dir)  # Sube un nivel hasta 'crm'
    env_path = os.path.join(crm_dir, "configuraciones", ".env")  # Ruta al .env

    # Cargar variables de entorno
    load_dotenv(env_path)

    # Variables requeridas
    required_vars = [
        "SMTP_HOST",
        "SMTP_PORT",
        "SMTP_USER",
        "SMTP_PASS",
        "APP_URL",
        "APP_NAME",
        "SMTP_NOTIFY",
    ]

    # Obtener valores y validar que no falten
    config = {}
    for var in required_vars:
        value = os.getenv(var)
        if value is None or value.strip() == "":
            raise ValueError(
                f"❌ ERROR: La variable de entorno '{var}' no está definida o está vacía en {env_path}"
            )
        config[var] = value.strip()

    # Convertir el puerto a entero
    try:
        config["SMTP_PORT"] = int(config["SMTP_PORT"])
    except ValueError:
        raise ValueError(
            f"❌ ERROR: SMTP_PORT ('{config['SMTP_PORT']}') debe ser un número entero válido."
        )

    print("✅ Configuración SMTP cargada correctamente.")
    return config


# Cargar configuración SMTP
smtp_config = cargar_configuracion_smtp()

# === OVERRIDE (CREDENCIALES QUEMADAS PARA PRUEBA) ===
hostname = "smtp.office365.com"
port = 587  # Office 365 usa 587 con STARTTLS

# Opción 1 (activa)
username = "notificacionelectronica@mascredimas.us"

password = "dSU#oH+z$%RTak"

# Branding del correo (ajústalo si quieres)
appUrl = "https://dev.crm.imparables.cic-ware.com/"
appName = "Imparables"
senderName = "Notificaciones Electrónicas"
# === /OVERRIDE ===

def sendEmail(input_data):
    # =========================
    # DEBUG: imprimir lo que llega
    # =========================
    try:
        def _mask(s: str, visible: int = 3) -> str:
            if not s:
                return ""
            if len(s) <= visible * 2:
                return s[0] + "…" if len(s) > 1 else s
            return s[:visible] + "…" + s[-visible:]

        print("[DEBUG][sendEmail] input_data keys:", list(input_data.keys()))
    except Exception:
        pass  # por si input_data no es dict

    # Modificación: manejar destinatario como string o lista
    destinatario_input = input_data.get("destinatario")
    if isinstance(destinatario_input, list):
        destinatarios = [email.strip() for email in destinatario_input if email.strip()]
    else:
        destinatarios = [destinatario_input.strip()] if destinatario_input else []

    asunto = (input_data.get("asunto") or f"Notificación {appName}").strip()
    cuerpo = input_data.get("cuerpo_correo") or ""

    # Debug modificado para mostrar lista
    print(f"[DEBUG][sendEmail] destinatarios count: {len(destinatarios)}")
    print("[DEBUG][sendEmail] destinatarios:", [_mask(email) for email in destinatarios])
    print("[DEBUG][sendEmail] asunto:", asunto)
    print("[DEBUG][sendEmail] cuerpo_correo.len:", len(cuerpo))
    print(
        "[DEBUG][sendEmail] SMTP host:",
        hostname,
        "port:",
        port,
        "user:",
        _mask(username),
    )
    print("[DEBUG][sendEmail] senderName:", senderName)

    # Validación
    if not destinatarios:
        return {
            "success": False,
            "message": "No se especificaron destinatarios válidos."
        }

    # Soporte para texto plano o HTML
    def _parece_html(s: str) -> bool:
        return "<" in s and ">" in s

    if _parece_html(cuerpo):
        cuerpo_html = cuerpo
    else:
        from html import escape
        cuerpo_html = "<p>" + escape(cuerpo).replace("\n", "<br>") + "</p>"

    # HTML template (sin cambios)
    html_body = f"""
    <!DOCTYPE html>
    <html lang="es">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>{asunto}</title>
        <style>
            body {{
                font-family: Arial, sans-serif;
            }}
            .container {{
                max-width: 600px;
                margin: 0 auto;
                padding: 20px;
                border: 1px solid #e0e0e0;
                border-radius: 5px;
            }}
            .header {{
                text-align: center;
                margin-bottom: 20px;
            }}
            .footer {{
                text-align: center;
                margin-top: 20px;
                color: #666;
                font-size: 12px;
            }}
            a {{ color: #0b57d0; text-decoration: none; }}
        </style>
    </head>
    <body>
        <div class="container">
            <div class="header">
                <h1>{appName}</h1>
                <p>{asunto}</p>
            </div>

            <div class="content">
                {cuerpo_html}
            </div>

            <div class="footer">
                <p>🖥 Equipo {appName}</p>
            </div>
        </div>
    </body>
    </html>
    """

    # Variables para tracking de envíos masivos
    enviados_exitosos = []
    errores = []

    # Conexión SMTP y envío de correo (modificado para múltiples destinatarios)
    try:
        print("[DEBUG][sendEmail] Abriendo conexión SMTP…")
        context = ssl.create_default_context()
        with smtplib.SMTP(hostname, port) as server:
            server.ehlo()
            print("[DEBUG][sendEmail] STARTTLS…")
            server.starttls(context=context)
            server.ehlo()
            print("[DEBUG][sendEmail] Intentando login como:", _mask(username))
            server.login(username, password)
            print("[DEBUG][sendEmail] Login OK. Enviando mensaje(s)…")
            
            # Enviar a cada destinatario
            for i, destinatario in enumerate(destinatarios):
                try:
                    # Crear el mensaje de correo para cada destinatario
                    message = MIMEMultipart("alternative")
                    message["From"] = f"{senderName} <{username}>"
                    message["To"] = destinatario
                    message["Subject"] = asunto

                    part = MIMEText(html_body, "html")
                    message.attach(part)
                    
                    server.sendmail(username, destinatario, message.as_string())
                    enviados_exitosos.append(destinatario)
                    print(f"[DEBUG][sendEmail] Enviado a {_mask(destinatario)} ({i+1}/{len(destinatarios)})")
                    
                except Exception as e:
                    errores.append({"destinatario": destinatario, "error": str(e)})
                    print(f"[DEBUG][sendEmail] Error enviando a {_mask(destinatario)}: {e}")

        print(f"[DEBUG][sendEmail] Proceso completado. Enviados: {len(enviados_exitosos)}, Errores: {len(errores)}")


        if len(errores) == 0:
            # Todos enviados correctamente
            if len(destinatarios) == 1:
                return {
                    "success": True,
                    "message": "El correo electrónico ha sido enviado correctamente.",
                }
            else:
                return {
                    "success": True,
                    "message": f"Los {len(enviados_exitosos)} correos electrónicos han sido enviados correctamente.",
                    "enviados": len(enviados_exitosos),
                    "total": len(destinatarios)
                }
        elif len(enviados_exitosos) > 0:
            return {
                "success": True,
                "message": f"Se enviaron {len(enviados_exitosos)} de {len(destinatarios)} correos. {len(errores)} fallaron.",
                "enviados": len(enviados_exitosos),
                "errores_count": len(errores),
                "total": len(destinatarios),
                "detalles_errores": errores
            }
        else:
            return {
                "success": False,
                "message": f"No se pudo enviar ningún correo de {len(destinatarios)} intentos.",
                "errores_count": len(errores),
                "detalles_errores": errores
            }

    except smtplib.SMTPAuthenticationError as e:
        try:
            code = getattr(e, "smtp_code", None)
            err = getattr(e, "smtp_error", b"").decode(errors="ignore")
        except Exception:
            code, err = None, str(e)
        print(f"[DEBUG][sendEmail] SMTPAuthenticationError code={code} error={err}")
        return {
            "success": False,
            "message": f"Error en el envío del correo electrónico: ({code}) {err or str(e)}",
        }

    except Exception as e:
        print("[DEBUG][sendEmail] Exception:", repr(e))
        return {
            "success": False,
            "message": f"Error en el envío del correo electrónico: {str(e)}",
        }


def registrar_logs_envio(destinatarios_exitosos: List[str], id_campana: int):
    """
    Registra los logs de envío exitoso en la base de datos
    """
    if not destinatarios_exitosos:
        return {"success": False, "message": "No hay destinatarios exitosos para registrar"}
    
    try:
        # Configurar zona horaria de Colombia
        colombia_tz = pytz.timezone('America/Bogota')
        fecha_envio = datetime.now(colombia_tz)
        
        conexionBD = get_connection()
        if conexionBD is None:
            return {"success": False, "message": "Error de conexión a la base de datos"}
        
        cursor = conexionBD.cursor()
        
        # Query de inserción múltiple
        query = """
            INSERT INTO campanas_envio_correos_logs (id_campana, correo, fecha_envio)
            VALUES (%s, %s, %s)
        """
        
        # Preparar datos para inserción múltiple
        datos_insercion = [(id_campana, correo, fecha_envio) for correo in destinatarios_exitosos]
        
        # Ejecutar inserción múltiple
        cursor.executemany(query, datos_insercion)
        conexionBD.commit()
        
        registros_insertados = cursor.rowcount
        cursor.close()
        conexionBD.close()
        
        return {
            "success": True, 
            "message": f"Se registraron {registros_insertados} logs de envío",
            "registros": registros_insertados
        }
        
    except Exception as e:
        if 'conexionBD' in locals():
            try:
                conexionBD.rollback()
                conexionBD.close()
            except:
                pass
        return {"success": False, "message": f"Error al registrar logs: {str(e)}"}
    


def sendEmail_marketing(input_data):
    # =========================
    # DEBUG: imprimir lo que llega
    # =========================
    try:
        def _mask(s: str, visible: int = 3) -> str:
            if not s:
                return ""
            if len(s) <= visible * 2:
                return s[0] + "…" if len(s) > 1 else s
            return s[:visible] + "…" + s[-visible:]

        print("[DEBUG][sendEmail] input_data keys:", list(input_data.keys()))
    except Exception:
        pass  # por si input_data no es dict

    # Modificación: manejar destinatario como string o lista
    destinatario_input = input_data.get("destinatario")
    if isinstance(destinatario_input, list):
        destinatarios = [email.strip() for email in destinatario_input if email.strip()]
    else:
        destinatarios = [destinatario_input.strip()] if destinatario_input else []

    asunto = (input_data.get("asunto") or f"Notificación {appName}").strip()
    cuerpo = input_data.get("cuerpo_correo") or ""

    # Debug modificado para mostrar lista
    print(f"[DEBUG][sendEmail] destinatarios count: {len(destinatarios)}")
    print("[DEBUG][sendEmail] destinatarios:", [_mask(email) for email in destinatarios])
    print("[DEBUG][sendEmail] asunto:", asunto)
    print("[DEBUG][sendEmail] cuerpo_correo.len:", len(cuerpo))
    print(
        "[DEBUG][sendEmail] SMTP host:",
        hostname,
        "port:",
        port,
        "user:",
        _mask(username),
    )
    print("[DEBUG][sendEmail] senderName:", senderName)

    # Validación
    if not destinatarios:
        return {
            "success": False,
            "message": "No se especificaron destinatarios válidos.",
            "destinatarios_exitosos": []
        }

    # Soporte para texto plano o HTML
    def _parece_html(s: str) -> bool:
        return "<" in s and ">" in s

    if _parece_html(cuerpo):
        cuerpo_html = cuerpo
    else:
        cuerpo_html = "<p>" + escape(cuerpo).replace("\n", "<br>") + "</p>"

    # HTML template
    html_body = f"""
    <!DOCTYPE html>
    <html lang="es">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>{asunto}</title>
        <style>
            body {{
                font-family: Arial, sans-serif;
            }}
            .container {{
                max-width: 600px;
                margin: 0 auto;
                padding: 20px;
                border: 1px solid #e0e0e0;
                border-radius: 5px;
            }}
            .header {{
                text-align: center;
                margin-bottom: 20px;
            }}
            .footer {{
                text-align: center;
                margin-top: 20px;
                color: #666;
                font-size: 12px;
            }}
            a {{ color: #0b57d0; text-decoration: none; }}
        </style>
    </head>
    <body>
        <div class="container">
            <div class="header">
                <h1>{appName}</h1>
                <p>{asunto}</p>
            </div>

            <div class="content">
                {cuerpo_html}
            </div>

            <div class="footer">
                <p>🖥 Equipo {appName}</p>
            </div>
        </div>
    </body>
    </html>
    """

    # Variables para tracking de envíos masivos
    enviados_exitosos = []
    destinatarios_exitosos_detalle = []
    errores = []

    # Conexión SMTP y envío de correo (modificado para múltiples destinatarios)
    try:
        print("[DEBUG][sendEmail] Abriendo conexión SMTP…")
        context = ssl.create_default_context()
        with smtplib.SMTP(hostname, port) as server:
            server.ehlo()
            print("[DEBUG][sendEmail] STARTTLS…")
            server.starttls(context=context)
            server.ehlo()
            print("[DEBUG][sendEmail] Intentando login como:", _mask(username))
            server.login(username, password)
            print("[DEBUG][sendEmail] Login OK. Enviando mensaje(s)…")
            
            # Enviar a cada destinatario
            for i, destinatario in enumerate(destinatarios):
                try:
                    # Crear el mensaje de correo para cada destinatario
                    message = MIMEMultipart("alternative")
                    message["From"] = f"{senderName} <{username}>"
                    message["To"] = destinatario
                    message["Subject"] = asunto

                    part = MIMEText(html_body, "html")
                    message.attach(part)
                    
                    server.sendmail(username, destinatario, message.as_string())
                    enviados_exitosos.append(destinatario)
                    destinatarios_exitosos_detalle.append(destinatario)
                    print(f"[DEBUG][sendEmail] Enviado a {_mask(destinatario)} ({i+1}/{len(destinatarios)})")
                    
                except Exception as e:
                    errores.append({"destinatario": destinatario, "error": str(e)})
                    print(f"[DEBUG][sendEmail] Error enviando a {_mask(destinatario)}: {e}")

        print(f"[DEBUG][sendEmail] Proceso completado. Enviados: {len(enviados_exitosos)}, Errores: {len(errores)}")

        # Preparar respuestas con información detallada
        if len(errores) == 0:
            # Todos enviados correctamente
            if len(destinatarios) == 1:
                return {
                    "success": True,
                    "message": "El correo electrónico ha sido enviado correctamente.",
                    "enviados": 1,
                    "total": 1,
                    "destinatarios_exitosos": destinatarios_exitosos_detalle
                }
            else:
                return {
                    "success": True,
                    "message": f"Los {len(enviados_exitosos)} correos electrónicos han sido enviados correctamente.",
                    "enviados": len(enviados_exitosos),
                    "total": len(destinatarios),
                    "destinatarios_exitosos": destinatarios_exitosos_detalle
                }
        elif len(enviados_exitosos) > 0:
            return {
                "success": True,
                "message": f"Se enviaron {len(enviados_exitosos)} de {len(destinatarios)} correos. {len(errores)} fallaron.",
                "enviados": len(enviados_exitosos),
                "errores_count": len(errores),
                "total": len(destinatarios),
                "destinatarios_exitosos": destinatarios_exitosos_detalle,
                "detalles_errores": errores
            }
        else:
            return {
                "success": False,
                "message": f"No se pudo enviar ningún correo de {len(destinatarios)} intentos.",
                "errores_count": len(errores),
                "detalles_errores": errores,
                "destinatarios_exitosos": []
            }

    except smtplib.SMTPAuthenticationError as e:
        try:
            code = getattr(e, "smtp_code", None)
            err = getattr(e, "smtp_error", b"").decode(errors="ignore")
        except Exception:
            code, err = None, str(e)
        print(f"[DEBUG][sendEmail] SMTPAuthenticationError code={code} error={err}")
        return {
            "success": False,
            "message": f"Error en el envío del correo electrónico: ({code}) {err or str(e)}",
            "destinatarios_exitosos": []
        }

    except Exception as e:
        print("[DEBUG][sendEmail] Exception:", repr(e))
        return {
            "success": False,
            "message": f"Error en el envío del correo electrónico: {str(e)}",
            "destinatarios_exitosos": []
        }



def sendEmailEmployee2(input_data):

    # Obtener datos del input
    nombre_usuario = input_data.get('user', '').strip()
    correos = input_data.get('email', '').strip()
    codigo = input_data.get('codigo')

    # Crear el mensaje de correo
    message = MIMEMultipart("alternative")
    message["From"] = f"{senderName} <{username}>"
    message["To"] = correos
    message["Subject"] = f"Bienvenido a {appName}"

    # Cuerpo del correo en formato HTML
    html_body = f"""
    <!DOCTYPE html>
    <html lang="es">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Bienvenido a {appName}</title>
        <style>
            body {{
                font-family: Arial, sans-serif;
            }}
            .container {{
                max-width: 600px;
                margin: 0 auto;
                padding: 20px;
                border: 1px solid #e0e0e0;
                border-radius: 5px;
            }}
            .header {{
                text-align: center;
                margin-bottom: 20px;
            }}
            .code {{
                background-color: #f7f7f7;
                padding: 10px;
                border: 1px solid #e0e0e0;
                border-radius: 5px;
                text-align: center;
            }}
            .footer {{
                text-align: center;
                margin-top: 20px;
            }}
        </style>
    </head>
      <body>
        <div class="container">
            <div class="header">
                <h1>Bienvenido al Movimiento Imparables</h1>
                <p>¡Gracias por unirte a nuestra plataforma!</p>
            </div>
            <p>Hola, <strong>{nombre_usuario}</strong></p>
            <p>A continuación, te proporcionamos un código temporal para que puedas acceder a tu cuenta:</p>
            <div class="code">
                <h3>{codigo}</h3>
            </div>
            <p>Utiliza este código como contraseña temporal para acceder a tu cuenta. Si no has solicitado un código temporal, ignora este mensaje o ponte en contacto con nuestro equipo de soporte.</p>
            <p>Recuerda que puedes cambiar tu contraseña en cualquier momento.</p>
            <p>Para acceder a tu cuenta, visita la siguiente ruta: <a href="{appUrl}"> Entrada al Sistema Imparables CRM</a></p>
            <div class="footer">
                <p>🖥 Equipo Imparables</p>
            </div>
        </div>
    </body>
    </html>
    """

    part = MIMEText(html_body, "html")
    message.attach(part)

    # Conexión SMTP y envío de correo
    try:
        context = ssl.create_default_context()
        with smtplib.SMTP(hostname, port) as server:
            server.ehlo()
            server.starttls(context=context)
            server.login(username, password)
            server.sendmail(username, correos, message.as_string())

        response = {
            "success": True,
            "message": "El correo electrónico ha sido enviado correctamente."
        }
        return response

    except Exception as e:
        return {
            "success": False,
            "message": f"Error en el envío del correo electrónico: {str(e)}"
        }



def get_email_template_by_category(template_category):
    """
    Obtiene una plantilla de correo por categoría
    
    Args:
        template_category (str): La categoría de la plantilla a buscar
        
    Returns:
        dict: Objeto con estructura {success: bool, message: str, data: dict}
    """
    
    # Validación de entrada
    if not template_category or not isinstance(template_category, str):
        return {
            'success': False,
            'message': 'La categoría es requerida y debe ser una cadena de texto',
            'data': {}
        }
    
    # Limpiar entrada
    template_category = template_category.strip()
    
    if not template_category:
        return {
            'success': False,
            'message': 'La categoría no puede estar vacía',
            'data': {}
        }
    
    conexionBD = get_connection()
    if conexionBD is None:
        return {
            'success': False,
            'message': 'Error de conexión',
            'data': {}
        }

    try:
        # Query SQL para obtener plantilla por categoría
        query = """
            SELECT 
                template_id,
                template_category,
                email_subject,
                email_body
            FROM email_templates 
            WHERE template_category = %s
            LIMIT 1
        """
        
        cursor = conexionBD.cursor(dictionary=True)
        cursor.execute(query, (template_category,))
        template_data = cursor.fetchone()

        cursor.close()
        conexionBD.close()

        if template_data:
            return {
                'success': True,
                'message': f'Plantilla encontrada para la categoría "{template_category}"',
                'data': template_data
            }
        else:
            return {
                'success': False,
                'message': f'No se encontró ninguna plantilla para la categoría "{template_category}"',
                'data': {}
            }

    except Exception as e:
        cursor.close()
        conexionBD.close()
        return {
            'success': False,
            'message': f'Error: {str(e)}',
            'data': {}
        }



def update_email_template_by_id(template_id, template_category=None, email_subject=None, email_body=None):
    # Validaciones básicas
    if not template_id or not isinstance(template_id, int):
        return {
            'success': False,
            'message': 'El template_id es requerido y debe ser un número entero',
            'data': {}
        }
    
    if template_category is None and email_subject is None and email_body is None:
        return {
            'success': False,
            'message': 'Debe especificar al menos un campo para actualizar',
            'data': {}
        }
    
    conexionBD = get_connection()
    if conexionBD is None:
        return {
            'success': False,
            'message': 'Error de conexión',
            'data': {}
        }

    try:
        cursor = conexionBD.cursor(dictionary=True)
        
        # Construir query dinámicamente
        updates = []
        values = []
        
        if template_category is not None:
            updates.append("template_category = %s")
            values.append(template_category.strip())
        
        if email_subject is not None:
            updates.append("email_subject = %s")
            values.append(email_subject)
        
        if email_body is not None:
            updates.append("email_body = %s")
            values.append(email_body)
        
        values.append(template_id)
        
        # Ejecutar actualización
        query = f"UPDATE email_templates SET {', '.join(updates)} WHERE template_id = %s"
        cursor.execute(query, values)
        conexionBD.commit()
        
        if cursor.rowcount > 0:
            # Retornar datos actualizados
            cursor.execute("SELECT * FROM email_templates WHERE template_id = %s", (template_id,))
            updated_data = cursor.fetchone()
            
            cursor.close()
            conexionBD.close()
            
            return {
                'success': True,
                'message': 'Plantilla actualizada exitosamente',
                'data': updated_data
            }
        else:
            cursor.close()
            conexionBD.close()
            return {
                'success': False,
                'message': f'No se encontró la plantilla con ID {template_id}',
                'data': {}
            }

    except Exception as e:
        cursor.close()
        conexionBD.close()
        return {
            'success': False,
            'message': f'Error: {str(e)}',
            'data': {}
        }