"""Pipeline-related operations."""

from __future__ import annotations

from dataclasses import dataclass

from zenhub_client.exceptions import ZenhubError
from zenhub_client.graphql import GraphQLClient
from zenhub_client.models import Pipeline
from zenhub_client.queries import GET_PIPELINES, MOVE_ISSUE
from zenhub_client.utils import get_in, normalise_name


@dataclass(slots=True)
class PipelineService:
    """Operations for pipelines and moving issues between them."""

    _graphql: GraphQLClient

    def list_pipelines(self, workspace_id: str, *, first: int = 50) -> list[Pipeline]:
        variables = {
            "workspaceId": str(workspace_id),
            "first": int(first),
        }
        data = self._graphql.execute(GET_PIPELINES.text, variables)
        nodes = get_in(data, ["workspace", "pipelinesConnection", "nodes"])
        if not isinstance(nodes, list):
            raise ZenhubError(f"Unexpected pipelines nodes shape: {nodes!r}")
        return [Pipeline.from_node(n) for n in nodes if isinstance(n, dict)]

    def find_pipeline_id(self, workspace_id: str, pipeline_name: str) -> str:
        target = normalise_name(pipeline_name)
        pipelines = self.list_pipelines(workspace_id)
        for pipeline in pipelines:
            if normalise_name(pipeline.name) == target:
                return pipeline.id
        available = [p.name for p in pipelines]
        raise ZenhubError(f"Pipeline '{pipeline_name}' not found. Available: {available}")

    def move_issue(self, *, workspace_id: str, issue_id: str, pipeline_id: str, position: int = 0) -> None:
        variables = {
            "workspaceId": str(workspace_id),
            "moveIssueInput": {
                "pipelineId": str(pipeline_id),
                "issueId": str(issue_id),
                "position": int(position),
            },
        }
        self._graphql.execute(MOVE_ISSUE.text, variables)
