"""pay_quicker_sdk.

This file was automatically generated for PayQuicker by APIMATIC v3.0 (
 https://www.apimatic.io ).
"""

# ruff: noqa: E501
import os
from enum import Enum

from apimatic_core.http.configurations.http_client_configuration import (
    HttpClientConfiguration,
)
from apimatic_requests_client_adapter.requests_client import (
    RequestsClient,
)
from dotenv import load_dotenv

from payquickersdk.api_helper import APIHelper
from payquickersdk.http.proxy_settings import (
    ProxySettings,
)
from payquickersdk.logging.configuration.api_logging_configuration import (
    LoggingConfiguration,
)
from payquickersdk.models.sandbox_instance import (
    SandboxInstance,
)
from payquickersdk.models.uat_instance import (
    UatInstance,
)


class Environment(Enum):
    """An enum for SDK environments."""

    # Production
    PRODUCTION = 0
    # Sandbox is used for both sandbox testing and customer UAT.
    SANDBOX = 1
    # UAT is used for both sandbox testing and customer UAT.
    UAT = 2
    # Development is used for local development testing.
    DEVELOPMENT = 3

    @classmethod
    def from_value(cls, value, default=None):
        """Convert a value (string or int) to an Environment enum member.

        Args:
            value (Union[str, int]): The value to convert.
            default (Environment): The fallback enum member if conversion fails.

        Returns:
            Environment: Matching enum member or fallback if invalid.

        """
        if value is None:
            return default

        # Try to match directly by enum member
        if isinstance(value, cls):
            return value

        # Handle integer or string conversion
        for member in cls:
            if (str(member.value).lower() == str(value).lower()
                or member.name.lower() == str(value).lower()):
                return member

        # Fallback to provided default
        return default


class Server(Enum):
    """An enum for API servers."""

    API = 0

    @classmethod
    def from_value(cls, value, default=None):
        """Convert a value (string or int) to a Server enum member.

        Args:
            value (Union[str, int]): The value to convert.
            default (Server): The fallback enum member if conversion fails.

        Returns:
            Server: Matching enum member or fallback if invalid.

        """
        if value is None:
            return default

        # Try to match directly by enum member
        if isinstance(value, cls):
            return value

        # Handle integer or string conversion
        for member in cls:
            if (str(member.value).lower() == str(value).lower()
                or member.name.lower() == str(value).lower()):
                return member

        # Fallback to provided default
        return default


class Configuration(HttpClientConfiguration):
    """A class used for configuring the SDK by a user."""

    @property
    def environment(self):
        """Return current environment."""
        return self._environment

    @property
    def sandbox_instance(self):
        """Return current sandbox_instance."""
        return self._sandbox_instance

    @property
    def uat_instance(self):
        """Return current uat_instance."""
        return self._uat_instance

    @property
    def server_credentials(self):
        """Return current server_credentials."""
        return self._server_credentials

    @property
    def clientside_credentials(self):
        """Return current clientside_credentials."""
        return self._clientside_credentials

    @property
    def x_my_pay_quicker_version(self):
        """Return current x_my_pay_quicker_version."""
        return self._x_my_pay_quicker_version

    def __init__(self, http_client_instance=None,
                 override_http_client_configuration=False, http_call_back=None,
                 timeout=60, max_retries=0, backoff_factor=2, retry_statuses=None,
                 retry_methods=None, proxy_settings=None, logging_configuration=None,
                 environment=Environment.SANDBOX, sandbox_instance="sandbox",
                 uat_instance="uat1", server_credentials=None,
                 clientside_credentials=None, x_my_pay_quicker_version="2026.02.01"):
        """Initialize Configuration object."""
        if retry_methods is None:
            retry_methods = ["GET", "PUT"]

        if retry_statuses is None:
            retry_statuses = [408, 413, 429, 500, 502, 503, 504, 521,
                522, 524]

        super().__init__(
            http_client_instance=http_client_instance,
            override_http_client_configuration=override_http_client_configuration,
            http_call_back=http_call_back, timeout=timeout,
            max_retries=max_retries, backoff_factor=backoff_factor,
            retry_statuses=retry_statuses, retry_methods=retry_methods,
            proxy_settings=proxy_settings,
            logging_configuration=logging_configuration,
        )

        # Current API environment
        self._environment = environment

        # Sandbox Environments
        self._sandbox_instance = sandbox_instance

        # UAT Environments
        self._uat_instance = uat_instance

        # The object holding OAuth 2 Client Credentials Grant credentials
        self._server_credentials = server_credentials

        # The object holding OAuth 2 Bearer token credentials
        self._clientside_credentials = clientside_credentials

        # Date-based API Version specified in the header *required* on all calls.
        self._x_my_pay_quicker_version = x_my_pay_quicker_version

        # The Http Client to use for making requests.
        self.set_http_client(self.create_http_client())

    def clone_with(self, http_client_instance=None,
                   override_http_client_configuration=None, http_call_back=None,
                   timeout=None, max_retries=None, backoff_factor=None,
                   retry_statuses=None, retry_methods=None, proxy_settings=None,
                   logging_configuration=None, environment=None, sandbox_instance=None,
                   uat_instance=None, server_credentials=None,
                   clientside_credentials=None, x_my_pay_quicker_version=None):
        """Clone configuration with overrides."""
        http_client_instance = http_client_instance or self.http_client_instance
        override_http_client_configuration =\
            (override_http_client_configuration
            or self.override_http_client_configuration)
        http_call_back = http_call_back or self.http_callback
        timeout = timeout or self.timeout
        max_retries = max_retries or self.max_retries
        backoff_factor = backoff_factor or self.backoff_factor
        retry_statuses = retry_statuses or self.retry_statuses
        retry_methods = retry_methods or self.retry_methods
        proxy_settings = proxy_settings or self.proxy_settings
        logging_configuration = logging_configuration or self.logging_configuration
        environment = environment or self.environment
        sandbox_instance = sandbox_instance or self.sandbox_instance
        uat_instance = uat_instance or self.uat_instance
        server_credentials = server_credentials or self.server_credentials
        clientside_credentials = clientside_credentials or self.clientside_credentials
        x_my_pay_quicker_version =\
            (x_my_pay_quicker_version
            or self.x_my_pay_quicker_version)
        return Configuration(
            http_client_instance=http_client_instance,
            override_http_client_configuration=override_http_client_configuration,
            http_call_back=http_call_back, timeout=timeout, max_retries=max_retries,
            backoff_factor=backoff_factor, retry_statuses=retry_statuses,
            retry_methods=retry_methods, proxy_settings=proxy_settings,
            logging_configuration=logging_configuration, environment=environment,
            sandbox_instance=sandbox_instance, uat_instance=uat_instance,
            server_credentials=server_credentials,
            clientside_credentials=clientside_credentials,
            x_my_pay_quicker_version=x_my_pay_quicker_version,
        )

    def create_http_client(self):
        """Create the HTTP client instance."""
        return RequestsClient(
            timeout=self.timeout, max_retries=self.max_retries,
            backoff_factor=self.backoff_factor, retry_statuses=self.retry_statuses,
            retry_methods=self.retry_methods,
            http_client_instance=self.http_client_instance,
            override_http_client_configuration=self.override_http_client_configuration,
            response_factory=self.http_response_factory,
            proxies=self.proxy_settings.to_proxies() if self.proxy_settings else None,
        )

    # All the environments the SDK can run in
    environments = {
        Environment.PRODUCTION: {
            Server.API: "https://api.payquicker.io/api/v2",
        },
        Environment.SANDBOX: {
            Server.API: "https://api.{sandbox_instance}.payquicker.io/api/v2",
        },
        Environment.UAT: {
            Server.API: "https://api.{uat_instance}.payquicker.io/api/v2",
        },
        Environment.DEVELOPMENT: {
            Server.API: "https://api.local.payquicker.io/api/v2",
        },
    }

    def get_base_uri(self, server=Server.API):
        """Generate the appropriate base URI for the environment and the server.

        Args:
            server (Configuration.Server): The server enum for which the base
            URI is required.

        Returns:
            String: The base URI.

        """
        parameters = {
            "sandbox_instance": {"value": self.sandbox_instance, "encode": False},
            "uat_instance": {"value": self.uat_instance, "encode": False},
        }

        return APIHelper.append_url_with_template_parameters(
            self.environments[self.environment][server], parameters,
        )

    @classmethod
    def from_environment(cls, dotenv_path=None, **overrides):
        """Create Configuration object from .env and environment variables.

        Args:
            dotenv_path (str, optional): Path to the .env file to load.
             If None, the default .env file is used.
            **overrides: Optional values overriding setting from environment variables.

        Returns:
            Configuration: A configuration object populated with the resolved values.

        """
        # load .env automatically
        load_dotenv(dotenv_path or None, override=True)

        override_http_client_configuration = os.getenv(
            "OVERRIDE_HTTP_CLIENT_CONFIGURATION", "false").lower() == "true"
        timeout = int(os.getenv("TIMEOUT", "60"))
        max_retries = int(os.getenv("MAX_RETRIES", "0"))
        backoff_factor = float(os.getenv("BACKOFF_FACTOR", "2"))
        statuses = os.getenv("RETRY_STATUSES", None)
        retry_statuses = [int(v.strip()) for v in statuses.split(",")
                          if v.strip().isdigit()] if statuses else None
        methods = os.getenv("RETRY_METHODS", None)
        retry_methods = [v.strip() for v in methods.split(",") if v.strip()]\
            if methods else None
        environment = Environment.from_value(
            os.getenv("ENVIRONMENT"), Environment.SANDBOX)
        sandbox_instance = SandboxInstance.from_value(os.getenv("SANDBOX_INSTANCE"), "sandbox")
        uat_instance = UatInstance.from_value(os.getenv("UAT_INSTANCE"), "uat1")
        x_my_pay_quicker_version = os.getenv("X_MY_PAY_QUICKER_VERSION", "2026.02.01")

        from payquickersdk.http.auth.clientside import (
            ClientsideCredentials,
        )
        from payquickersdk.http.auth.server import ServerCredentials

        # Preparing default configuration
        default_config = cls(
            override_http_client_configuration=override_http_client_configuration,
            timeout=timeout,
            max_retries=max_retries,
            backoff_factor=backoff_factor,
            retry_statuses=retry_statuses,
            retry_methods=retry_methods,
            environment=environment,
            sandbox_instance=sandbox_instance,
            uat_instance=uat_instance,
            x_my_pay_quicker_version=x_my_pay_quicker_version,
            proxy_settings=ProxySettings.from_environment(),
            logging_configuration=LoggingConfiguration.from_environment(),
            server_credentials=ServerCredentials.from_environment(),
            clientside_credentials=ClientsideCredentials.from_environment(),
        )

        return default_config.clone_with(**overrides)
