from ..base_azure_agent import BaseAzureAgent
from ..azure_connector import AzureConnector
from azure.mgmt.web.models import Site, HostingEnvironmentProfile, SkuDescription, FunctionAppMajorVersion
from azure.mgmt.storage.models import StorageAccountCreateParameters, Sku, Kind
from msrestazure.azure_exceptions import CloudError
import time

class FunctionsAgent(BaseAzureAgent):
    """
    An agent specialized in handling Azure Functions tasks.
    """

    def execute(self, command: str, **kwargs):
        """
        Executes a given command related to Azure Functions.
        """
        if command == 'smart_create_function_app':
            app_name = kwargs.get('app_name', '')
            resource_group = kwargs.get('resource_group', '')
            print(f"You are about to smart-create an Azure Function App '{app_name}' in resource group '{resource_group}'.")
            confirm = input("This will create a new Function App and a Storage Account (if needed). Are you sure? (yes/no): ")
            if confirm.lower() == 'yes':
                return self._smart_create_function_app(**kwargs)
            else:
                return {"status": "cancelled", "message": "Smart Create Function App command cancelled by user."}
        else:
            raise NotImplementedError(f"Command '{command}' is not supported by FunctionsAgent.")

    def _smart_create_function_app(self, subscription_id: str, resource_group: str, location: str, 
                                   app_name: str, storage_account_name: str, runtime: str = 'node', runtime_version: str = '18'):
        """
        Creates an Azure Function App with sensible defaults.
        Automatically creates a Storage Account if it doesn't exist.
        """
        print(f"FunctionsAgent: Smart creating Function App '{app_name}' in resource group '{resource_group}', location '{location}'...")
        try:
            web_client = AzureConnector.get_web_client()
            storage_client = AzureConnector.get_storage_client()

            # 1. Create Storage Account if it doesn't exist
            try:
                storage_client.storage_accounts.get_properties(resource_group, storage_account_name)
                print(f"Using existing Storage Account: {storage_account_name}")
            except CloudError:
                print(f"Creating Storage Account '{storage_account_name}' for Function App...")
                storage_account_params = StorageAccountCreateParameters(
                    sku=Sku(name='Standard_LRS'),
                    kind=Kind('StorageV2'),
                    location=location,
                    enable_https_traffic_only=True,
                    minimum_tls_version='TLS1_2',
                    allow_blob_public_access=False,
                    network_rule_set={'default_action': 'Deny'}
                )
                async_storage_creation = storage_client.storage_accounts.begin_create(resource_group, storage_account_name, storage_account_params)
                storage_account = async_storage_creation.wait()
                print(f"Storage Account '{storage_account_name}' created.")

            # 2. Create Function App
            print(f"Creating Function App: {app_name}")
            app_service_plan_name = f'{app_name}-plan'

            # Create App Service Plan (Consumption Plan for Functions)
            try:
                web_client.app_service_plans.get(resource_group, app_service_plan_name)
                print(f"Using existing App Service Plan: {app_service_plan_name}")
            except CloudError:
                print(f"Creating App Service Plan: {app_service_plan_name}")
                plan_params = web_client.app_service_plans.begin_create_or_update(
                    resource_group,
                    app_service_plan_name,
                    {
                        'location': location,
                        'kind': 'FunctionApp',
                        'sku': SkuDescription(name='Y1', tier='Dynamic'), # Consumption plan
                        'reserved': True # For Linux
                    }
                ).result()
                print(f"App Service Plan '{app_service_plan_name}' created.")

            function_app_params = Site(
                location=location,
                server_farm_id=f"/subscriptions/{subscription_id}/resourceGroups/{resource_group}/providers/Microsoft.Web/serverfarms/{app_service_plan_name}",
                kind='functionapp',
                site_config={
                    'app_settings': [
                        {'name': 'FUNCTIONS_WORKER_RUNTIME', 'value': runtime},
                        {'name': 'FUNCTIONS_EXTENSION_VERSION', 'value': '~4'},
                        {'name': 'AzureWebJobsStorage', 'value': f'DefaultEndpointsProtocol=https;AccountName={storage_account_name};AccountKey={storage_client.storage_accounts.list_keys(resource_group, storage_account_name).keys[0].value};EndpointSuffix=core.windows.net'},
                        {'name': 'WEBSITE_RUN_FROM_PACKAGE', 'value': '1'},
                        {'name': 'WEBSITE_NODE_DEFAULT_VERSION', 'value': runtime_version if runtime == 'node' else None},
                        {'name': 'WEBSITE_PYTHON_DEFAULT_VERSION', 'value': runtime_version if runtime == 'python' else None},
                    ]
                }
            )
            async_app_creation = web_client.web_apps.begin_create_or_update(resource_group, app_name, function_app_params)
            function_app = async_app_creation.wait()

            return {"status": "success", "message": f"Function App '{app_name}' created successfully.", "app_id": function_app.id}
        except CloudError as e:
            print(f"Azure Error creating Function App: {e.message}")
            return {"status": "error", "message": e.message}
        except Exception as e:
            print(f"Error creating Function App: {e}")
            return {"status": "error", "message": str(e)}
