from cw_rpa import HttpClient, Input
from m365_user_manager.utils.input_processor import InputProcessor
from m365_user_manager.managers.environment_manager import EnvironmentManager
from m365_user_manager.managers.token_manager import TokenManager
from m365_user_manager.managers.user_manager import M365UserManager
from m365_user_manager.utils.result_handler import ResultHandler
from m365_user_manager.utils.input_identifiers import FormFields

class UserManagementOrchestrator():
    """
    Orchestrates the entire user management workflow.
    
    Coordinates between different components (EnvironmentManager, InputProcessor,
    TokenManager, etc.) to execute the complete user management process.
    
    Usage:
        orchestrator = UserManagementOrchestrator()
        orchestrator.run()
        
    Methods:
        run(): Executes the complete user management workflow
    """
    def __init__(self, running_in_asio: bool = False):
        self.input_form = Input()
        self.input_ids = FormFields()
        self.discord_webhook_id = self.input_ids.WEBHOOK_URL
        self.running_in_asio = running_in_asio
        self.discord_webhook_url = self.return_webhook_url()
        self.input_processor = InputProcessor(discord_webhook_url=self.discord_webhook_url)
        self.env_manager = EnvironmentManager(discord_webhook_url=self.discord_webhook_url, running_in_asio=self.running_in_asio)
        self.config = self.env_manager.initialize()
        self.logger = EnvironmentManager(discord_webhook_url=self.discord_webhook_url, running_in_asio=self.running_in_asio).setup_logging()
        self.result_handler = ResultHandler(discord_webhook_url=self.discord_webhook_url)
        self.token_manager = TokenManager(discord_webhook_url=self.discord_webhook_url)
        self.integration_name = "azure_o365"
        if self.running_in_asio:
            self.http_client = HttpClient()

    def return_webhook_url(self):
        try:
            webhook_url = self.input_form.get_value(self.discord_webhook_id)
            return webhook_url
        except Exception as e:
            self.logger.error(f"Error retrieving webhook URL: {str(e)}")
            return None
        
    def run(self):
        """Run the user management process."""
        try:
            # Process input based on environment
            kwargs, error = self.input_processor.process_input()
            if error:
                self.env_manager.logger.error(error)
                self.env_manager.logger.result_failed_message(error)
                return

            # Get authorization based on environment
            if self.running_in_asio:
                integration_client = self.http_client.third_party_integration(self.integration_name)
                token_response = integration_client.fetch_token(
                    client_id=integration_client.client_id,
                    client_secret=integration_client.client_secret,
                    scopes=["platform.rpa.resolve"]
                )
                
                if not token_response or not hasattr(token_response, 'token'):
                    error = "Failed to obtain authentication token"
                    self.env_manager.logger.error(error)
                    self.env_manager.logger.result_failed_message(error)
                    return

                access_token = token_response.token
            else:
                access_token = self.token_manager.get_access_token(
                    self.config['client_id'],
                    self.config['client_secret'],
                    self.config['tenant_id']
                )

            # Create and execute user management
            user_manager = M365UserManager(
                access_token, 
                self.env_manager.logger, 
                self.env_manager.PRODUCT_LICENSES,
                self.running_in_asio,
                discord_webhook_url=self.discord_webhook_url
            )
            result = user_manager.create_user(**kwargs)
            
            # Handle result based on environment
            if self.running_in_asio:
                self.result_handler.handle_asio_result(result)
            else:
                self.result_handler.handle_local_result(result)

        except Exception as e:
            error_msg = f"Critical error: {str(e)}"
            if self.running_in_asio:
                self.env_manager.logger.error(error_msg)
                self.env_manager.logger.result_failed_message(error_msg)
            else:
                self.env_manager.logger.error(error_msg)
                raise