# Copyright (c) CloudZero - ALL RIGHTS RESERVED - PROPRIETARY AND CONFIDENTIAL
# Unauthorized copying of this file and/or project, via any medium is strictly prohibited.
# Direct all questions to legal@cloudzero.com
#

"""
Connection-specific utilities.

This module provides utilities for working with CloudZero connections:
- Connection type determination
- Feature extraction
- Status calculations
- Common connection operations
"""

from typing import Any


class ConnectionUtils:
    """Utilities for working with connections."""

    @staticmethod
    def get_connection_type(connection: dict[str, Any]) -> str:
        """
        Determine connection type from connection data.

        Args:
            connection: Connection dictionary

        Returns:
            Connection type string (payer, resource, or unknown)
        """
        # V4 API stores connection details nested, legacy at top level
        connection_details = connection.get("connection_details", {})

        # Check for payer type - V4 API stores flags in connection_details
        is_cost_connection = connection_details.get("is_cost_connection") or connection.get("is_cost_connection", False)
        is_payer_account = connection.get("account_type") == "payer"
        has_master_payer_role = connection_details.get("role_arn") or connection.get("master_payer_role_arn")

        if is_cost_connection or is_payer_account or has_master_payer_role:
            return "payer"

        # Check for resource type
        is_resource_connection = connection_details.get("is_resource_connection") or connection.get("is_resource_connection", False)
        is_resource_account = connection.get("account_type") == "resource"
        has_resource_role = connection.get("resource_owner_role_arn")

        if is_resource_connection or is_resource_account or has_resource_role:
            return "resource"

        return "unknown"

    @staticmethod
    def is_payer_connection(connection: dict[str, Any]) -> bool:
        """
        Check if connection is a payer type.

        Args:
            connection: Connection dictionary

        Returns:
            True if payer connection
        """
        return ConnectionUtils.get_connection_type(connection) == "payer"

    @staticmethod
    def is_resource_connection(connection: dict[str, Any]) -> bool:
        """
        Check if connection is a resource type.

        Args:
            connection: Connection dictionary

        Returns:
            True if resource connection
        """
        return ConnectionUtils.get_connection_type(connection) == "resource"

    @staticmethod
    def get_connection_features(connection: dict[str, Any]) -> list[str]:
        """
        Extract enabled features from connection.

        Args:
            connection: Connection dictionary

        Returns:
            List of enabled feature names
        """
        features = []

        # Check various feature flags
        if connection.get("enable_anomaly_detection"):
            features.append("Anomaly Detection")

        if connection.get("enable_cost_allocation"):
            features.append("Cost Allocation")

        if connection.get("enable_rightsizing"):
            features.append("Rightsizing")

        if connection.get("enable_savings_plans"):
            features.append("Savings Plans")

        if connection.get("enable_reserved_instances"):
            features.append("Reserved Instances")

        return features

    @staticmethod
    def get_connection_id(connection: dict[str, Any]) -> str | None:
        """
        Safely get connection ID from connection data.

        Args:
            connection: Connection dictionary

        Returns:
            Connection ID or None
        """
        # Note: Backend API field 'cloud_account_id' still uses 'account' terminology
        return connection.get("cloud_account_id")

    @staticmethod
    def get_connection_name(connection: dict[str, Any]) -> str:
        """
        Get connection display name.

        Args:
            connection: Connection dictionary

        Returns:
            Connection name or 'Unknown'
        """
        return connection.get("cz_account_name", "Unknown")

    @staticmethod
    def get_organization_info(connection: dict[str, Any]) -> tuple[str, str]:
        """
        Get organization ID and name from connection.

        Args:
            connection: Connection dictionary

        Returns:
            Tuple of (org_id, org_name)
        """
        org_id = connection.get("cz_organization_id", "Unknown")
        org_name = connection.get("cz_organization_name", "Unknown")
        return org_id, org_name

    @staticmethod
    def calculate_spend_percentage(
        connection_id: str,
        spend_data: dict[str, float],
    ) -> tuple[float, float, float]:
        """
        Calculate spend amount and percentage for a connection.

        Args:
            connection_id: Connection ID
            spend_data: Dictionary of connection_id -> spend amount

        Returns:
            Tuple of (connection_spend, total_spend, percentage)
        """
        if not spend_data:
            return 0.0, 0.0, 0.0

        connection_spend = spend_data.get(connection_id, 0.0)
        total_spend = sum(spend_data.values())

        percentage = connection_spend / total_spend * 100 if total_spend > 0 else 0.0

        return connection_spend, total_spend, percentage

    @staticmethod
    def format_cur_features(schema_elements: list[str]) -> str:
        """
        Format CUR schema elements for display.

        Maps abbreviated names to full feature names.

        Args:
            schema_elements: List of schema element names

        Returns:
            Comma-separated string of full feature names
        """
        # Mapping of common abbreviations to full names
        feature_map = {
            "RESOURCES": "RESOURCES",
            "RESOURCE_TAGS": "RESOURCE_TAGS",
            "MANUAL_DISCOUNT_COMPATIBILITY": "MANUAL_DISCOUNT_COMPATIBILITY",
            "SPLIT_COST_ALLOCATION_DATA": "SPLIT_COST_ALLOCATION_DATA",
            "BILLING_ENTITY": "BILLING_ENTITY",
        }

        # Map any abbreviated names to full names
        full_names = []
        for element in schema_elements:
            full_name = feature_map.get(element, element)
            full_names.append(full_name)

        return ", ".join(full_names) if full_names else "None"

    @staticmethod
    def format_resource_collection_details(connection: dict[str, Any]) -> str:
        """
        Analyze resource collection configuration and return display string.

        Args:
            connection: Connection dictionary

        Returns:
            Formatted resource collection string
        """
        rc_configs = connection.get("resource_collector_configurations")
        if not rc_configs:
            return "[dim]Disabled[/]"

        # If configs exist, resource collection is enabled
        # Check CloudWatch Metrics status
        cwm_enabled = rc_configs.get("cwm", False)
        cwm_status = "[green]CWM[/]" if cwm_enabled else "[dim]CWM[/]"

        # Check for probes
        probes = rc_configs.get("probes", [])
        if not probes:
            return cwm_status

        # Format probe list
        probe_list = ", ".join(f"[blue]{p}[/]" for p in probes)
        return f"{cwm_status} {probe_list}"

    @staticmethod
    def format_connection_info_list(payer_accounts: list[str], org_connections: dict[str, Any]) -> list[str]:
        """
        Format connection information for display.

        Args:
            payer_accounts: List of payer account IDs
            org_connections: Dictionary of organization connections

        Returns:
            List of formatted connection info strings
        """
        connections_info = []

        # Track which payer accounts we've processed
        for i, payer_id in enumerate(payer_accounts[:2]):
            if i < 2:  # Only show first two payers
                # Find the provider type for this account ID
                provider_type = ""
                for _conn_id, conn in org_connections.items():
                    if conn.get("cloud_account_id") == payer_id and conn.get("cloud_provider"):
                        provider_type = conn.get("cloud_provider").lower()
                        break

                provider_str = f"({provider_type})" if provider_type else ""
                connections_info.append(f"{payer_id} {provider_str}")

        if len(payer_accounts) > 2:
            connections_info.append(f"+{len(payer_accounts) - 2} more")

        return connections_info
