# Copyright (c) 2025 Patrick Motsch
# All rights reserved.
"""File-related datamodels: FileItem, FilePreview, FileData."""

from typing import Dict, Any, Optional, Union
from pydantic import BaseModel, ConfigDict, Field
from modules.shared.attributeUtils import registerModelLabels
from modules.shared.timeUtils import getUtcTimestamp
import uuid
import base64


class FileItem(BaseModel):
    model_config = ConfigDict(extra='allow')  # Preserve system fields (_createdBy, _createdAt, etc.)
    id: str = Field(default_factory=lambda: str(uuid.uuid4()), description="Primary key", json_schema_extra={"frontend_type": "text", "frontend_readonly": True, "frontend_required": False})
    mandateId: Optional[str] = Field(default="", description="ID of the mandate this file belongs to", json_schema_extra={"frontend_type": "text", "frontend_readonly": True, "frontend_required": False})
    featureInstanceId: Optional[str] = Field(default="", description="ID of the feature instance this file belongs to", json_schema_extra={"frontend_type": "text", "frontend_readonly": True, "frontend_required": False})
    fileName: str = Field(description="Name of the file", json_schema_extra={"frontend_type": "text", "frontend_readonly": False, "frontend_required": True})
    mimeType: str = Field(description="MIME type of the file", json_schema_extra={"frontend_type": "text", "frontend_readonly": True, "frontend_required": False})
    fileHash: str = Field(description="Hash of the file", json_schema_extra={"frontend_type": "text", "frontend_readonly": True, "frontend_required": False})
    fileSize: int = Field(description="Size of the file in bytes", json_schema_extra={"frontend_type": "integer", "frontend_readonly": True, "frontend_required": False})
    creationDate: float = Field(default_factory=getUtcTimestamp, description="Date when the file was created (UTC timestamp in seconds)", json_schema_extra={"frontend_type": "timestamp", "frontend_readonly": True, "frontend_required": False})

registerModelLabels(
    "FileItem",
    {"en": "File Item", "fr": "Élément de fichier"},
    {
        "id": {"en": "ID", "fr": "ID"},
        "mandateId": {"en": "Mandate ID", "fr": "ID du mandat"},
        "featureInstanceId": {"en": "Feature Instance ID", "fr": "ID de l'instance de fonctionnalité"},
        "fileName": {"en": "fileName", "fr": "Nom de fichier"},
        "mimeType": {"en": "MIME Type", "fr": "Type MIME"},
        "fileHash": {"en": "File Hash", "fr": "Hash du fichier"},
        "fileSize": {"en": "File Size", "fr": "Taille du fichier"},
        "creationDate": {"en": "Creation Date", "fr": "Date de création"},
    },
)

class FilePreview(BaseModel):
    content: Union[str, bytes] = Field(description="File content (text or binary)")
    mimeType: str = Field(description="MIME type of the file")
    fileName: str = Field(description="Original fileName")
    isText: bool = Field(description="Whether the content is text (True) or binary (False)")
    encoding: Optional[str] = Field(None, description="Text encoding if content is text")
    size: int = Field(description="Size of the content in bytes")

    def toDictWithBase64Encoding(self) -> Dict[str, Any]:
        """Convert to dictionary with base64 encoding for binary content."""
        data = self.model_dump()
        if isinstance(data.get("content"), bytes):
            data["content"] = base64.b64encode(data["content"]).decode("utf-8")
        return data
registerModelLabels(
    "FilePreview",
    {"en": "File Preview", "fr": "Aperçu du fichier"},
    {
        "content": {"en": "Content", "fr": "Contenu"},
        "mimeType": {"en": "MIME Type", "fr": "Type MIME"},
        "fileName": {"en": "fileName", "fr": "Nom de fichier"},
        "isText": {"en": "Is Text", "fr": "Est du texte"},
        "encoding": {"en": "Encoding", "fr": "Encodage"},
        "size": {"en": "Size", "fr": "Taille"},
    },
)

class FileData(BaseModel):
    id: str = Field(default_factory=lambda: str(uuid.uuid4()), description="Primary key")
    data: str = Field(description="File data content")
    base64Encoded: bool = Field(description="Whether the data is base64 encoded")
registerModelLabels(
    "FileData",
    {"en": "File Data", "fr": "Données de fichier"},
    {
        "id": {"en": "ID", "fr": "ID"},
        "data": {"en": "Data", "fr": "Données"},
        "base64Encoded": {"en": "Base64 Encoded", "fr": "Encodé en Base64"},
    },
)
