"""Models for Portainer Stacks API."""

from __future__ import annotations

from dataclasses import dataclass, field
from enum import IntEnum

from mashumaro import field_options
from mashumaro.mixins.orjson import DataClassORJSONMixin


class StackStatus(IntEnum):
    """Stack status values."""

    ACTIVE = 1
    INACTIVE = 2


class StackType(IntEnum):
    """Stack type values."""

    SWARM = 1
    COMPOSE = 2
    KUBERNETES = 3


class GitCredentialAuthType(IntEnum):
    """Git credential authentication types."""

    BASIC = 0
    TOKEN = 1


@dataclass
class StackEnvVar(DataClassORJSONMixin):
    """Environment variable for a stack (name/value pair)."""

    name: str | None = None
    value: str | None = None


@dataclass
class StackOption(DataClassORJSONMixin):
    """Stack deployment options."""

    prune: bool | None = None


@dataclass
class AutoUpdateSettings(DataClassORJSONMixin):
    """GitOps auto-update settings for a stack."""

    force_pull_image: bool | None = field(default=None, metadata=field_options(alias="forcePullImage"))
    force_update: bool | None = field(default=None, metadata=field_options(alias="forceUpdate"))
    interval: str | None = None
    job_id: str | None = field(default=None, metadata=field_options(alias="jobID"))
    webhook: str | None = None


@dataclass
class GitAuthentication(DataClassORJSONMixin):
    """Git authentication configuration."""

    authorization_type: GitCredentialAuthType | None = field(default=None, metadata=field_options(alias="authorizationType"))
    git_credential_id: int | None = field(default=None, metadata=field_options(alias="gitCredentialID"))
    password: str | None = None
    username: str | None = None


@dataclass
class GitRepoConfig(DataClassORJSONMixin):
    """Git repository configuration for a stack."""

    authentication: GitAuthentication | None = None
    config_file_path: str | None = field(default=None, metadata=field_options(alias="configFilePath"))
    config_hash: str | None = field(default=None, metadata=field_options(alias="configHash"))
    reference_name: str | None = field(default=None, metadata=field_options(alias="referenceName"))
    tls_skip_verify: bool | None = field(default=None, metadata=field_options(alias="tlsskipVerify"))
    url: str | None = None


@dataclass
class UserResourceAccess(DataClassORJSONMixin):
    """User access level for a resource."""

    access_level: int | None = field(default=None, metadata=field_options(alias="AccessLevel"))
    user_id: int | None = field(default=None, metadata=field_options(alias="UserId"))


@dataclass
class TeamResourceAccess(DataClassORJSONMixin):
    """Team access level for a resource."""

    access_level: int | None = field(default=None, metadata=field_options(alias="AccessLevel"))
    team_id: int | None = field(default=None, metadata=field_options(alias="TeamId"))


@dataclass
class ResourceControl(DataClassORJSONMixin):
    """Resource access control configuration."""

    id: int | None = field(default=None, metadata=field_options(alias="Id"))
    resource_id: str | None = field(default=None, metadata=field_options(alias="ResourceId"))
    sub_resource_ids: list[str] | None = field(default=None, metadata=field_options(alias="SubResourceIds"))
    type: int | None = field(default=None, metadata=field_options(alias="Type"))
    user_accesses: list[UserResourceAccess] | None = field(default=None, metadata=field_options(alias="UserAccesses"))
    team_accesses: list[TeamResourceAccess] | None = field(default=None, metadata=field_options(alias="TeamAccesses"))
    public: bool | None = field(default=None, metadata=field_options(alias="Public"))
    administrators_only: bool | None = field(default=None, metadata=field_options(alias="AdministratorsOnly"))
    system: bool | None = field(default=None, metadata=field_options(alias="System"))
    owner_id: int | None = field(default=None, metadata=field_options(alias="OwnerId"))


@dataclass
class Stack(DataClassORJSONMixin):
    """Represents a Portainer stack."""

    id: int = field(metadata=field_options(alias="Id"))
    name: str = field(metadata=field_options(alias="Name"))
    type: int = field(metadata=field_options(alias="Type"))
    endpoint_id: int = field(metadata=field_options(alias="EndpointId"))
    status: int = field(metadata=field_options(alias="Status"))

    swarm_id: str | None = field(default=None, metadata=field_options(alias="SwarmId"))
    entry_point: str | None = field(default=None, metadata=field_options(alias="EntryPoint"))
    additional_files: list[str] | None = field(default=None, metadata=field_options(alias="AdditionalFiles"))
    env: list[StackEnvVar] | None = field(default=None, metadata=field_options(alias="Env"))
    option: StackOption | None = field(default=None, metadata=field_options(alias="Option"))
    auto_update: AutoUpdateSettings | None = field(default=None, metadata=field_options(alias="AutoUpdate"))
    git_config: GitRepoConfig | None = field(default=None, metadata=field_options(alias="GitConfig"))
    resource_control: ResourceControl | None = field(default=None, metadata=field_options(alias="ResourceControl"))
    project_path: str | None = field(default=None, metadata=field_options(alias="ProjectPath"))
    namespace: str | None = field(default=None, metadata=field_options(alias="Namespace"))
    created_by: str | None = field(default=None, metadata=field_options(alias="CreatedBy"))
    creation_date: int | None = field(default=None, metadata=field_options(alias="CreationDate"))
    updated_by: str | None = field(default=None, metadata=field_options(alias="UpdatedBy"))
    update_date: int | None = field(default=None, metadata=field_options(alias="UpdateDate"))
    from_app_template: bool | None = field(default=None, metadata=field_options(alias="FromAppTemplate"))

    @property
    def is_active(self) -> bool:
        """Check if the stack is active."""
        return self.status == StackStatus.ACTIVE

    @property
    def stack_type(self) -> StackType:
        """Get the stack type as an enum."""
        return StackType(self.type)
