from queue import Queue
import threading
import logging

logger = logging.getLogger(__name__)

# =========================================
# CONFIG
# =========================================

MAX_CONCURRENT_EXCEL = 10

# =========================================
# STATE
# =========================================

EXCEL_QUEUE = Queue()
EXCEL_LOCK = threading.Lock()

ACTIVE_JOBS = set()   # jobs em execução

# =========================================
# Helpers
# =========================================

def get_queue_position(job_id: str) -> int:
    """
    Retorna:
    0 = já está executando
    1..N = posição na fila
    -1 = não encontrado
    """
    with EXCEL_LOCK:

        if job_id in ACTIVE_JOBS:
            return 0

        items = list(EXCEL_QUEUE.queue)

        for i, item in enumerate(items):
            if item["job_id"] == job_id:
                return i + 1

        return -1


# =========================================
# WORKER
# =========================================

def _worker(worker_id: int):
    logger.info(f"🟢 Excel worker-{worker_id} started")

    while True:
        job = EXCEL_QUEUE.get()

        job_id = job["job_id"]

        try:
            with EXCEL_LOCK:
                ACTIVE_JOBS.add(job_id)

            logger.info(f"🚀 [worker-{worker_id}] Processing {job_id}")

            job["fn"](*job["args"], **job["kwargs"])

            logger.info(f"✅ [worker-{worker_id}] Finished {job_id}")

        except Exception as e:
            logger.exception(f"❌ [worker-{worker_id}] Failed {job_id}: {e}")

        finally:
            with EXCEL_LOCK:
                ACTIVE_JOBS.discard(job_id)

            EXCEL_QUEUE.task_done()


# =========================================
# START POOL
# =========================================

def start_excel_worker():
    """
    Inicia pool com N workers simultâneos
    """
    for i in range(MAX_CONCURRENT_EXCEL):
        threading.Thread(
            target=_worker,
            args=(i + 1,),
            daemon=True
        ).start()

    logger.info(f"🔥 Excel queue started with {MAX_CONCURRENT_EXCEL} workers")


# =========================================
# ENQUEUE
# =========================================

def enqueue_excel_job(job_id, fn, *args, **kwargs):
    job = {
        "job_id": job_id,
        "fn": fn,
        "args": args,
        "kwargs": kwargs
    }

    with EXCEL_LOCK:
        EXCEL_QUEUE.put(job)
        position = EXCEL_QUEUE.qsize()

    return position