"""Content/file operations for Archer REST API with model support."""

import logging
from typing import BinaryIO, Optional, Union
import base64

from ..models import AttachmentWrapper, AttachmentResponse
from .base import BaseAPI


logger = logging.getLogger(__name__)


class AttachmentAPI(BaseAPI):
    """API client for file/attachment operations."""
    
    def upload(
        self,
        application_id: int = None,
        content_id: int = None,
        field_id: int = None,
        file_data: BinaryIO = None,
        filename: str = None,
        is_sensitive: bool = False,
        attachment_model: Optional[AttachmentWrapper] = None
    ) -> int:
        """
        Upload a file attachment.
        
        Args:
            application_id: ID of the application (traditional)
            content_id: Content ID (traditional)
            field_id: Field ID (traditional)
            file_data: File object (traditional)
            filename: File name (traditional)
            is_sensitive: Encrypt the file (traditional)
            attachment_model: AttachmentWrapper model (model-based)
            
        Returns:
            Attachment ID
            
        Example (Traditional):
            >>> with open("document.pdf", "rb") as f:
            ...     att_id = client.rest.attachments.upload(
            ...         application_id=75,
            ...         content_id=123,
            ...         field_id=1001,
            ...         file_data=f,
            ...         filename="document.pdf",
            ...         is_sensitive=True
            ...     )
        
        Example (Model-based):
            >>> from py_ullr.models import AttachmentWrapper
            >>> 
            >>> attachment = AttachmentWrapper.from_file(
            ...     "document.pdf",
            ...     is_sensitive=True
            ... )
            >>> att_id = client.rest.attachments.upload(
            ...     content_id=123,
            ...     field_id=1001,
            ...     attachment_model=attachment
            ... )
        """
        url = f"{self.base_url}/api/core/content/attachment"
        
        if attachment_model:
            # Use model - post as JSON with bytes
            data = {
                'AttachmentName': attachment_model.AttachmentName,
                'AttachmentBytes': attachment_model.AttachmentBytes,
                'IsSensitive': attachment_model.IsSensitive,
                'ContentId': content_id,
                'FieldId': field_id
            }
            response = self._make_request("POST", url, json=data)
        else:
            # Traditional way - multipart form data
            if not all([file_data, filename]):
                raise ValueError("file_data and filename are required")
            
            files = {'file': (filename, file_data)}
            data = {
                'AttachmentName': filename,
                'ContentId': content_id,
                'FieldId': field_id,
                'IsSensitive': is_sensitive
            }
            response = self._make_request("POST", url, files=files, data=data)
        
        result = response.json()
        response_model = AttachmentResponse(**result)
        
        if not response_model.IsSuccessful:
            raise Exception(f"Upload failed: {response_model.ValidationMessages}")
        
        return response_model.attachment_id
    
    def download(
        self,
        attachment_id: int,
        as_model: bool = False
    ) -> Union[bytes, AttachmentWrapper]:
        """
        Download a file attachment.
        
        Args:
            attachment_id: Attachment ID
            as_model: If True, return as AttachmentWrapper
            
        Returns:
            File bytes or AttachmentWrapper model
            
        Example (Traditional):
            >>> file_bytes = client.rest.attachments.download(456)
            >>> with open("downloaded.pdf", "wb") as f:
            ...     f.write(file_bytes)
        
        Example (Model-based):
            >>> attachment = client.rest.attachments.download(456, as_model=True)
            >>> attachment.save_to_file("downloaded.pdf")
            >>> print(f"Downloaded: {attachment.AttachmentName}")
        """
        url = f"{self.base_url}/api/core/content/attachment/{attachment_id}"
        response = self._make_request("GET", url)
        
        if as_model:
            # Parse the response as AttachmentWrapper
            data = response.json()
            return AttachmentWrapper(**data)
        
        return response.content
    
    def delete(self, attachment_id: int) -> bool:
        """Delete a file attachment."""
        url = f"{self.base_url}/api/core/content/attachment/{attachment_id}"
        response = self._make_request("DELETE", url)
        return response.status_code == 200
