# Copyright (c) 2025 Patrick Motsch
# All rights reserved.
"""
Notification model for in-app notifications.
Supports actionable notifications (e.g., invitation accept/decline).
"""

import uuid
from typing import Optional, List
from enum import Enum
from pydantic import BaseModel, Field, ConfigDict
from modules.shared.attributeUtils import registerModelLabels
from modules.shared.timeUtils import getUtcTimestamp


class NotificationType(str, Enum):
    """Types of notifications"""
    INVITATION = "invitation"      # Einladung zu Mandat/Feature
    SYSTEM = "system"              # System-Nachrichten
    WORKFLOW = "workflow"          # Workflow-Status Updates
    MENTION = "mention"            # Erwähnung in Chat/Kommentar


class NotificationStatus(str, Enum):
    """Status of a notification"""
    UNREAD = "unread"              # Noch nicht gelesen
    READ = "read"                  # Gelesen
    ACTIONED = "actioned"          # Aktion wurde durchgeführt
    DISMISSED = "dismissed"        # Verworfen/Geschlossen


class NotificationAction(BaseModel):
    """Possible action for a notification"""
    actionId: str = Field(
        description="Unique identifier for the action (e.g., 'accept', 'decline')"
    )
    label: str = Field(
        description="Display label for the action button"
    )
    style: str = Field(
        default="default",
        description="Button style: 'primary', 'danger', 'default'"
    )


class UserNotification(BaseModel):
    """
    In-app notification for a user.
    Supports actionable notifications with accept/decline buttons.
    """
    id: str = Field(
        default_factory=lambda: str(uuid.uuid4()),
        description="Unique ID of the notification",
        json_schema_extra={"frontend_type": "text", "frontend_readonly": True, "frontend_required": False}
    )
    userId: str = Field(
        description="Target user ID for this notification",
        json_schema_extra={"frontend_type": "text", "frontend_readonly": True, "frontend_required": True}
    )
    
    # Notification type and status
    type: NotificationType = Field(
        default=NotificationType.SYSTEM,
        description="Type of notification",
        json_schema_extra={
            "frontend_type": "select",
            "frontend_readonly": True,
            "frontend_required": True,
            "frontend_options": [
                {"value": "invitation", "label": {"en": "Invitation", "de": "Einladung"}},
                {"value": "system", "label": {"en": "System", "de": "System"}},
                {"value": "workflow", "label": {"en": "Workflow", "de": "Workflow"}},
                {"value": "mention", "label": {"en": "Mention", "de": "Erwähnung"}}
            ]
        }
    )
    status: NotificationStatus = Field(
        default=NotificationStatus.UNREAD,
        description="Current status of the notification",
        json_schema_extra={
            "frontend_type": "select",
            "frontend_readonly": True,
            "frontend_required": False,
            "frontend_options": [
                {"value": "unread", "label": {"en": "Unread", "de": "Ungelesen"}},
                {"value": "read", "label": {"en": "Read", "de": "Gelesen"}},
                {"value": "actioned", "label": {"en": "Actioned", "de": "Bearbeitet"}},
                {"value": "dismissed", "label": {"en": "Dismissed", "de": "Verworfen"}}
            ]
        }
    )
    
    # Content
    title: str = Field(
        description="Notification title",
        json_schema_extra={"frontend_type": "text", "frontend_readonly": True, "frontend_required": True}
    )
    message: str = Field(
        description="Notification message/body",
        json_schema_extra={"frontend_type": "textarea", "frontend_readonly": True, "frontend_required": True}
    )
    icon: Optional[str] = Field(
        default=None,
        description="Optional icon identifier (e.g., 'mail', 'warning', 'info')",
        json_schema_extra={"frontend_type": "text", "frontend_readonly": True, "frontend_required": False}
    )
    
    # Reference to triggering object (for actionable notifications)
    referenceType: Optional[str] = Field(
        default=None,
        description="Type of referenced object (e.g., 'Invitation', 'Workflow')",
        json_schema_extra={"frontend_type": "text", "frontend_readonly": True, "frontend_required": False}
    )
    referenceId: Optional[str] = Field(
        default=None,
        description="ID of referenced object",
        json_schema_extra={"frontend_type": "text", "frontend_readonly": True, "frontend_required": False}
    )
    
    # Actions (for actionable notifications like invitations)
    actions: Optional[List[NotificationAction]] = Field(
        default=None,
        description="List of possible actions for this notification",
        json_schema_extra={"frontend_type": "json", "frontend_readonly": True, "frontend_required": False}
    )
    
    # Action result (when user takes action)
    actionTaken: Optional[str] = Field(
        default=None,
        description="Which action was taken (actionId)",
        json_schema_extra={"frontend_type": "text", "frontend_readonly": True, "frontend_required": False}
    )
    actionResult: Optional[str] = Field(
        default=None,
        description="Result message from the action",
        json_schema_extra={"frontend_type": "textarea", "frontend_readonly": True, "frontend_required": False}
    )
    
    # Timestamps
    createdAt: float = Field(
        default_factory=getUtcTimestamp,
        description="When the notification was created (UTC timestamp)",
        json_schema_extra={"frontend_type": "timestamp", "frontend_readonly": True, "frontend_required": False}
    )
    readAt: Optional[float] = Field(
        default=None,
        description="When the notification was read (UTC timestamp)",
        json_schema_extra={"frontend_type": "timestamp", "frontend_readonly": True, "frontend_required": False}
    )
    actionedAt: Optional[float] = Field(
        default=None,
        description="When action was taken (UTC timestamp)",
        json_schema_extra={"frontend_type": "timestamp", "frontend_readonly": True, "frontend_required": False}
    )
    expiresAt: Optional[float] = Field(
        default=None,
        description="When the notification expires (optional, UTC timestamp)",
        json_schema_extra={"frontend_type": "timestamp", "frontend_readonly": True, "frontend_required": False}
    )
    
    model_config = ConfigDict(use_enum_values=True)


registerModelLabels(
    "UserNotification",
    {"en": "Notification", "de": "Benachrichtigung", "fr": "Notification"},
    {
        "id": {"en": "ID", "de": "ID", "fr": "ID"},
        "userId": {"en": "User", "de": "Benutzer", "fr": "Utilisateur"},
        "type": {"en": "Type", "de": "Typ", "fr": "Type"},
        "status": {"en": "Status", "de": "Status", "fr": "Statut"},
        "title": {"en": "Title", "de": "Titel", "fr": "Titre"},
        "message": {"en": "Message", "de": "Nachricht", "fr": "Message"},
        "icon": {"en": "Icon", "de": "Symbol", "fr": "Icône"},
        "referenceType": {"en": "Reference Type", "de": "Referenz-Typ", "fr": "Type de référence"},
        "referenceId": {"en": "Reference ID", "de": "Referenz-ID", "fr": "ID de référence"},
        "actions": {"en": "Actions", "de": "Aktionen", "fr": "Actions"},
        "actionTaken": {"en": "Action Taken", "de": "Durchgeführte Aktion", "fr": "Action effectuée"},
        "actionResult": {"en": "Action Result", "de": "Aktions-Ergebnis", "fr": "Résultat de l'action"},
        "createdAt": {"en": "Created At", "de": "Erstellt am", "fr": "Créé le"},
        "readAt": {"en": "Read At", "de": "Gelesen am", "fr": "Lu le"},
        "actionedAt": {"en": "Actioned At", "de": "Bearbeitet am", "fr": "Traité le"},
        "expiresAt": {"en": "Expires At", "de": "Gültig bis", "fr": "Expire le"},
    },
)


registerModelLabels(
    "NotificationType",
    {"en": "Notification Type", "de": "Benachrichtigungs-Typ", "fr": "Type de notification"},
    {
        "invitation": {"en": "Invitation", "de": "Einladung", "fr": "Invitation"},
        "system": {"en": "System", "de": "System", "fr": "Système"},
        "workflow": {"en": "Workflow", "de": "Workflow", "fr": "Workflow"},
        "mention": {"en": "Mention", "de": "Erwähnung", "fr": "Mention"},
    },
)


registerModelLabels(
    "NotificationStatus",
    {"en": "Notification Status", "de": "Benachrichtigungs-Status", "fr": "Statut de notification"},
    {
        "unread": {"en": "Unread", "de": "Ungelesen", "fr": "Non lu"},
        "read": {"en": "Read", "de": "Gelesen", "fr": "Lu"},
        "actioned": {"en": "Actioned", "de": "Bearbeitet", "fr": "Traité"},
        "dismissed": {"en": "Dismissed", "de": "Verworfen", "fr": "Rejeté"},
    },
)
