from typing import Dict, List, Optional, Tuple
from pathlib import Path
import json
import logging
from cw_rpa_unified_logger import UnifiedLogger
from m365_user_manager.config import logging_config

class EnvironmentManager():
    """
    Manages environment configuration and setup for the application.
    
    This class handles environment detection (local vs Asio RPA), logging setup,
    and configuration management. It maintains a predefined list of Microsoft 365
    product licenses and their corresponding SKU IDs.
    
    Usage:
        env_manager = EnvironmentManager()
        is_asio, config = env_manager.initialize()
        
        # Access logger
        env_manager.logger.info("Application started")
        
    Attributes:
        PRODUCT_LICENSES (List[Dict]): Mapping of M365 license names to SKU IDs
        running_in_asio (bool): Indicates if running in Asio environment
        config (Dict): Configuration parameters loaded from file
        logger (Logger): Logging instance for the application
        
    Methods:
        initialize(): Sets up environment and returns (is_asio, config)
        setup_logging(): Configures logging handlers
        determine_environment(): Detects runtime environment
    """
    PRODUCT_LICENSES = [
        {"ProductName": "Microsoft 365 E1", "StringID": "STANDARDPACK"},
        {"ProductName": "Microsoft 365 E3", "StringID": "SPE_E3"},
        {"ProductName": "Microsoft 365 E5", "StringID": "SPE_E5"},
        {"ProductName": "Microsoft 365 Business Basic", "StringID": "O365_BUSINESS_ESSENTIALS"},
        {"ProductName": "Microsoft 365 Business Standard", "StringID": "O365_BUSINESS_PREMIUM"},
        {"ProductName": "Microsoft 365 Business Premium", "StringID": "SPB"},
        {"ProductName": "Microsoft Defender for Endpoint", "StringID": "DEFENDER_ENDPOINT_P1"},
        {"ProductName": "Power Automate Free", "StringID": "FLOW_FREE"},
        {"ProductName": "Power Automate Premium", "StringID": "POWERAUTOMATE_ATTENDED_RPA"},
        {"ProductName": "Power BI Pro", "StringID": "POWER_BI_PRO"},
        {"ProductName": "Microsoft Teams Essentials", "StringID": "Teams_Ess"},
        {"ProductName": "Exchange Online Plan 1", "StringID": "EXCHANGESTANDARD"},
        {"ProductName": "Exchange Online Plan 2", "StringID": "EXCHANGEENTERPRISE"},
        {"ProductName": "Copilot for Microsoft 365", "StringID": "Microsoft_365_Copilot"}
    ]

    def __init__(self, discord_webhook_url: Optional[str] = None, running_in_asio: Optional[bool] = None):
        self.running_in_asio = running_in_asio
        self.config = None
        self.discord_webhook_url = discord_webhook_url
        self.logging_config = logging_config(discord_webhook_url=self.discord_webhook_url)
        self.logger = self.setup_logging()
        self.configuration_path = self._configuration_path()
        
    def setup_logging(self):
        """Configure logging for the application."""
        unified_logger = UnifiedLogger(self.logging_config)
        return unified_logger

    def _configuration_path(self) -> Optional[Path]:
        """
        Get the path to the configuration file by searching up directory tree.
        Only used when not running in Asio.
        
        Returns:
            Optional[Path]: Path to configuration file or None if not found
        """
        if self.running_in_asio:
            return None
            
        try:
            current = Path(__file__).resolve()
            config_name = "asio_365_config.json"
            
            # Search up directory tree for environments folder
            while current.parent != current:  # Stop at root directory
                for env_dir in ["environments", "Environments"]:
                    config_path = current / env_dir / config_name
                    if config_path.exists():
                        self.logger.info(f"Found config at path: {config_path}")
                        return config_path
                current = current.parent
                
            self.logger.warning("No configuration file found in any environments directory")
            return None
                
        except Exception as e:
            self.logger.error(f"Error finding configuration path: {str(e)}")
            return None

    def determine_environment(self) -> Optional[Dict]:
        """Load configuration if not running in Asio."""
        if self.running_in_asio:
            return None
            
        try:
            if not self.configuration_path:
                self.logger.warning("No configuration path found")
                return None
                
            with open(self.configuration_path, 'r') as f:
                config = json.load(f)
                
            # Validate required keys
            required_keys = ['client_id', 'client_secret', 'tenant_id']
            if all(key in config for key in required_keys):
                return config
                
            self.logger.error("Configuration file missing required keys")
            return None

        except (FileNotFoundError, json.JSONDecodeError) as e:
            self.logger.error(f"Error loading configuration: {str(e)}")
            return None

    def initialize(self) -> Optional[Dict]:
        """Initialize and return configuration if not running in Asio."""
        return self.determine_environment()