"""Versioning client for the ZenOTC SDK."""

from typing import Optional

from ..models.versioning import (
    AlgoTypeSummary,
    AlgoVersionSummary,
    CompatibilityCheck,
    CurrentSDKVersion,
    DeprecationWarning,
    Environment,
    EnvironmentInfo,
    MaintenanceStatus,
    SDKPlatform,
    SDKSupportStatus,
    SDKVersionSummary,
    VersionResolution,
)


class VersioningClient:
    """Client for versioning and deprecation management APIs."""

    def __init__(self, http_client):
        """Initialize the versioning client.

        Args:
            http_client: The HTTP client for making API requests.
        """
        self._http = http_client

    # ==================== Algo Versions ====================

    async def resolve_algo_version(
        self,
        algo_type: str,
        version: Optional[str] = None,
        environment: Optional[Environment] = None,
    ) -> VersionResolution:
        """Resolve the version to use for an algo execution.

        Args:
            algo_type: The type of algo (e.g., 'twap', 'vwap').
            version: Optional specific version to use.
            environment: Optional environment override.

        Returns:
            VersionResolution with the resolved version details.
        """
        params = {}
        if version:
            params["version"] = version
        if environment:
            params["environment"] = environment.value

        response = await self._http.get(
            f"/sdk/versioning/algo/{algo_type}/version",
            params=params if params else None,
        )
        return VersionResolution.model_validate(response)

    async def get_available_algo_versions(
        self,
        algo_type: str,
        environment: Optional[Environment] = None,
    ) -> list[AlgoVersionSummary]:
        """Get available versions for an algo type.

        Args:
            algo_type: The type of algo.
            environment: Optional environment filter.

        Returns:
            List of available algo versions.
        """
        params = {}
        if environment:
            params["environment"] = environment.value

        response = await self._http.get(
            f"/sdk/versioning/algo/{algo_type}/versions",
            params=params if params else None,
        )
        return [AlgoVersionSummary.model_validate(v) for v in response]

    async def get_available_algos(self) -> list[AlgoTypeSummary]:
        """Get all available algo types with their current versions.

        Returns:
            List of algo types with current version info.
        """
        response = await self._http.get("/sdk/versioning/algos")
        return [AlgoTypeSummary.model_validate(a) for a in response]

    # ==================== SDK Versions ====================

    async def get_current_sdk_version(
        self,
        platform: SDKPlatform = SDKPlatform.PYTHON,
    ) -> CurrentSDKVersion:
        """Get the current (latest) SDK version for a platform.

        Args:
            platform: The SDK platform.

        Returns:
            Current SDK version details.
        """
        response = await self._http.get(f"/sdk/versioning/sdk/{platform.value}/current")
        return CurrentSDKVersion.model_validate(response)

    async def get_sdk_versions(
        self,
        platform: SDKPlatform = SDKPlatform.PYTHON,
    ) -> list[SDKVersionSummary]:
        """Get all available SDK versions for a platform.

        Args:
            platform: The SDK platform.

        Returns:
            List of SDK versions.
        """
        response = await self._http.get(f"/sdk/versioning/sdk/{platform.value}/versions")
        return [SDKVersionSummary.model_validate(v) for v in response]

    async def check_sdk_version(
        self,
        platform: str,
        version: str,
    ) -> SDKSupportStatus:
        """Check if an SDK version is supported.

        Args:
            platform: The SDK platform (e.g., 'python').
            version: The version to check.

        Returns:
            SDK support status.
        """
        response = await self._http.get(
            "/sdk/versioning/sdk/check",
            params={"platform": platform, "version": version},
        )
        return SDKSupportStatus.model_validate(response)

    # ==================== Compatibility ====================

    async def check_compatibility(
        self,
        algo_type: str,
        algo_version: Optional[str] = None,
    ) -> CompatibilityCheck:
        """Check compatibility for algo execution.

        This checks SDK version compatibility with the requested algo version.
        SDK version info is sent via headers.

        Args:
            algo_type: The type of algo.
            algo_version: Optional specific algo version to check.

        Returns:
            Compatibility check result with any issues or warnings.
        """
        params = {"algoType": algo_type}
        if algo_version:
            params["algoVersion"] = algo_version

        response = await self._http.get(
            "/sdk/versioning/compatibility",
            params=params,
        )
        return CompatibilityCheck.model_validate(response)

    # ==================== Deprecations ====================

    async def get_deprecations(self) -> list[DeprecationWarning]:
        """Get all active deprecation warnings.

        Returns:
            List of active deprecation warnings.
        """
        response = await self._http.get("/sdk/versioning/deprecations")
        return [DeprecationWarning.model_validate(d) for d in response]

    async def get_algo_deprecations(
        self,
        algo_type: str,
        version: Optional[str] = None,
    ) -> list[DeprecationWarning]:
        """Get deprecations for a specific algo.

        Args:
            algo_type: The type of algo.
            version: Optional version to filter by.

        Returns:
            List of deprecation warnings for the algo.
        """
        params = {}
        if version:
            params["version"] = version

        response = await self._http.get(
            f"/sdk/versioning/deprecations/algo/{algo_type}",
            params=params if params else None,
        )
        return [DeprecationWarning.model_validate(d) for d in response]

    # ==================== Environment ====================

    async def get_environment_info(self) -> EnvironmentInfo:
        """Get current environment information.

        Returns:
            Environment configuration and status.
        """
        response = await self._http.get("/sdk/versioning/environment")
        return EnvironmentInfo.model_validate(response)

    async def check_maintenance(self) -> MaintenanceStatus:
        """Check if the environment is in maintenance mode.

        Returns:
            Maintenance status with details if in maintenance.
        """
        response = await self._http.get("/sdk/versioning/environment/maintenance")
        return MaintenanceStatus.model_validate(response)

    # ==================== Convenience Methods ====================

    async def is_sdk_supported(self, sdk_version: str) -> bool:
        """Quick check if the current SDK version is supported.

        Args:
            sdk_version: The SDK version to check.

        Returns:
            True if the SDK version is supported.
        """
        status = await self.check_sdk_version("python", sdk_version)
        return status.supported

    async def get_upgrade_recommendation(self, sdk_version: str) -> Optional[str]:
        """Get upgrade recommendation if SDK version is deprecated.

        Args:
            sdk_version: The SDK version to check.

        Returns:
            Upgrade recommendation if deprecated, None otherwise.
        """
        status = await self.check_sdk_version("python", sdk_version)
        return status.upgrade_recommendation

    async def has_deprecation_warnings(self, algo_type: str) -> bool:
        """Check if an algo has any active deprecation warnings.

        Args:
            algo_type: The type of algo.

        Returns:
            True if there are deprecation warnings.
        """
        warnings = await self.get_algo_deprecations(algo_type)
        return len(warnings) > 0

    async def is_maintenance(self) -> bool:
        """Quick check if the environment is in maintenance.

        Returns:
            True if in maintenance mode.
        """
        status = await self.check_maintenance()
        return status.in_maintenance
