"""
Genera el JSONL de batch, lo sube a OpenAI y registra el batch en la DB.

Uso:
    python generar_batch.py [cantidad_edictos]

Variables de entorno requeridas:
    APIKEY_CHATGPT, PATH_BATCH_INPUT,
    SERVER_D, DATABASE_D, USERNAME_D, PASSWORD_D
"""

from dotenv import load_dotenv
import datetime
import logging
import json
import os
import pathlib
import socket
import sys
import uuid

# Asegura que la raíz del proyecto esté en sys.path para poder importar
# `helpers` y `procesamiento` cuando el script se ejecuta directamente.
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))))

import helpers.db as db
import procesamiento.batch_openai.openai_client as openai_client
from helpers.logging_setup import setup_logging, setup_logging_db

load_dotenv()
_run_id = setup_logging("generar_batch")

ID_PROMPT  = 23
TOKENS     = 1000
MAX_SIZE   = 209_715_200  # 200 MB
ID_PROCESO = int(os.getenv("ID_PROCESO_GENERAR_BATCH", 0))


def generar_batch(cantidad_edictos=2000):
    api_key = os.getenv("APIKEY_CHATGPT")
    if not api_key:
        raise ValueError("APIKEY_CHATGPT no está definida en las variables de entorno.")

    prompt_data = db.ejecutar_sp(
        'gestor_prompts',
        ['SELECT_ONE', None, None, None, None, None, None, None, ID_PROMPT],
    )
    
    if not prompt_data:
        return logging.warning("No se encontraron prompts")

    model         = 'gpt-5.4-mini'#prompt_data[0]["ai_provider"]
    system_prompt = prompt_data[0]["system_prompt"]
    user_prompt   = prompt_data[0]["user_prompt"]

    edictos = db.ejecutar_sp(
        "openai_edictos_dia",
        ['BUSQUEDA_VACIOS', None, None, 11, None, cantidad_edictos],
    )
    if not edictos:
        return logging.info("No se encontraron edictos")

    logging.info(f"Edictos encontrados: {len(edictos)}")

    directorio = os.getenv('PATH_BATCH_INPUT')
    os.makedirs(directorio, mode=0o777, exist_ok=True)

    timestamp  = datetime.datetime.now().strftime('%Y%m%d_%H%M%S')
    unique_id  = uuid.uuid4().hex[:6]
    batch_file = os.path.join(directorio, f'batchinput_{timestamp}_{unique_id}.jsonl')

    lineas = [
        openai_client.formatear_linea_batch(
            edicto.get('fecha_publicacion', '') or '',
            edicto.get('id_fide', '')           or '',
            edicto.get('fuente', '')             or '',
            model, system_prompt, user_prompt,
            edicto['contenido_archivo'],
            TOKENS,
        )
        for edicto in edictos
    ]

    with open(batch_file, 'w', encoding='utf-8') as f:
        for linea in lineas:
            f.write(json.dumps(linea, ensure_ascii=False) + '\n')

    logging.info(f"Archivo generado: {batch_file}")

    if os.path.getsize(batch_file) > MAX_SIZE:
        return logging.error(f"Archivo supera 200 MB ({os.path.getsize(batch_file)} bytes)")

    file_resp  = openai_client.subir_archivo(batch_file, api_key)
    batch_resp = openai_client.crear_batch(file_resp['id'], api_key)
    logging.info(f"BATCH_CREADO | batch_id={batch_resp['id']} file_id={file_resp['id']}")
    db.ejecutar_sp('gestor_batch_procesos', [
        'INSERT', None, batch_resp['id'], None, 'pendiente',
        ID_PROMPT, 'batch grande diario', cantidad_edictos, None, batch_file, None
    ])
    logging.debug(f"BATCH_RESPUESTA | {json.dumps(batch_resp, ensure_ascii=False)}")


if __name__ == "__main__":
    logging.info("Inicio del proceso")
    cantidad = 2000 #int(sys.argv[1]) if len(sys.argv) > 1 else 100

    id_log = None
    try:
        result = db.ejecutar_sp('PRS_iniciar', [
            ID_PROCESO,
            socket.gethostbyname(socket.gethostname()),
            os.getpid(),
            socket.gethostname(),
            12,
            _run_id,
        ])
        if result:
            id_log = result[0].get('id_log')
            setup_logging_db(id_log)
    except Exception as e:
        logging.warning(f"PRS_iniciar falló: {e}")

    ok_count = 0
    error_count = 0
    total = cantidad
    try:
        generar_batch(cantidad)
        ok_count = 1
    except Exception as e:
        error_count = 1
        logging.error(f"Error en generar_batch: {e}")
    finally:
        if id_log is not None:
            try:
                db.ejecutar_sp('PRS_finalizar', [id_log, None, total, ok_count, error_count])
            except Exception as e:
                logging.warning(f"PRS_finalizar falló: {e}")