import uuid

from app.core.celery_app import celery_app
from app.db.session import SessionLocal
from app.models.stubs import EvaluationResult, EvaluationStatus
from app.services.evaluation import run_evaluation
from app.ws.events import publish_job_event


@celery_app.task(name="evaluation.run")
def run_evaluation_task(
    evaluation_id: str,
    dataset_id: str,
    project_id: str,
    base_model: str,
    judge_model: str,
    use_rag: bool,
    sample_size: int | None,
) -> None:
    db = SessionLocal()
    try:
        publish_job_event(evaluation_id, {"status": "running"})
        run_evaluation(
            db,
            uuid.UUID(evaluation_id),
            uuid.UUID(dataset_id),
            uuid.UUID(project_id),
            base_model,
            judge_model,
            use_rag,
            sample_size,
        )
        evaluation = db.get(EvaluationResult, uuid.UUID(evaluation_id))
        publish_job_event(evaluation_id, {"status": evaluation.status.value, "metrics": evaluation.metrics})
    except Exception as exc:  # noqa: BLE001
        db.rollback()
        evaluation = db.get(EvaluationResult, uuid.UUID(evaluation_id))
        if evaluation:
            evaluation.status = EvaluationStatus.failed
            evaluation.metrics = {"error": str(exc)}
            db.commit()
        publish_job_event(evaluation_id, {"status": "failed", "error": str(exc)})
        raise
    finally:
        db.close()
