from django.shortcuts import render
from django.http import JsonResponse
from django.views.decorators.csrf import csrf_exempt
import json
import os
from datetime import datetime, timedelta

# Gemini Imports
from .gemini_client import GeminiClient
from .rag_service import RAGService

# OpenAI Imports (Legacy)
try:
    from langchain_community.llms import OpenAI
    from langchain.chains import LLMChain
    from langchain.prompts import PromptTemplate
except ImportError:
    print("WARNING: OpenAI dependencies could not be imported. OpenAI Agent will be unavailable.")
    OpenAI = None
    LLMChain = None
    PromptTemplate = None
except Exception as e:
    print(f"WARNING: Error importing OpenAI dependencies: {e}")
    OpenAI = None
    LLMChain = None
    PromptTemplate = None

# Importamos los modelos reales de empresa y contacto
try:
    from Models.Empresa import Empresa
    print("Usando modelo Empresa desde Models.Empresa")
except ImportError:
    try:
        from api_empresa.models import Empresa
        print("Usando modelo Empresa desde api_empresa.models")
    except ImportError:
        print("No se pudo importar ningún modelo de Empresa, usando simulación")
        class Empresa:
            objects = None

# Import OportunidadDeVenta with fallbacks
try:
    from Models.oportunidad_de_venta_model import OportunidadDeVenta
    print("Usando modelo OportunidadDeVenta desde Models")
except ImportError:
    try:
        from api_oportunidad_de_venta.models import OportunidadDeVenta
        print("Usando modelo OportunidadDeVenta desde api")
    except ImportError:
        print("No se pudo importar OportunidadDeVenta, simulación")
        class OportunidadDeVenta:
            objects = None

# Common helper functions (could be moved to a mixin or utils)
def get_new_companies_this_month():
    current_month = datetime.now().month
    current_year = datetime.now().year
    try:
        new_companies = Empresa.objects.filter(
            fecha_creacion__month=current_month,
            fecha_creacion__year=current_year,
            deleted_at__isnull=True
        )
        return [{
            "nombre": c.nombre,
            "fecha_creacion": c.fecha_creacion.strftime("%Y-%m-%d"),
            "cuit": getattr(c, 'cuit', "No disponible"),
            "provincia": getattr(c.provincia, 'nombre', "No disponible") if hasattr(c, 'provincia') else "No disponible",
            "localidad": getattr(c.localidad, 'nombre', "No disponible") if hasattr(c, 'localidad') else "No disponible",
            "direccion": getattr(c, 'direccion', "No disponible")
        } for c in new_companies]
    except Exception as e:
        print(f"Error al obtener empresas: {str(e)}")
        return []

def get_recent_activities():
    try:
        try:
            from api_actividad.models import Actividad
        except ImportError:
            try:
                from Models.api_actividad_model import Actividad
            except ImportError:
                print("No se pudo importar el modelo de Actividad")
                return []
                
        fecha_limite = datetime.now() - timedelta(days=7)
        actividades = Actividad.objects.filter(
            fecha__gte=fecha_limite,
            deleted_at__isnull=True
        ).order_by('-fecha')[:10]
        
        return [{
            "tipo": getattr(a, 'tipo', "General"),
            "empresa": a.empresa.nombre if hasattr(a, 'empresa') and a.empresa else "No especificada",
            "fecha": a.fecha.strftime("%Y-%m-%d") if hasattr(a, 'fecha') else "Fecha no disponible",
            "notas": getattr(a, 'descripcion', "Sin notas")
        } for a in actividades]
    except Exception as e:
        print(f"Error al obtener actividades: {str(e)}")
        return []

def get_system_stats():
    """Retrieves real-time statistics from the database"""
    try:
        total_clientes = Empresa.objects.filter(deleted_at__isnull=True, tipo_empresa=2).count()
        total_datos = Empresa.objects.filter(deleted_at__isnull=True, tipo_empresa=1).count()
        
        # Oportunidades
        try:
            total_oportunidades = OportunidadDeVenta.objects.filter(deleted_at__isnull=True).count()
        except:
            total_oportunidades = 0
            
        return {
            "total_clientes": total_clientes,
            "total_datos_potenciales": total_datos,
            "total_oportunidades": total_oportunidades,
            "resumen": f"El sistema cuenta con {total_clientes} clientes activos, {total_datos} datos potenciales y {total_oportunidades} oportunidades de venta registradas."
        }
    except Exception as e:
        print(f"Error stats: {e}")
        return {}

class GeminiAgent:
    def __init__(self):
        try:
            self.client = GeminiClient()
            self.rag = RAGService()
            print("Inicializando GeminiAgent con RAG")
        except Exception as e:
            raise Exception(f"Error inicializando Gemini: {e}")

    def process_query(self, query, context_data=None):
        if not context_data:
            context_data = {}
            new_companies = get_new_companies_this_month()
            if new_companies: context_data["empresas_nuevas_mes"] = new_companies
            activities = get_recent_activities()
            if activities: context_data["actividades_recientes"] = activities
            
            # [NEW] Add Real-time Stats
            stats = get_system_stats()
            if stats: context_data["estadisticas_sistema"] = stats

        rag_results = []
        try:
            # RAG Search
            rag_results = self.rag.search(query)
            
            # [ANSWER BANK] Check for exact/high-confidence matches in metadata for stored answers
            # This is a simple implementation: if a document has metadata type='answer_bank' and high score, we use it directly.
            for result in rag_results:
                meta = result.get('metadata')
                # Assuming score is 0-1 distance (lower is better) or similarity (1 is best). 
                # Implementation returns cosine distance (0=same), so looking for close to 0
                if meta and meta.get('type') == 'answer_bank' and result.get('score', 1) > 0.85: # 0.85 similarity threshold
                    print(f"Using Cached Answer: {result['content']}")
                    return result['content']
            
            context_data["knowledge_base"] = rag_results
        except Exception as e:
            print(f"RAG Error: {e}")
            context_data["knowledge_base"] = []

        formatted_context = json.dumps(context_data, ensure_ascii=False, indent=2)
        prompt = f"""
        Eres un asistente experto para el CRM Dreinet.
        
        INSTRUCCIONES CRÍTICAS:
        1. Tu objetivo es responder preguntas sobre el ESTADO ACTUAL del negocio usando los datos proporcionados.
        2. Si te preguntan "cuántos", "reporte", o "estado", TIENES QUE USAR los datos de 'estadisticas_sistema' o 'empresas_nuevas_mes'.
        3. NO describas capacidades. RESPONDE CON NÚMEROS.
        4. Si el usuario pregunta algo que ya está en 'knowledge_base' (como un reporte anterior guardado), úsalo.
        5. IMPORTANTE: SIEMPRE menciona los números exactos de clientes, datos y oportunidades si te piden un resumen.
        
        DATOS EN TIEMPO REAL:
        {formatted_context}
        
        PREGUNTA DEL USUARIO: {query}
        
        Respuesta:
        """
        return self.client.generate_content(prompt).strip()

class OpenAIAgent:
    def __init__(self):
        if OpenAI is None:
            raise Exception("OpenAI libraries are not available due to dependency issues.")
            
        self.use_simulation = False
        try:
            os.environ["OPENAI_API_KEY"] = os.getenv("OPENAI_API_KEY")
            self.llm = OpenAI(temperature=0.7)
            print("Inicializando OpenAIAgent")
        except Exception as e:
            raise Exception(f"Error inicializando OpenAI: {e}")

    def process_query(self, query, context_data=None):
        if not context_data:
            context_data = {}
            new_companies = get_new_companies_this_month()
            if new_companies: context_data["empresas_nuevas_mes"] = new_companies
            activities = get_recent_activities()
            if activities: context_data["actividades_recientes"] = activities

        template = """
        Eres un asistente para un sistema CRM llamado Dreinet CRM.
        Información disponible (formato JSON):
        {context}
        Pregunta del usuario: {query}
        Responde de manera profesional.
        """
        prompt = PromptTemplate(input_variables=["context", "query"], template=template)
        chain = LLMChain(llm=self.llm, prompt=prompt)
        formatted_context = json.dumps(context_data, ensure_ascii=False, indent=2)
        return chain.run(context=formatted_context, query=query).strip()

@csrf_exempt
def agent_query(request):
    if request.method == 'POST':
        try:
            data = json.loads(request.body)
            query = data.get('query', '')
            if not query: return JsonResponse({"error": "Consulta vacía"}, status=400)

            # Switch logic: Default to Gemini, fall back to OpenAI if requested or env var set
            provider = os.getenv('AI_PROVIDER', 'gemini').lower()
            
            if provider == 'openai':
                agent = OpenAIAgent()
            else:
                agent = GeminiAgent()

            response = agent.process_query(query)
            return JsonResponse({"response": response})

        except Exception as e:
            return JsonResponse({"error": f"Error: {str(e)}"}, status=500)
    return JsonResponse({"error": "Method not allowed"}, status=405)

def chat_view(request):
    return render(request, 'ai_agent/chat.html')
