import os
import openai
import mysql.connector
from dotenv import load_dotenv
from datetime import datetime
from typing import List
from pydantic import BaseModel
import json
from db_utils import get_db, save_message

load_dotenv()
#openai.api_key = os.getenv("OPENAI_API_KEY")

MESSAGE_LIMIT = int(os.getenv("MESSAGE_ANALYSIS_LIMIT", 100))


client = openai.OpenAI(api_key=os.getenv("OPENAI_API_KEY"))

class LeadAnalysis(BaseModel):
    is_lead: bool
    funnel_stage: str
    topics_detected: List[str]
    possible_project: str
    search_criteria: str
    suggested_next_action: str

def obtener_conversaciones_por_contacto(db):
    cursor = db.cursor(dictionary=True)
    cursor.execute("SELECT id FROM contact where source != 'email'")
    contactos = cursor.fetchall()

    conversaciones = []
    for contacto in contactos:
        # Obtener última fecha de análisis
        cursor.execute("SELECT MAX(analyzed_at) AS last_analysis FROM message_analysis WHERE contact_id = %s", (contacto["id"],))
        last_analysis = cursor.fetchone()["last_analysis"]

        # Verificar si hay mensajes nuevos desde la última fecha de análisis
        if last_analysis:
            cursor.execute("""
                SELECT COUNT(*) AS nuevos FROM message
                WHERE contact_id = %s AND timestamp > %s
            """, (contacto["id"], last_analysis))
            if cursor.fetchone()["nuevos"] == 0:
                continue  # No hay mensajes nuevos

        cursor.execute(f"""
            SELECT m.*, u.name AS user_name
            FROM message m
            JOIN user_account u ON m.user_id = u.id
            WHERE m.contact_id = %s
            ORDER BY m.timestamp ASC
            LIMIT {MESSAGE_LIMIT}
        """, (contacto["id"],))
        mensajes = cursor.fetchall()
        if mensajes:
            conversaciones.append((contacto["id"], mensajes))
    return conversaciones


def construir_mensaje_texto(mensajes):
    texto = ""
    total_tokens = 0
    for msg in reversed(mensajes):
        autor = "ASESOR" if msg["direction"] == "outgoing" else "CLIENTE"
        linea = f"{autor}: {msg['content']}\n"
        #tokens = len(encoder.encode(linea))
        #if total_tokens + tokens > MAX_PROMPT_TOKENS:
        #    break
        texto = linea + texto
        #total_tokens += tokens
    return texto

def analizar_conversacion(conversacion):
    try:
        response = client.responses.create(
            model="gpt-4o",
            input=[
                {"role": "system", "content": "Sos un asistente especializado en ventas inmobiliarias para la desarrolladora Quartier (marca de Argencons S.A.). Tu tarea es: 1. Leer la conversación de WhatsApp entre un lead y un vendedor. 2. Determinar en qué estado del embudo se encuentra el lead. 3. Sugerir una acción si corresponde (ej. enviar follow-up, agendar_meet, etc).Actuá como un analista de ventas inmobiliarias. Vas a recibir el historial de mensajes entre un posible cliente y un asesor de ventas."},
                {"role": "user", "content": conversacion}
            ],
            text={
                "format": {
                    "type": "json_schema",
                    "name": "lead_analysis",
                    "schema": {
                        "type": "object",
                        "properties": {
                            "is_lead": {
                                "type": "boolean",
                                "description": "es un lead"
                            },
                            "funnel_stage": {
                                "type": "string",
                                "description": "etapa del embudo de ventas según tabla crestados: - **new**: El lead no respondió ningún mensaje - **warm**: Mostró interés general - **appt**: Acordó reunión o visita - **cold**: El lead deja de responder luego de 10 días pero antes haber estado en conversación - **won**: Ya reservó o compró - **lost**: No está interesado o no respondió - **wrong**: Está interesado en algo fuera de lo que ofrecemos (Alquiler, zona incorrecta, nada de real estate, etc) - **no_lead**: Los medios de contacto dieron error, nunca se pudo establecer conversación durante 30 días ó lo que dijo fue que no está interesado o que nunca lo estuvo",
                                "enum": [
                                    "new",
                                    "warm", 
                                    "appt",
                                    "cold",
                                    "won",
                                    "lost",
                                    "wrong",
                                    "no_lead"
                                ]
                            },
                            "topics_detected": {
                                "type": "array",
                                "items": {
                                    "type": "string"
                                }
                            },
                            "possible_project": {
                                "type": "string",
                                "description": "proyecto posible de interés",
                                "enum": [
                                    "Quartier Juan B. Justo",
                                    "Quartier Brava 30",
                                    "Quartier Bajo Belgrano",
                                    "Quartier +Colonia",
                                    "Quartier Del Bajo",
                                    "Distrito Quartier",
                                    "Edificio Plaza",
                                    "Quartier Lacroze",
                                    "Quartier Dorrego",
                                    "Quartier Nordelta",
                                    "Otros Quartier"
                                ]
                            },
                            "search_criteria": {
                                "type": "string",
                                "description": "criterios de búsqueda"
                            },
                            "suggested_next_action": {
                                "type": "string",
                                "description": "siguiente acción sugerida según tabla cracciones: - **followup_1**: Primer seguimiento automático luego de 48hs sin respuesta - **followup_2**: Segundo seguimiento luego de propuesta sin respuesta (72hs) - **enviar_info**: Enviar información o brochure solicitado - **reactivar**: Reactivar lead que estaba en estado perdido y vuelve a escribir - **cerrar**: Marcar como venta concretada (won) - **agendar_meet**: Coordinar videollamada o reunión presencial - **agendar_visita**: Coordinar visita al showroom o a la obra - **esperar**: No hacer nada por el momento - **archivar**: Archivar el lead (fuera del embudo activo)",
                                "enum": [
                                    "followup_1",
                                    "followup_2",
                                    "enviar_info",
                                    "reactivar",
                                    "cerrar",
                                    "agendar_meet",
                                    "agendar_visita",
                                    "esperar",
                                    "archivar"
                                ]
                            },
                        },
                        "required": [
                            "is_lead",
                            "funnel_stage",
                            "topics_detected",
                            "possible_project",
                            "search_criteria",
                            "suggested_next_action"
                        ],
                        "additionalProperties": False
                    },
                    "strict": True
                }
            }
        )
        return LeadAnalysis.model_validate(json.loads(response.output_text))
    except Exception as e:
        print(f"❌ Error al llamar a OpenAI: {e}")
        return None

def guardar_analisis(db, contact_id, datos: LeadAnalysis):
    cursor = db.cursor()
    resumen = f"Lead: {'sí' if datos.is_lead else 'no'}, Proyecto: {datos.possible_project}, Estado: {datos.funnel_stage}, Acción: {datos.suggested_next_action}"
    cursor.execute("""
        INSERT INTO message_analysis (
            contact_id, is_lead, funnel_stage,
            topics_detected, suggested_next_action,
            possible_project, search_criteria, analyzed_at,
            resumen
        ) VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s)
    """, (
        contact_id,
        datos.is_lead,
        datos.funnel_stage,
        ', '.join(datos.topics_detected),
        datos.suggested_next_action,
        datos.possible_project,
        datos.search_criteria,
        datetime.now(),
        resumen
    ))
    db.commit()
    return resumen


def main():
    db = get_db()
    conversaciones = obtener_conversaciones_por_contacto(db)
    print(f"🧠 Analizando {len(conversaciones)} conversaciones...")

    for contact_id, mensajes in conversaciones:
        print(f"🔍 Analizando mensajes del contacto {contact_id} : {len(mensajes)} mensajes...")
        #prompt = construir_prompt(mensajes)
        texto = construir_mensaje_texto(mensajes)
        respuesta = analizar_conversacion(texto)
        if respuesta:
            try:
                resume = guardar_analisis(db, contact_id, respuesta)
                print(f"✅ Análisis guardado para contacto {contact_id}: {resume}")
            except Exception as e:
                print(f"❌ Error al parsear/guardar respuesta: {e}\nRespuesta:\n{respuesta}")

if __name__ == '__main__':
    main()

