"""Type Models for Questra Automation based on automation.sdl."""

from __future__ import annotations

from dataclasses import dataclass
from datetime import datetime
from enum import Enum
from uuid import UUID

# ===== Enums =====


class ApplyPolicy(str, Enum):
    """Defines when a policy shall be executed."""

    BEFORE_RESOLVER = "BEFORE_RESOLVER"
    AFTER_RESOLVER = "AFTER_RESOLVER"
    VALIDATION = "VALIDATION"


class AutomationBuildStatus(str, Enum):
    """Build status of an automation."""

    PENDING = "PENDING"
    RUNNING = "RUNNING"
    FAILED = "FAILED"
    SUCCEEDED = "SUCCEEDED"


class AutomationExecutionDomainStatus(str, Enum):
    """Domain status of an automation execution."""

    SUCCEEDED = "SUCCEEDED"
    FAILED = "FAILED"


class AutomationExecutionStatus(str, Enum):
    """Status of an automation execution."""

    PENDING = "PENDING"
    RUNNING = "RUNNING"
    SUCCEEDED = "SUCCEEDED"
    FAILED = "FAILED"


class AutomationInitiatorType(str, Enum):
    """Type of initiator of an automation."""

    MANUAL = "MANUAL"
    SCRIPT = "SCRIPT"
    SCHEDULE = "SCHEDULE"


class ExecutionInitiator(str, Enum):
    """Initiator type for automation execution."""

    MANUAL = "MANUAL"
    SCRIPT = "SCRIPT"
    SCHEDULE = "SCHEDULE"


class RepositoryAuthenticationMethod(str, Enum):
    """Authentication method for repository access."""

    USERNAME_PASSWORD = "USERNAME_PASSWORD"
    SSH_KEY = "SSH_KEY"


class SortEnumType(str, Enum):
    """Sort order."""

    ASC = "ASC"
    DESC = "DESC"


# ===== Types =====


@dataclass
class AutomationArgumentDefinition:
    """Definition of an automation argument."""

    name: str
    description: str
    mandatory: bool


@dataclass
class AutomationArgumentInstance:
    """Instance of an automation argument."""

    name: str
    value: str


@dataclass
class AutomationBuildError:
    """Build error of an automation."""

    code: str
    message_template: str
    data: list[KeyValuePair]


@dataclass
class KeyValuePair:
    """Key-value pair."""

    key: str
    value: str


@dataclass
class PageInfo:
    """Pagination information."""

    has_next_page: bool
    has_previous_page: bool
    start_cursor: str | None
    end_cursor: str | None


@dataclass
class ServiceInfo:
    """Service information."""

    name: str
    version: str
    informational_version: str


@dataclass
class WorkspaceView:
    """View of a workspace."""

    name: str
    repository_name: str
    build_status: AutomationBuildStatus
    build_errors: list[AutomationBuildError]
    build_branch: str | None
    build_commit: str | None
    build_started_at: datetime | None
    build_finished_at: datetime | None
    build_duration: str | None  # TimeSpan as ISO-8601 string
    active_branch: str | None
    active_commit: str | None
    created_at: datetime
    changed_at: datetime
    repository: RepositoryView | None = None
    automations: list[AutomationView] | None = None


@dataclass
class AutomationView:
    """View of an automation."""

    workspace_name: str
    path: str
    description: str
    environment: str
    allow_parallel_execution: bool
    argument_definitions: list[AutomationArgumentDefinition]
    workspace: WorkspaceView | None = None
    schedules: list[ScheduleView] | None = None


@dataclass
class AutomationExecutionView:
    """View of an automation execution."""

    id: UUID
    branch: str
    commit: str
    workspace_name: str
    repository_name: str
    repository_url: str
    automation_path: str
    environment: str
    initiator_type: AutomationInitiatorType
    initiator_reference: str | None
    argument_instances: list[AutomationArgumentInstance]
    status: AutomationExecutionStatus
    output: str | None
    domain_status: AutomationExecutionDomainStatus | None
    domain_status_message: str | None
    created_at: datetime
    started_at: datetime | None
    finished_at: datetime | None
    duration: str | None  # TimeSpan as ISO-8601 string
    workspace: WorkspaceView | None = None


@dataclass
class RepositoryView:
    """View of a repository."""

    name: str
    url: str
    created_at: datetime
    changed_at: datetime
    authentication_method: RepositoryAuthenticationMethod
    username: str | None
    ssh_public_key: str | None
    workspaces: list[WorkspaceView] | None = None


@dataclass
class ScheduleView:
    """View of a schedule."""

    automation_path: str
    name: str
    description: str
    cron: str
    timezone: str
    active: bool
    argument_instances: list[AutomationArgumentInstance]
    version: int
    workspace: WorkspaceView | None = None


@dataclass
class ScheduledExecutionView:
    """View of a scheduled execution."""

    name: str
    description: str
    cron: str
    timezone: str
    automation_path: str
    fire_time: datetime
    argument_instances: list[AutomationArgumentInstance]
    workspace: WorkspaceView | None = None


@dataclass
class ErrorCodeView:
    """View of an error code."""

    code: str
    message_template: str
    parameters: list[str]


# ===== Connection Types =====


@dataclass
class AutomationsEdge:
    """Edge for automations connection."""

    cursor: str
    node: AutomationView


@dataclass
class AutomationsConnection:
    """Connection for automations."""

    page_info: PageInfo
    edges: list[AutomationsEdge]
    nodes: list[AutomationView]
    total_count: int


@dataclass
class ExecutionsEdge:
    """Edge for executions connection."""

    cursor: str
    node: AutomationExecutionView


@dataclass
class ExecutionsConnection:
    """Connection for executions."""

    page_info: PageInfo
    edges: list[ExecutionsEdge]
    nodes: list[AutomationExecutionView]
    total_count: int


@dataclass
class RepositoriesEdge:
    """Edge for repositories connection."""

    cursor: str
    node: RepositoryView


@dataclass
class RepositoriesConnection:
    """Connection for repositories."""

    page_info: PageInfo
    edges: list[RepositoriesEdge]
    nodes: list[RepositoryView]
    total_count: int


@dataclass
class SchedulesEdge:
    """Edge for schedules connection."""

    cursor: str
    node: ScheduleView


@dataclass
class SchedulesConnection:
    """Connection for schedules."""

    page_info: PageInfo
    edges: list[SchedulesEdge]
    nodes: list[ScheduleView]
    total_count: int


@dataclass
class ScheduledExecutionsEdge:
    """Edge for scheduled executions connection."""

    cursor: str
    node: ScheduledExecutionView


@dataclass
class ScheduledExecutionsConnection:
    """Connection for scheduled executions."""

    page_info: PageInfo
    edges: list[ScheduledExecutionsEdge]
    nodes: list[ScheduledExecutionView]


@dataclass
class ErrorCodesEdge:
    """Edge for error codes connection."""

    cursor: str
    node: ErrorCodeView


@dataclass
class ErrorCodesConnection:
    """Connection for error codes."""

    page_info: PageInfo
    edges: list[ErrorCodesEdge]
    nodes: list[ErrorCodeView]
    total_count: int


@dataclass
class WorkspacesEdge:
    """Edge for workspaces connection."""

    cursor: str
    node: WorkspaceView


@dataclass
class WorkspacesConnection:
    """Connection for workspaces."""

    page_info: PageInfo
    edges: list[WorkspacesEdge]
    nodes: list[WorkspaceView]
    total_count: int


# ===== Payload Types =====


@dataclass
class ExecutePayload:
    """Result of an automation execution."""

    id: UUID


@dataclass
class CreateRepositoryPayload:
    """Result of repository creation."""

    name: str


@dataclass
class UpdateRepositoryPayload:
    """Result of repository update."""

    name: str


@dataclass
class DeleteRepositoryPayload:
    """Result of repository deletion."""

    name: str


@dataclass
class RenewRepositorySshKeyPayload:
    """Result of SSH key renewal."""

    name: str


@dataclass
class CreateSchedulePayload:
    """Result of schedule creation."""

    name: str
    workspace_name: str
    automation_path: str


@dataclass
class UpdateSchedulePayload:
    """Result of schedule update."""

    name: str
    workspace_name: str
    automation_path: str


@dataclass
class DeleteSchedulePayload:
    """Result of schedule deletion."""

    name: str
    workspace_name: str
    automation_path: str


@dataclass
class CreateWorkspacePayload:
    """Result of workspace creation."""

    name: str


@dataclass
class UpdateWorkspacePayload:
    """Result of workspace update."""

    name: str


@dataclass
class DeleteWorkspacePayload:
    """Result of workspace deletion."""

    name: str


@dataclass
class SynchronizeWorkspacePayload:
    """Result of workspace synchronization."""

    name: str
