import uuid

from app.core.celery_app import celery_app
from app.db.session import SessionLocal
from app.services import ollama_client
from app.services.model_registry import build_modelfile, register_model_version
from app.ws.events import publish_job_event


@celery_app.task(name="models.pull")
def pull_model_task(tag: str) -> None:
    try:
        for progress in ollama_client.pull_model_stream(tag):
            event = {"status": progress.get("status", "pulling")}
            if "completed" in progress and "total" in progress and progress["total"]:
                event["percent"] = round(progress["completed"] / progress["total"] * 100, 1)
            publish_job_event(f"pull:{tag}", event)
        publish_job_event(f"pull:{tag}", {"status": "success"})
    except Exception as exc:  # noqa: BLE001
        publish_job_event(f"pull:{tag}", {"status": "failed", "error": str(exc)})
        raise


@celery_app.task(name="models.create")
def create_model_task(
    job_id: str,
    project_id: str,
    name: str,
    base_model: str,
    tag: str,
    system_prompt: str | None,
    parameters: dict | None,
    created_by: str | None,
) -> None:
    db = SessionLocal()
    try:
        publish_job_event(job_id, {"status": "creating"})
        modelfile = build_modelfile(base_model, system_prompt, parameters)
        ollama_client.create_model(tag, modelfile)
        register_model_version(
            db,
            uuid.UUID(project_id),
            name,
            base_model,
            tag,
            uuid.UUID(created_by) if created_by else None,
            notes=f"Created via Modelfile from {base_model}",
        )
        publish_job_event(job_id, {"status": "success", "tag": tag})
    except Exception as exc:  # noqa: BLE001
        db.rollback()
        publish_job_event(job_id, {"status": "failed", "error": str(exc)})
        raise
    finally:
        db.close()
