from typing import Any

from celery import Task
from sqlalchemy.orm import Session

from core.database import rls_company_var, rls_tenant_var

from .service import TaskTrackerService


def track_and_dispatch(
    *,
    db: Session,
    task: Task,
    tenant_id: int,
    task_name: str,
    task_group: str,
    company_id: int | None = None,
    requested_by_user: str | None = None,
    task_origin: str | None = None,
    args: list[Any] | None = None,
    kwargs: dict[str, Any] | None = None,
    task_id: str | None = None,
    meta_payload: dict[str, Any] | None = None,
):
    # Propaga contexto RLS vía Celery headers (leídos en task_prerun) y
    # ContextVars (para modo eager, donde before_task_publish no dispara).
    headers = {"rls_tenant_id": str(int(tenant_id))}
    if company_id is not None:
        headers["rls_company_id"] = str(int(company_id))

    prev_tenant = rls_tenant_var.get()
    prev_company = rls_company_var.get()
    rls_tenant_var.set(int(tenant_id))
    rls_company_var.set(int(company_id) if company_id is not None else None)
    try:
        celery_task = task.apply_async(
            args=args or [],
            kwargs=kwargs or {},
            task_id=task_id,
            headers=headers,
        )
    finally:
        rls_tenant_var.set(prev_tenant)
        rls_company_var.set(prev_company)

    tracker = TaskTrackerService(db)
    tracker.register_dispatch(
        task_id=celery_task.id,
        tenant_id=tenant_id,
        company_id=company_id,
        requested_by_user=requested_by_user,
        task_name=task_name,
        task_group=task_group,
        task_origin=task_origin,
        meta_payload=meta_payload,
    )
    return celery_task
