# Archivo: RecepcionCotiz.py
# Ruta: src\App\Ventas_Module\Cotiz\RecepcionCotiz.py

from flask import render_template, request, session, jsonify, redirect, url_for
from functools import wraps
import logging, json
from datetime import datetime
from typing import Dict, List

# Importar funciones SQL específicas para recepción de cotizaciones
from Consultas_SQL.Ventas.Cotiz.RecepcionCotizSQL import (
    buscar_cotizacion_completa,
    actualizar_lineas_cotizacion,
    actualizar_calculo_financiero,
    actualizar_tiempo_y_condiciones,
    finalizar_cotizacion_y_enviar
)
# Importar utilidades
from App.Utilities_module.MailManagement import enviar_correo_universal

logger = logging.getLogger('recepcion_cotizacion')

def registrar_rutas_recepcion_cotizacion(app, mail): # Nombre más claro
    """
    Función principal que registra todas las rutas del módulo de recepción de cotizaciones.
    """    

    # =========================================================================================
    # RUTA 1: BÚSQUEDA DE COTIZACIÓN
    # =========================================================================================
    @app.route("/Ventas/Cotiz/Recepcion/BuscarCotizacion", methods=['POST'])
    def buscar_cotizacion():
        """Busca y recupera todos los datos de una cotización finalizada por ingeniería."""
        try:
            data = request.get_json()
            if not data or 'cotizacion_id' not in data:
                return jsonify({"success": False, "error": {"message": "ID de cotización no proporcionado.", "code": "INVALID_REQUEST"}}), 400
            
            cotizacion_id = data['cotizacion_id'].strip()
            logger.info(f"Buscando cotización completada: {cotizacion_id}")
            
            # Llamada al DAO para buscar la cotización
            cotizacion_completa = buscar_cotizacion_completa(cotizacion_id)
            
            if cotizacion_completa and cotizacion_completa.get('StatusIngenieria', 'PENDIENTE') in ['COMPLETADO', 'FINALIZADA']:
                logger.info(f"Cotización {cotizacion_id} encontrada y lista para revisión.")
                return jsonify({
                    "success": True,
                    "data": cotizacion_completa,
                    "message": "Cotización lista para revisión final."
                }), 200
            elif cotizacion_completa:
                # La cotización existe, pero no ha sido completada por ingeniería
                status = cotizacion_completa.get('StatusIngenieria', 'PENDIENTE')
                logger.warning(f"Cotización {cotizacion_id} no está lista. Estatus: {status}")
                return jsonify({
                    "success": False,
                    "error": {
                        "message": f"La cotización aún no ha sido finalizada por Ingeniería. Estado actual: {status}",
                        "alert_type": "info",
                        "code": "COTIZACION_PENDIENTE"
                    }
                }), 409
            else:
                logger.warning(f"Cotización {cotizacion_id} no encontrada en el sistema.")
                return jsonify({
                    "success": False,
                    "error": {
                        "message": f"El ID de cotización '{cotizacion_id}' no existe o no está activo.",
                        "alert_type": "warning",
                        "code": "COTIZACION_NOT_FOUND"
                    }
                }), 404

        except Exception as e:
            logger.error(f"Error en búsqueda de cotización: {str(e)}", exc_info=True)
            return jsonify({"success": False, "error": {"message": "Error interno del servidor en la búsqueda.", "code": "INTERNAL_ERROR", "alert_type": "error"}}), 500


    # =========================================================================================
    # RUTA 2: ENVÍO FINAL DE LA COTIZACIÓN (Procesa la venta y notifica)
    # =========================================================================================
    @app.route("/Ventas/Cotiz/Recepcion/EnviarCotizacion", methods=['POST'])
    def enviar_cotizacion():
        """Procesa la cotización final, actualiza el estado y notifica al cliente/CRM."""
        user_id = session.get('user_id')
        if not user_id:
            return jsonify({"success": False, "error": {"message": "Usuario no autenticado", "code": "NOT_AUTHENTICATED"}}), 401
            
        try:
            data = request.get_json()
            if not data or 'cotizacion_id' not in data:
                return jsonify({"success": False, "error": {"message": "Datos de cotización incompletos.", "code": "INVALID_REQUEST"}}), 400
            
            cotizacion_id = data['cotizacion_id']
            # Obtener datos para la actualización
            financieros = data['financieros']
            lineas = data['lineas']
            tiempo_condiciones = data['tiempo_condiciones']
            
            logger.info(f"Iniciando proceso de finalización para Cotización: {cotizacion_id}")
            
            # 1. Actualizar las líneas de cotización (si hay cambios en cantidad/descuento manual)
            # Nota: Esto es opcional, pero se incluye por si el vendedor puede ajustar algo.
            # (Se asume una función para guardar líneas de DataTables)
            resultado_lineas = actualizar_lineas_cotizacion(cotizacion_id, lineas, user_id)
            if not resultado_lineas['success']:
                return jsonify({"success": False, "error": {"message": f"Error al actualizar líneas: {resultado_lineas['message']}", "alert_type": "warning"}}), 500

            # 2. Actualizar la sección de cálculo financiero
            resultado_financiero = actualizar_calculo_financiero(cotizacion_id, financieros, user_id)
            if not resultado_financiero['success']:
                return jsonify({"success": False, "error": {"message": f"Error al actualizar datos financieros: {resultado_financiero['message']}", "alert_type": "warning"}}), 500

            # 3. Actualizar tiempo de entrega y condiciones
            resultado_tiempo = actualizar_tiempo_y_condiciones(cotizacion_id, tiempo_condiciones, user_id)
            if not resultado_tiempo['success']:
                return jsonify({"success": False, "error": {"message": f"Error al actualizar tiempo y condiciones: {resultado_tiempo['message']}", "alert_type": "warning"}}), 500

            # 4. Finalizar la cotización: Marcar como 'ENVIADA_A_CLIENTE' y crear PDF final
            resultado_final = finalizar_cotizacion_y_enviar(cotizacion_id, user_id, data)
            if not resultado_final['success']:
                return jsonify({"success": False, "error": {"message": f"Error al finalizar cotización: {resultado_final['message']}", "alert_type": "error"}}), 500
            
            # 5. Enviar Correo de Notificación al Cliente (Usando la utilidad de correo)
            # Asumiendo que `resultado_final` contiene la URL del PDF final
            if resultado_final.get('pdf_url'):
                enviar_correo_cliente_v2(cotizacion_id, data, user_id, resultado_final['pdf_url'])
            
            logger.info(f"Cotización {cotizacion_id} finalizada y enviada exitosamente.")
            return jsonify({
                "success": True,
                "message": f"La cotización {cotizacion_id} ha sido enviada al cliente y actualizada en el CRM.",
                "data": {"cotizacion_id": cotizacion_id, "pdf_url": resultado_final.get('pdf_url')}
            }), 200

        except Exception as e:
            logger.error(f"Error inesperado en el envío final: {str(e)}", exc_info=True)
            return jsonify({"success": False, "error": {"message": "Error interno del servidor en el envío final.", "code": "INTERNAL_ERROR", "alert_type": "error"}}), 500

# ----------------------------------------------------------------------------------------
# FUNCIONES AUXILIARES (simuladas aquí, usarías tus módulos)
# ----------------------------------------------------------------------------------------

def enviar_correo_cliente_v2(cotizacion_id: str, data: Dict, user_id: int, pdf_url: str):
    """Simula el envío de correo de cotización al cliente."""
    try:
        # 1. Obtener datos necesarios (cliente, correo, nombre del vendedor)
        # Esto debería venir del resultado de la búsqueda o de una función SQL
        cliente_email = data.get('oportunidad', {}).get('CRM_ContactEmail', 'correo_prueba@igsa.com.mx')
        cliente_name = data.get('oportunidad', {}).get('CRM_ContactName', 'Cliente Estimado')
        
        # 2. Construir el template de datos
        template_data = {
            "cliente_nombre": cliente_name,
            "cotizacion_id": cotizacion_id,
            "pdf_url": pdf_url,
            "fecha_envio": datetime.now().strftime('%d/%m/%Y'),
            # ... otros datos para el template
        }
        
        # 3. Llamar al motor de correo universal (que debe manejar attachments o links)
        resultado = enviar_correo_universal(
            template_path='Emails/Ventas/Cotiz/CotizFinalClientMail.html',
            asunto=f"Cotización Finalizada - ID {cotizacion_id}",
            to_list=[cliente_email], # Enviar directamente al cliente
            template_data=template_data
        )
        
        if not resultado['success']:
            logger.warning(f"Error al enviar correo al cliente {cliente_email}: {resultado['mensaje']}")
            return {'success': False, 'message': resultado['mensaje']}
        
        logger.info(f"Correo de cotización enviado exitosamente al cliente: {cliente_email}")
        return {'success': True}
        
    except Exception as e:
        logger.error(f"Error en el proceso de envío de correo al cliente: {str(e)}")
        return {'success': False, 'message': str(e)}