import os
import sys
import time
import logging
import subprocess
from concurrent.futures import ThreadPoolExecutor, as_completed

# --- AUTO-INSTALADOR ---
def install_missing():
    try:
        import pandas
        import requests
        import openpyxl
        import tqdm # Agregamos tqdm para ver una barra de progreso real
    except ImportError:
        subprocess.check_call([sys.executable, "-m", "pip", "install", "pandas", "requests", "openpyxl", "tqdm", "-q"])

install_missing()

import pandas as pd
import requests
from tqdm import tqdm

# --- LOGGING ---
logging.basicConfig(
    level=logging.INFO,
    format='%(asctime)s [%(levelname)s] %(message)s',
    handlers=[logging.FileHandler("ejecucion_telefonos.log", encoding='utf-8'), logging.StreamHandler(sys.stdout)]
)
logger = logging.getLogger(__name__)

# --- CONFIGURACIÓN ---
FILE_INPUT = 'CHK-IDMERIT_PhoneCheck_AR_POC_20260203.xlsx'
FILE_OUTPUT = 'CHK-IDMERIT_PhoneCheck_AR_POC_20260203_PROCESSED.xlsx'
API_URL = "https://api.fidelitas.com.ar/v3/telephone"
API_KEY = "WF6ABLD8J93EURIOPZK7"
COL_PHONE = "National Phone Number" # Columna H
MAX_WORKERS = 10  # Ajustar este número según la capacidad de la API

def process_api_sanitized(row_data):
    """
    Función optimizada para hilos.
    Recibe una tupla (index, phone) y retorna los resultados mapeados.
    """
    index, phone = row_data
    if not phone or str(phone).lower() == 'nan':
        return index, "SIN_DATOS", "", 0

    # Limpieza básica del teléfono
    phone_clean = str(phone).split('.')[0].replace(' ', '').strip()

    try:
        payload = {'apikey': API_KEY, 'phone': phone_clean}
        # Eliminamos el sleep manual. El paralelismo gestiona la espera.
        res = requests.post(API_URL, data=payload, timeout=15)

        if res.status_code != 200:
            return index, f"HTTP_{res.status_code}", "", 0

        data = res.json()
        items = data.get('response', [])
        if not isinstance(items, list):
            items = [items] if items else []

        cuits_unicos = set()
        nombres_unicos = set()
        blacklist = ["CLARO", "ERROR PROCESS", "NONE", "NULL", "ERROR_PROCESS"]

        for i in items:
            if isinstance(i, dict):
                raw_cuit = str(i.get('cuit', '')).replace('-', '').strip()
                raw_nombre = str(i.get('nombre', '')).strip().upper()

                if raw_cuit and raw_cuit not in blacklist and raw_cuit.isdigit():
                    cuits_unicos.add(raw_cuit)
                if raw_nombre and raw_nombre not in blacklist and raw_nombre != "":
                    nombres_unicos.add(raw_nombre)

        str_cuits = "/".join(sorted(list(cuits_unicos)))
        str_nombres = "/".join(sorted(list(nombres_unicos)))

        return index, str_cuits, str_nombres, len(items)

    except Exception as e:
        return index, "ERROR_API", str(e), 0

def main():
    if not os.path.exists(FILE_INPUT):
        logger.error(f"❌ No se encontró: {FILE_INPUT}")
        return

    logger.info(f"🚀 Iniciando proceso MULTIHILO en {FILE_INPUT}")
    df = pd.read_excel(FILE_INPUT)

    # Preparar columnas
    if 'TAXID' not in df.columns: df['TAXID'] = ""
    if 'NOMBRE_API' not in df.columns: df['NOMBRE_API'] = ""

    # Crear lista de tareas (index, phone)
    tasks = [(i, row[COL_PHONE]) for i, row in df.iterrows()]
    total_tasks = len(tasks)

    results_count = 0
    enriquecidos_ok = 0
    total_json_items = 0

    # Ejecución en paralelo
    logger.info(f"⚙️ Procesando con {MAX_WORKERS} hilos en paralelo...")

    with ThreadPoolExecutor(max_workers=MAX_WORKERS) as executor:
        # Usamos tqdm para una barra de progreso profesional
        futures = [executor.submit(process_api_sanitized, task) for task in tasks]

        for future in tqdm(as_completed(futures), total=total_tasks, desc="Enriqueciendo"):
            idx, taxid, nombre, raw_count = future.result()

            # Actualizar el DataFrame de forma segura
            df.at[idx, 'TAXID'] = taxid
            df.at[idx, 'NOMBRE_API'] = nombre

            total_json_items += raw_count
            if taxid and not any(x in str(taxid) for x in ["HTTP", "ERROR", "SIN_DATOS"]):
                enriquecidos_ok += 1

    # MÉTRICAS FINALES
    hit_rate = (enriquecidos_ok / total_tasks) * 100 if total_tasks > 0 else 0
    df.to_excel(FILE_OUTPUT, index=False)

    print("\n" + "═"*50)
    print("📊 REPORTE FINAL (MODO MULTITHREAD)")
    print("═"*50)
    print(f"✅ Registros totales:           {total_tasks}")
    print(f"📦 Total ítems JSON:            {total_json_items}")
    print(f"🎯 Registros con TAXID válido:  {enriquecidos_ok}")
    print(f"📈 Porcentaje de Efectividad:   {hit_rate:.2f}%")
    print(f"📂 Archivo generado:            {FILE_OUTPUT}")
    print("═"*50)
    logger.info("🏁 Fin del proceso.")

if __name__ == "__main__":
    main()