"""Application operations for Archer REST API with model support."""

import logging
from typing import List, Dict, Any, Union

from ..models.application import Application, FieldDefinition
from .base import BaseAPI


logger = logging.getLogger(__name__)


class ApplicationsAPI(BaseAPI):
    """API client for Archer application operations."""
    
    def get_all(self, as_model: bool = False) -> Union[List[Dict[str, Any]], List[Application]]:
        """
        Get all applications.
        
        Args:
            as_model: If True, return as list of Application models
            
        Returns:
            List of applications as dicts or Application models
            
        Example:
            >>> apps = client.rest.applications.get_all(as_model=True)
            >>> for app in apps:
            ...     print(f"{app.Name} (ID: {app.Id})")
        """
        url = f"{self.base_url}/platformapi/core/system/application"
        response = self._make_request("GET", url)
        data = response.json()
        
        # Handle different response formats
        if isinstance(data, list):
            # Extract RequestedObject from each item if wrapped
            unwrapped_data = []
            for item in data:
                if isinstance(item, dict) and 'RequestedObject' in item:
                    unwrapped_data.append(item['RequestedObject'])
                else:
                    unwrapped_data.append(item)
            data = unwrapped_data
        elif isinstance(data, dict) and 'RequestedObject' in data:
            data = data['RequestedObject']
            if not isinstance(data, list):
                data = [data]
        
        if as_model:
            return [Application(**app) for app in data]
        return data
    
    def get(
        self,
        application_id: int,
        as_model: bool = False,
        include_fields: bool = False
    ) -> Union[Dict[str, Any], Application]:
        """
        Get a specific application.
        
        Args:
            application_id: Application ID
            as_model: If True, return as Application model
            include_fields: If True and as_model=True, fetch and include field definitions
            
        Returns:
            Application data as dict or Application model
            
        Example:
            >>> # Get application with fields
            >>> app = client.rest.applications.get(
            ...     application_id=191,
            ...     as_model=True,
            ...     include_fields=True
            ... )
            >>> print(f"App: {app.Name}")
            >>> print(f"Fields: {len(app.fields)}")
            >>> for field in app.fields:
            ...     print(f"  {field.Name}: {field.type_name}")
        """
        url = f"{self.base_url}/platformapi/core/system/application/{application_id}"
        response = self._make_request("GET", url)
        data = response.json()
        
        # Extract from RequestedObject wrapper
        if isinstance(data, dict) and 'RequestedObject' in data:
            data = data['RequestedObject']
        
        if as_model:
            app = Application(**data)
            
            # Optionally fetch and attach field definitions
            if include_fields:
                # get_fields already returns the correct format
                fields_data = self.get_fields(application_id, as_model=True)
                app.fields = fields_data
            
            return app
        
        return data
    
    def get_fields(
        self,
        application_id: int,
        as_model: bool = False
    ) -> Union[List[Dict[str, Any]], List[FieldDefinition]]:
        """
        Get fields for an application.
        
        Args:
            application_id: Application ID
            as_model: If True, return as list of FieldDefinition models
            
        Returns:
            List of field definitions
            
        Example:
            >>> # Get as dictionaries
            >>> fields = client.rest.applications.get_fields(191)
            >>> 
            >>> # Get as models with validation
            >>> fields = client.rest.applications.get_fields(191, as_model=True)
            >>> for field in fields:
            ...     print(f"{field.Name}: {field.type_name} ({field.type_syntax})")
        """
        url = f"{self.base_url}/platformapi/core/system/fielddefinition/application/{application_id}"
        response = self._make_request("GET", url)
        data = response.json()
        
        logger.debug(f"get_fields raw response type: {type(data)}")
        
        # ✅ CRITICAL FIX: Handle list of wrapped objects
        # The API returns: [{"RequestedObject": {...}}, {"RequestedObject": {...}}, ...]
        # We need to extract RequestedObject from each item
        
        if isinstance(data, list):
            # Extract RequestedObject from each item in the list
            unwrapped_data = []
            for item in data:
                if isinstance(item, dict) and 'RequestedObject' in item:
                    unwrapped_data.append(item['RequestedObject'])
                else:
                    unwrapped_data.append(item)
            data = unwrapped_data
        elif isinstance(data, dict) and 'RequestedObject' in data:
            # Single wrapped object
            data = [data['RequestedObject']]
        elif not isinstance(data, list):
            # Single unwrapped object
            data = [data] if data else []
        
        logger.debug(f"get_fields final data type: {type(data)}, length: {len(data)}")
        
        if as_model:
            return [FieldDefinition(**f) for f in data]
        return data