from pathlib import Path
from uuid import UUID

import srsly
from radicli import Arg
from wasabi import msg

from prodigy_teams_broker_sdk import models as broker_models

from ..cli import cli
from ..errors import CLIError
from ..messages import Messages
from ._state import get_auth_state


@cli.subcommand(
    "jobs",
    "run",
    spec_path=Arg(help="Path to a YAML job spec file"),
)
def run(spec_path: str) -> None:
    """
    Run a job directly on the broker from a YAML spec file, bypassing PAM.
    """
    path = Path(spec_path)
    if not path.exists():
        raise CLIError(f"Spec file not found: {spec_path}")
    data = srsly.read_yaml(path)
    if not isinstance(data, dict):
        raise CLIError(f"Expected a YAML mapping in {spec_path}")
    plan_data = data.get("plan")
    if plan_data is None:
        raise CLIError("Spec file must contain a 'plan' key")
    plan = broker_models.RecipePlan(
        recipe_name=plan_data["recipe_name"],
        command=plan_data.get("command"),
        args=plan_data.get("args"),
        positional_fields=plan_data.get("positional_fields"),
        cli_names=plan_data.get("cli_names"),
        package_name=plan_data.get("package_name", ""),
        objects=plan_data.get("objects", {}),
    )
    resources = None
    resources_data = data.get("resources")
    if resources_data is not None:
        resources = broker_models.Resources(
            cpu_cores=resources_data.get("cpu_cores"),
            memory_mb=resources_data.get("memory_mb"),
            memory_max_mb=resources_data.get("memory_max_mb"),
        )
    container = data.get("container")
    if not container:
        raise CLIError("Spec file must contain a 'container' key")
    job_spec = broker_models.JobSpec(
        job_id=UUID(data["job_id"]),
        job_type=broker_models.JobType(data["job_type"]),
        name=data["name"],
        plan=plan,
        container=container,
        resources=resources,
        node_selector=data.get("node_selector"),
    )
    auth = get_auth_state()
    if auth.broker_host is None:
        raise CLIError(Messages.E035)
    msg.info(f"Submitting job {job_spec.name} ({job_spec.job_id}) to broker")
    response = auth.broker_client.jobs.start_job(job_spec)
    if response.cluster_change is not None:
        msg.good(f"Job submitted successfully: {response.cluster_change.job_id}")
    elif response.cluster_error is not None:
        raise CLIError(
            f"Cluster error starting job {job_spec.name}",
            response.cluster_error,
        )
    elif response.validation_error is not None:
        raise CLIError(
            f"Validation error starting job {job_spec.name}",
            response.validation_error.message,
        )
    else:
        msg.info(f"Job {job_spec.name} submitted (status: {response.status})")
