from pydantic import BaseModel, ConfigDict, Field

from apolo_app_types import AppInputs
from apolo_app_types.protocols.common import (
    AppOutputs,
    AutoscalingHPA,
    Container,
    ContainerImage,
    DeploymentName,
    IngressHttp,
    Preset,
    RestAPI,
    SchemaExtraMetadata,
    StorageMounts,
)
from apolo_app_types.protocols.common.k8s import Port


class NetworkingConfig(BaseModel):
    model_config = ConfigDict(
        protected_namespaces=(),
        json_schema_extra=SchemaExtraMetadata(
            title="Network Configuration",
            description="Configure custom networking "
            "options for your deployment, including ports and ingress settings.",
            is_advanced_field=True,
        ).as_json_schema_extra(),
    )

    service_enabled: bool = Field(
        default=True,
        json_schema_extra=SchemaExtraMetadata(
            title="Service Enabled",
            description="Enable or disable the internal "
            "network service for the deployment.",
        ).as_json_schema_extra(),
    )

    ingress_http: IngressHttp | None = Field(
        default_factory=lambda: IngressHttp(),
        json_schema_extra=SchemaExtraMetadata(
            title="HTTP Ingress",
            description="Define HTTP ingress configuration"
            " for exposing services over the web.",
        ).as_json_schema_extra(),
    )

    ports: list[Port] = Field(
        default_factory=lambda: [Port()],
        json_schema_extra=SchemaExtraMetadata(
            title="Exposed Ports",
            description="Specify which ports should be exposed by the application.",
        ).as_json_schema_extra(),
    )


class CustomDeploymentInputs(AppInputs):
    model_config = ConfigDict(
        protected_namespaces=(),
        json_schema_extra=SchemaExtraMetadata(
            title="Custom Deployment",
            description="Configuration for Custom Deployment.",
        ).as_json_schema_extra(),
    )
    preset: Preset
    name_override: DeploymentName | None = Field(
        default=None,
        json_schema_extra=SchemaExtraMetadata(
            title="Deployment Name Override",
            description="Override the default deployment name.",
        ).as_json_schema_extra(),
    )
    image: ContainerImage
    autoscaling: AutoscalingHPA | None = Field(
        default=None,
        json_schema_extra=SchemaExtraMetadata(
            title="Autoscaling",
            description="Enable Autoscaling and configure it.",
            is_advanced_field=True,
        ).as_json_schema_extra(),
    )
    container: Container | None = Field(
        None,
        json_schema_extra=SchemaExtraMetadata(
            title="Container",
            description="Enable Container configuration.",
            is_advanced_field=True,
        ).as_json_schema_extra(),
    )
    storage_mounts: StorageMounts | None = Field(
        default=None,
        json_schema_extra=SchemaExtraMetadata(
            title="Storage Mounts",
            description="Enable Storage mounts configuration.",
            is_advanced_field=True,
        ).as_json_schema_extra(),
    )
    networking: NetworkingConfig = Field(default_factory=lambda: NetworkingConfig())


class CustomDeploymentOutputs(AppOutputs):
    internal_web_app_url: RestAPI | None = None
    external_web_app_url: RestAPI | None = None
