U
    iJ                     @   s   d dl Z d dlZd dlZd dlmZ d dlmZ d dlmZmZ d dl	m
Z
mZ d dlmZmZmZmZ ejejd eeZddd	Zd
d Zdd Zdd Zdd ZdddZdS )    N)current_user)datetime)current_apprender_template)MailMessage)obtener_destinatarios_mailvalidar_mail_list_existeguardar_log_envioobtener_subject_de_mail_list)levelc                 C   s  ddg g g ddg g || g dd	}t  }zz"| sX|d d d|d< |W W ZS |s|rt|}|pnd}|s|d d nd}|d d |W W S tj}|pi }|pg }|pi }|pi }td|   g g g d}|rtd |  t|}|d s8|d d!|d   d"|d< |W W zS |d# sl|d d$| d% td$| d& n|d' s|d d$| d( td$| d( nbt|}|d r|d |d  |d |d  |d |d  n|d d)|d   |rddD ]V}||kr|| r|| D ]2}|r,d*|kr,||| kr,|| | q,q|d s|s|s|d d+ d,|d< |W W S |d d- d.|d< d/|d< |W W S |d |d |d t|d t|d  t|d  d|d0< g }|D ]R}t|}|d1 rD|| |d |d2d3 n|d d4|d   qt||}zt| f|}W nZ tk
r } z:|d d5|  d6t|  d7|d< | W Y 
W W S d}~X Y nX zt||d |d r|d nd|d r
|d nd||d8d9}|D ]}z0t||}|d sR|d d:|d   W nJ tk
r } z*|d d;|d2d< d=t|  W 5 d}~X Y nX q tt}|| d.|d< d>|d0 d?  d@|d< tdA|   W nf tk
rN } zF|d dBt|  dC|d< tdBt|  | W Y W W pS d}~X Y nX W nX tk
r } z8|d dDt|  dE|d< tdFt|  W 5 d}~X Y nX W 5 t  }	t|	| |d< |d rtd	|  ntd
|  z
tj}
W n tk
r   d}
Y nX zt	||d
|dg d
|dg d
|dg | t|t|dg |
|d r|dnd|drd
|dg ndd W n8 tk
r } ztdt|  W 5 d}~X Y nX X |S )Gu  
    Función universal para envío de correos electrónicos utilizando Flask-Mail.
    
    Args:
        template_path (str): Ruta del template HTML relativa a templates/
        asunto (str): Asunto del correo
        template_data (dict, optional): Datos para inyectar en el template
        mail_list_id (int, optional): ID de la lista de correos en Util_MailListHead
        destinatarios_adicionales (dict, optional): Destinatarios adicionales
            {'TO': ['email1@test.com'], 'CC': ['email2@test.com'], 'BCC': ['email3@test.com']}
        archivos_adjuntos (list, optional): Lista de archivos adjuntos
            [{'tipo': 'local', 'ruta': 'path/file.pdf', 'nombre': 'archivo.pdf'},
             {'tipo': 'url', 'ruta': 'https://...', 'nombre': 'archivo_web.pdf'}]
        configuracion_adicional (dict, optional): Configuraciones adicionales
        
    Returns:
        dict: Resultado del envío
    F r   )TOCCBCCtotal_destinatariosN)	successmensajedestinatarioserroreswarningsmail_list_idZtemplate_usadoarchivos_enviadostiempo_ejecucionr   r   z1Proceso completado exitosamente para MailListID: u    Proceso falló para MailListID: ZSYSTEM;r   r   r   r   ZENVIADOZFALLIDOr   z; )r   subjectZrecipients_toZrecipients_ccZrecipients_bccZtemplate_usedtemplate_dataZ
files_sentsent_bystatus	error_msgz Error al guardar log de correo: ztemplate_path es requeridou!   Parámetros de entrada inválidosr   z[Sin Asunto]r   u6   No se encontró asunto en la BD, usando "[Sin Asunto]"u@   No se proporcionó asunto ni mail_list_id, usando "[Sin Asunto]"u*   Iniciando envío de correo para template: r   r   r   z(Obteniendo destinatarios de MailListID: zError al validar MailListID: u"   Error en validación de MailListIDexistezMailListID z no existe en la base de datosz
 no existeactivou    está inactivoz&Error al obtener destinatarios de BD: @z:Debe proporcionar mail_list_id o destinatarios_adicionalesz*No hay destinatarios para enviar el correou+   No se encontraron destinatarios TO válidosTz=Proceso completado con advertencias - no hay destinatarios TOr   validonombrearchivou   Archivo no válido: zError al renderizar template 'z': z Error en renderizado de templateMAIL_DEFAULT_SENDER)r   
recipientsccbcchtmlsenderError al adjuntar archivo: zError al adjuntar archivo desconocidoz: zCorreo enviado exitosamente a r   z destinatariosz'Correo enviado exitosamente. Template: zError al enviar correo: u   Error en envío de correozError general: zError general en el procesoz*Error general en enviar_correo_universal: )r   nowstrloggerinfoerrorr   email	Exceptionr
   joingetjsondumpsappendr   r   configr	   warningr   extendlenvalidar_archivo_adjuntopreparar_datos_templater   r   agregar_archivo_adjuntor   send)template_pathasuntor   r   destinatarios_adicionalesZarchivos_adjuntosZconfiguracion_adicional	resultadoZinicio_tiempoZ
fin_tiempor   Zdestinatarios_finaleseZ	asunto_bdr;   
validacionZdestinatarios_bdtipor4   Zarchivos_validadosr&   Zresultado_validaciondatos_templatecuerpo_htmlmsgZresultado_adjuntomail rN   bC:\Users\victor.barrera\Documents\proyectos\elepV3\Elep\src\App\Utilities_module\MailManagement.pyenviar_correo_universal   s   




"



"


<
$*


 
(rP   c              
   C   s<  t | tsddddS | d}| dd}|s<dd|dS z|dkrtj|rztj|rzt|tjrzd	d
ddW S dd| ddW S nf|dkrddl	}|j
|}|jdkr|jrd	dddW S dd| ddW S ndd| d|dW S W n> tk
r6 } zddt| |d W Y S d}~X Y nX dS )u  
    Valida si un archivo adjunto es válido (local o URL).
    
    Args:
        archivo (dict): Diccionario con información del archivo
                       {'tipo': 'local', 'ruta': '/path/to/file', 'nombre': 'archivo.pdf'}
                       {'tipo': 'url', 'ruta': 'https://...', 'nombre': 'archivo.pdf'}
    
    Returns:
        dict: Resultado de la validación
              {'valido': True/False, 'mensaje': 'descripción', 'tipo': 'local/url'}
    FzArchivo debe ser un diccionarioN)r$   r   rI   rutarI   localzRuta del archivo es requeridaTu   Archivo local válidoz,Archivo local no encontrado o no accesible: urlr   )httphttpsu   URL válidau   URL inválida: u   Tipo de archivo no válido: z. Use "local" o "url"zError al validar archivo: )
isinstancedictr7   ospathexistsisfileaccessR_OKurllib.parseparseurlparseschemenetlocr5   r0   )r&   rQ   rI   urllib
parsed_urlrG   rN   rN   rO   r?      s(    

&r?   c              
   C   s`  z| dd}| d}| dd}| dd}|dkrtt|d}| |||  W 5 Q R X d	d
| dW S |dkr
ddl}zB|j|}| }	| |||	 W 5 Q R X d	d| dW W S  tk
r }
 zddt|
 d W Y W S d}
~
X Y nX ndd| dW S W n< tk
rZ }
 zddt|
 d W Y S d}
~
X Y nX dS )u   
    Agrega un archivo adjunto al mensaje de correo.
    
    Args:
        msg (Message): Mensaje de Flask-Mail
        archivo (dict): Información del archivo
        
    Returns:
        dict: Resultado de la operación
    rI   rR   rQ   r%   Zarchivo_adjuntomimetypezapplication/octet-streamrbTzArchivo local adjuntado: r   r   rS   r   NzArchivo URL adjuntado: Fz&Error al descargar archivo desde URL: zTipo de archivo no soportado: r-   )	r7   openattachreadurllib.requestrequesturlopenr5   r0   )rL   r&   rI   rQ   r%   re   fprc   responsedatarG   rN   rN   rO   rA   )  s*    

.rA   c                 C   sp   t  jt  ddd|dd d|dd |dd d|dd d	d
ddd	}| rl||  |S )u  
    Prepara los datos que se enviarán al template, incluyendo variables globales.
    
    Args:
        template_data (dict): Datos específicos del template
        config (Config): Configuración de Flask
        
    Returns:
        dict: Datos completos para el template
    z%d de %B, %YZIGSAz"Integradora de Servicios AvanzadosSCHEMErT   z://Host	localhostz/static/img/logo.pngzsoporte@igsa.comzventas@igsa.comz+52 (999) 123-4567)	u   año_actualZfecha_actualZempresaZempresa_completaZurl_baseZlogo_empresaZsoporte_emailZventas_emailZtelefono_principal)r   r/   yearstrftimer7   update)r   r;   Zdatos_completosrN   rN   rO   r@   S  s    
r@   c                 C   s   z~t | }t| }| |dd|dd|d|d|ddt|dg t|d	g t|d
g dddd	}|W S  tk
r } zddt| d W Y S d}~X Y nX dS )u   
    Obtiene información resumida sobre el envío de correo.
    
    Args:
        mail_list_id (int): ID de la lista de correos
        
    Returns:
        dict: Información del envío
    r!   Fr"   r   	module_idr   r   r   r   r   r    Tu#   Información obtenida correctamente)	r   r!   r"   r   rw   r   Zdestinatarios_por_tipor   r   u   Error al obtener información: rg   N)r	   r   r7   r>   r5   r0   )r   rH   r   r2   rG   rN   rN   rO   obtener_info_envios  s*    


rx   c           	   
   C   s   zDt j}|pi }t||}t| }t|f|}||||ddd}|W S  tk
r~ } zddt| d W Y S d}~X Y nX dS )a)  
    Genera una vista previa del correo sin enviarlo.
    
    Args:
        mail_list_id (int): ID de la lista de correos
        template_path (str): Ruta del template HTML
        template_data (dict, optional): Datos para el template
        
    Returns:
        dict: Preview del correo
    TzPreview generado correctamente)html_content
info_enviorJ   rC   r   r   FzError al generar preview: rg   N)r   r;   r@   rx   r   r5   r0   )	r   rC   r   r;   rJ   rz   rK   ZpreviewrG   rN   rN   rO   generar_preview_correo  s$    
	r{   )NNNNNN)N)rX   r8   loggingZflask_loginr   r   flaskr   r   
flask_mailr   r   Z)Consultas_SQL.Utilities.MailManagementSQLr   r	   r
   r   basicConfigINFO	getLogger__name__r1   rP   r?   rA   r@   rx   r{   rN   rN   rN   rO   <module>   s,   
      
 g/* )