from pathlib import Path
from uuid import UUID

import srsly
from radicli import Arg
from wasabi import msg

from ..cli import cli
from ..errors import CLIError
from ..messages import Messages
from ..prodigy_teams_broker_sdk import models as broker_models
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", ""),
        environment=plan_data.get("environment"),
        objects=plan_data.get("objects", {}),
    )
    resources = None
    resources_data = data.get("resources")
    if resources_data is not None:
        resources = broker_models.K8sResources(
            cpu_cores=resources_data.get("cpu_cores"),
            memory_mb=resources_data.get("memory_mb"),
            memory_max_mb=resources_data.get("memory_max_mb"),
        )
    job_spec = broker_models.JobSpec(
        job_id=UUID(data["job_id"]),
        job_type=broker_models.JobType(data["job_type"]),
        name=data["name"],
        plan=plan,
        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})")
