import cv2
import json
import re
from src.validators.deteccion import detectar_rostro
import numpy as np
face_cascade = cv2.CascadeClassifier(cv2.data.haarcascades + "haarcascade_frontalface_default.xml")



def sanitizar_json_no_estricto(texto):
    # Agrega comillas dobles a claves sin comillas
    return re.sub(r'(?<!")(\b\w+\b)(?=\s*:)', r'"\1"', texto)


def simular_respuesta_openai_con_usage():
    respuesta_simulada = """
    {
        "es_persona": true,
        "usa_lentes": false,
        "usa_auriculares": false,
        "vida_detectada": true,
        "accesorios": false
    }
    """
    usage_simulado = {
        "prompt_tokens": 28500,
        "completion_tokens": 50,
        "total_tokens": 28550
    }
    return respuesta_simulada, usage_simulado

def estimar_costo_usd_por_tokens(total_tokens: int, modelo: str = "gpt-4o") -> float:
    # Precios oficiales julio 2025 (simulados)
    precios = {
        "gpt-4o": 0.000005 / 1,    # $0.005 por 1K tokens input, $0.015 output (no diferenciamos aquí)
    }
    costo = total_tokens * precios.get(modelo, 0.000005)
    return round(costo, 4)

def procesar_prueba_vida_avanzada(video_path: str) -> dict:
    cap = cv2.VideoCapture(video_path)
    total_frames = 0
    frame_openai_1 = None
    frame_openai_2 = None
    rostros = 0

    while cap.isOpened():
        ret, frame = cap.read()
        if not ret:
            break
        total_frames += 1

        gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
        rostro = detectar_rostro(gray)
        if rostro is not None:
            rostros += 1
            x, y, w, h = rostro
            if total_frames == 3:
             frame_openai_1 = recortar_rostro(frame)
            if total_frames == 6:
               frame_openai_2 = recortar_rostro(frame)

    cap.release()

    openai_resultado = {}
    usage_simulado = {}

    if frame_openai_1 is not None and frame_openai_2 is not None:
        try:
            resultado_openai, usage_simulado = simular_respuesta_openai_con_usage()
            resultado_openai = resultado_openai.strip()

            match = re.search(r"{[\s\S]*?}", resultado_openai)
            resultado_limpio = match.group(0) if match else resultado_openai

            try:
                openai_resultado = json.loads(resultado_limpio)
            except json.JSONDecodeError:
                json_corr = sanitizar_json_no_estricto(resultado_limpio)
                openai_resultado = json.loads(json_corr)

            # Imprimir en terminal
            print("\n[SIMULACIÓN - JSON LIMPIO]")
            print(json.dumps(openai_resultado, indent=2))

            print("\n[SIMULACIÓN - TOKEN USAGE]")
            print(json.dumps(usage_simulado, indent=2))

            costo = estimar_costo_usd_por_tokens(usage_simulado["total_tokens"])
            print(f"\n[COSTO ESTIMADO]: ${costo} USD")

        except Exception as e:
            openai_resultado = {
                "error_lhia": str(e),
                "raw": locals().get("resultado_limpio", "")
            }

    return {
        "resultado_vida": openai_resultado,
        "vida_detectada": openai_resultado.get("vida_detectada", False),
        "usa_lentes": openai_resultado.get("usa_lentes"),
        "usa_auriculares": openai_resultado.get("usa_auriculares"),
        "porcentaje_rostros": round(100 * rostros / total_frames, 2) if total_frames else 0,
        "token_usage": usage_simulado
    }


def recortar_rostro(frame: np.ndarray) -> np.ndarray:
    gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
    rostros = face_cascade.detectMultiScale(gray, scaleFactor=1.1, minNeighbors=5)

    for (x, y, w, h) in rostros:
        margin = 20
        x1 = max(x - margin, 0)
        y1 = max(y - margin, 0)
        x2 = min(x + w + margin, frame.shape[1])
        y2 = min(y + h + margin, frame.shape[0])

        rostro_recortado = frame[y1:y2, x1:x2]
        return cv2.resize(rostro_recortado, (224, 224))  # tamaño estandarizado

    return None  # si no hay rostro