#!/usr/bin/env python3
# -*- coding: utf-8 -*-

import os
import json
import argparse
import logging
import pymysql
from dotenv import load_dotenv
from datetime import datetime

# -----------------------------------------------------------------------------
# Configuración
# -----------------------------------------------------------------------------
logging.basicConfig(
    level=logging.INFO,
    format="%(asctime)s %(levelname)s %(message)s"
)

load_dotenv()

DB_USER = os.getenv('DB_USER')
DB_PASSWORD = os.getenv('DB_PASSWORD')
DB_HOST = os.getenv('DB_HOST')
DB_NAME = os.getenv('DB_NAME')

# -----------------------------------------------------------------------------
# Función existente: guarda Json_full por whatsapp_user_id
# -----------------------------------------------------------------------------
def save_json_full_to_db(raw_data):
    """
    Guarda el JSON completo en UserInteraction.Json_full (tipo JSON),
    haciendo match entre UserInteraction.whatsapp_user_id y "whatsapp user id"
    dentro del mismo JSON.
    """
    try:
        # 1) Obtener el texto JSON en UTF-8
        if isinstance(raw_data, (bytes, bytearray)):
            json_text = raw_data.decode('utf-8', errors='strict')
        elif isinstance(raw_data, str):
            json_text = raw_data
        else:
            # Por si llega dict u otro objeto serializable
            json_text = json.dumps(raw_data, ensure_ascii=False)

        # 2) Validar que es JSON y extraer el whatsapp user id
        data_obj = json.loads(json_text)  # valida estructura JSON
        wa_id = data_obj.get('whatsapp user id')
        if not wa_id:
            raise ValueError("El JSON no contiene la llave 'whatsapp user id'.")

        # 3) Actualizar en DB por whatsapp_user_id
        connection = pymysql.connect(
            host=DB_HOST,
            user=DB_USER,
            password=DB_PASSWORD,
            database=DB_NAME,
            cursorclass=pymysql.cursors.DictCursor,
            charset='utf8mb4',
            use_unicode=True,
        )
        with connection:
            with connection.cursor() as cursor:
                sql = """
                    UPDATE UserInteraction
                       SET Json_full = CAST(%s AS JSON)
                     WHERE whatsapp_user_id = %s
                """
                cursor.execute(sql, (json_text, wa_id))
            connection.commit()
            logging.info(f"✅ Json_full actualizado para whatsapp_user_id={wa_id}; filas afectadas: {cursor.rowcount}")
            return cursor.rowcount

    except Exception as e:
        logging.error(f"Error guardando Json_full: {e}")
        raise

# -----------------------------------------------------------------------------
# Utilidades
# -----------------------------------------------------------------------------
def list_json_files_sorted(folder_path):
    """
    Lista archivos .json de una carpeta, ordenados por fecha de modificación
    (más antiguo -> más nuevo).
    """
    if not os.path.isdir(folder_path):
        raise FileNotFoundError(f"La carpeta no existe: {folder_path}")

    files = []
    for name in os.listdir(folder_path):
        if not name.lower().endswith(".json"):
            continue
        full = os.path.join(folder_path, name)
        if os.path.isfile(full):
            files.append(full)

    files.sort(key=lambda p: os.path.getmtime(p))
    return files

# -----------------------------------------------------------------------------
# Proceso batch
# -----------------------------------------------------------------------------
def process_folder(folder_path: str, limit: int = None):
    """
    Recorre la carpeta 'folder_path' de antiguo a nuevo, procesando JSONs.
    Si falta 'whatsapp phone', imprime error y continúa con el siguiente.
    """
    files = list_json_files_sorted(folder_path)
    if limit is not None and limit > 0:
        files = files[:limit]

    total = len(files)
    ok = 0
    skipped_no_phone = 0
    errors = 0

    logging.info(f"📁 Carpeta: {folder_path}")
    logging.info(f"🗂️ Archivos a procesar: {total}")

    for idx, path in enumerate(files, start=1):
        try:
            # Leer archivo como bytes (para mantener exactitud del JSON original)
            with open(path, "rb") as f:
                raw = f.read()

            # Chequear existencia de "whatsapp phone" antes de guardar
            try:
                parsed = json.loads(raw.decode("utf-8"))
            except Exception as je:
                errors += 1
                logging.error(f"[{idx}/{total}] ❌ JSON inválido en '{os.path.basename(path)}': {je}")
                continue

            phone = parsed.get("whatsapp phone")
            if not phone:
                skipped_no_phone += 1
                logging.error(f"[{idx}/{total}] ⚠️ Sin 'whatsapp phone' en '{os.path.basename(path)}'. Se omite.")
                continue

            # Guardar JSON completo en la BD
            affected = save_json_full_to_db(raw)
            if affected and affected > 0:
                ok += 1
                logging.info(f"[{idx}/{total}] ✅ Guardado desde '{os.path.basename(path)}'")
            else:
                # No encontró match en DB por whatsapp_user_id
                errors += 1
                wa_id = parsed.get("whatsapp user id")
                logging.error(f"[{idx}/{total}] ❌ No se encontró fila en DB para whatsapp_user_id={wa_id} (archivo: {os.path.basename(path)})")

        except Exception as e:
            errors += 1
            logging.error(f"[{idx}/{total}] ❌ Error procesando '{os.path.basename(path)}': {e}")

    logging.info("────────────────────────────────────────")
    logging.info(f"✅ OK: {ok}   ⚠️ Sin teléfono: {skipped_no_phone}   ❌ Errores: {errors}   🧮 Total: {total}")

# -----------------------------------------------------------------------------
# Main CLI
# -----------------------------------------------------------------------------
def main():
    parser = argparse.ArgumentParser(
        description="Carga masiva provisional de Json_full desde carpeta 'interacciones'."
    )
    parser.add_argument(
        "--folder", "-f",
        default="interacciones",
        help="Carpeta donde están los .json (por defecto: interacciones)"
    )
    parser.add_argument(
        "--limit", "-n",
        type=int,
        default=None,
        help="Procesar solo los primeros N archivos (ordenados por fecha)"
    )
    args = parser.parse_args()

    process_folder(args.folder, args.limit)

if __name__ == "__main__":
    main()
