from azure.identity import DefaultAzureCredential
from azure.mgmt.compute import ComputeManagementClient
from azure.mgmt.storage import StorageManagementClient
from azure.mgmt.sql import SqlManagementClient
from azure.mgmt.web import WebSiteManagementClient
from azure.mgmt.network import NetworkManagementClient
from azure.mgmt.containerservice import ContainerServiceClient
from azure.core.exceptions import AzureError

class AzureConnector:
    """
    Handles the connection to Microsoft Azure.

    This class provides a singleton pattern for Azure credentials and clients,
    ensuring consistent authentication and client management.
    """
    _credential = None
    _subscription_id = None

    @classmethod
    def get_credential(cls):
        """
        Gets the Azure credential.

        If credentials do not already exist, it attempts to load them.
        """
        if cls._credential is None:
            try:
                print("Attempting to load Azure credentials...")
                cls._credential = DefaultAzureCredential()
                # Attempt to get subscription ID from environment or config
                # For simplicity, we'll assume it's set in the environment or passed later.
                # In a real scenario, you might list subscriptions or require it as input.
                print("Azure credentials loaded successfully.")
            except Exception as e:
                print(f"Error loading Azure credentials: {e}")
                print("Please ensure you have authenticated to Azure (e.g., `az login`).")
                raise
        return cls._credential

    @classmethod
    def get_subscription_id(cls):
        """
        Gets the Azure Subscription ID.
        This needs to be set externally or discovered.
        """
        if cls._subscription_id is None:
            # This is a placeholder. In a real app, you'd get this from config or user input.
            # For now, it must be set before client calls.
            raise ValueError("Azure Subscription ID is not set. Please set it using AzureConnector.set_subscription_id().")
        return cls._subscription_id

    @classmethod
    def set_subscription_id(cls, subscription_id: str):
        cls._subscription_id = subscription_id

    @classmethod
    def get_compute_client(cls):
        cls.get_credential()
        return ComputeManagementClient(cls._credential, cls.get_subscription_id())

    @classmethod
    def get_storage_client(cls):
        cls.get_credential()
        return StorageManagementClient(cls._credential, cls.get_subscription_id())

    @classmethod
    def get_sql_client(cls):
        cls.get_credential()
        return SqlManagementClient(cls._credential, cls.get_subscription_id())

    @classmethod
    def get_web_client(cls):
        cls.get_credential()
        return WebSiteManagementClient(cls._credential, cls.get_subscription_id())

    @classmethod
    def get_network_client(cls):
        cls.get_credential()
        return NetworkManagementClient(cls._credential, cls.get_subscription_id())

    @classmethod
    def get_container_service_client(cls):
        cls.get_credential()
        return ContainerServiceClient(cls._credential, cls.get_subscription_id())

    # Add other Azure service clients as needed

    @classmethod
    def login(cls, subscription_id: str):
        """
        Attempts to log in to Azure by verifying credentials and subscription ID.
        """
        try:
            cls.set_subscription_id(subscription_id)
            credential = cls.get_credential()
            # Verify by trying to list resource groups
            from azure.mgmt.resource import ResourceManagementClient
            resource_client = ResourceManagementClient(credential, subscription_id)
            list(resource_client.resource_groups.list())
            print(f"Successfully verified Azure credentials for subscription: {subscription_id}")
            return True
        except AzureError as e:
            print(f"Azure API error during login: {e}")
            print("Please ensure you have authenticated to Azure (e.g., `az login`) and the subscription ID is correct.")
            return False
        except Exception as e:
            print(f"An unexpected error occurred during Azure login: {e}")
            return False
