"""Encolar `insert_valid_rows` con registro en core.task_runs y validación de acceso."""
from __future__ import annotations

import json
from typing import Any
from uuid import uuid4

from celery import Task
from fastapi import HTTPException
from sqlalchemy.orm import Session

from api.v1.modules.core.tasks_tracking import track_and_dispatch
from core.security import validate_access_to_resource


def dispatch_tracked_layouts_csv_commit(
    *,
    db: Session,
    current_user: dict[str, Any],
    redis_client: Any,
    layout_job_id: str,
    meta_redis_key: str,
    celery_task: Task,
    task_name: str,
    task_origin: str,
    args: list[Any],
    required_permissions: list[str] | None = None,
) -> str:
    """
    Lee tenant_id / company_id del meta en Redis, valida acceso y despacha la tarea Celery
    con un task_id nuevo (commit) para que el polling use commit_job_id.

    Si ``required_permissions`` es None, se normaliza a [] para validar acceso a compañía
    (``validate_access_to_resource(..., None)`` omitiría esa validación por el atajo tipo /me).
    """
    raw = redis_client.get(meta_redis_key)
    if not raw:
        raise HTTPException(status_code=404, detail="Job no encontrado o expiró")
    meta = json.loads(raw.decode("utf-8"))
    tenant_id = int(meta["tenant_id"])
    company_id = meta.get("company_id")
    if company_id is None:
        raise HTTPException(
            status_code=403,
            detail="Job sin compañía asociada o meta incompleto",
        )
    effective_permissions: list[str] = (
        [] if required_permissions is None else required_permissions
    )
    try:
        validate_access_to_resource(
            db, int(company_id), current_user, effective_permissions
        )
    except HTTPException:
        raise
    except Exception:
        raise HTTPException(status_code=403, detail="Sin acceso a este job") from None

    commit_id = str(uuid4())
    track_and_dispatch(
        db=db,
        task=celery_task,
        tenant_id=tenant_id,
        company_id=int(company_id),
        requested_by_user=current_user.get("preferred_username")
        or current_user.get("email")
        or current_user.get("sub"),
        task_name=task_name,
        task_group="layouts_csv",
        task_origin=task_origin,
        args=args,
        task_id=commit_id,
        meta_payload={"layout_import_job_id": layout_job_id},
    )
    return commit_id
