# Copyright (c) 2025 Patrick Motsch
# All rights reserved.
"""
Invitation model for self-service onboarding.
Token-basierte Einladungen für neue User zu Mandanten/Features.
"""

import uuid
import secrets
from typing import Optional, List
from pydantic import BaseModel, Field
from modules.datamodels.datamodelBase import PowerOnModel
from modules.shared.i18nRegistry import i18nModel


@i18nModel("Einladung")
class Invitation(PowerOnModel):
    """
    Einladungs-Token für neue User.
    Ermöglicht Self-Service Onboarding zu Mandanten und Feature-Instanzen.
    """
    id: str = Field(
        default_factory=lambda: str(uuid.uuid4()),
        description="Unique ID of the invitation",
        json_schema_extra={"label": "ID", "frontend_type": "text", "frontend_readonly": True, "frontend_required": False}
    )
    token: str = Field(
        default_factory=lambda: secrets.token_urlsafe(32),
        description="Secure invitation token",
        json_schema_extra={"label": "Token", "frontend_type": "text", "frontend_readonly": True, "frontend_required": False}
    )

    mandateId: str = Field(
        description="FK → Mandate.id - Target mandate for the invitation",
        json_schema_extra={"label": "Mandant", "frontend_type": "text", "frontend_readonly": True, "frontend_required": True}
    )
    featureInstanceId: Optional[str] = Field(
        default=None,
        description="Optional FK → FeatureInstance.id - Direct access to specific feature",
        json_schema_extra={"label": "Feature-Instanz", "frontend_type": "text", "frontend_readonly": True, "frontend_required": False}
    )
    roleIds: List[str] = Field(
        default_factory=list,
        description="List of Role IDs to assign to the invited user",
        json_schema_extra={"label": "Rollen", "frontend_type": "multiselect", "frontend_readonly": False, "frontend_required": True}
    )

    targetUsername: Optional[str] = Field(
        default=None,
        description="Username of the invited user (must match on acceptance)",
        json_schema_extra={"label": "Ziel-Benutzername", "frontend_type": "text", "frontend_readonly": False, "frontend_required": False}
    )
    email: Optional[str] = Field(
        default=None,
        description="Email address to send invitation link (optional)",
        json_schema_extra={"label": "E-Mail (optional)", "frontend_type": "email", "frontend_readonly": False, "frontend_required": False}
    )
    expiresAt: float = Field(
        description="When the invitation expires (UTC timestamp)",
        json_schema_extra={"label": "Gueltig bis", "frontend_type": "timestamp", "frontend_readonly": True, "frontend_required": True}
    )

    usedBy: Optional[str] = Field(
        default=None,
        description="User ID of the person who used the invitation",
        json_schema_extra={"label": "Verwendet von", "frontend_type": "text", "frontend_readonly": True, "frontend_required": False}
    )
    usedAt: Optional[float] = Field(
        default=None,
        description="When the invitation was used (UTC timestamp)",
        json_schema_extra={"label": "Verwendet am", "frontend_type": "timestamp", "frontend_readonly": True, "frontend_required": False}
    )
    revokedAt: Optional[float] = Field(
        default=None,
        description="When the invitation was revoked (UTC timestamp)",
        json_schema_extra={"label": "Widerrufen am", "frontend_type": "timestamp", "frontend_readonly": True, "frontend_required": False}
    )

    emailSent: Optional[bool] = Field(
        default=False,
        description="Whether the invitation email was successfully sent",
        json_schema_extra={"label": "E-Mail gesendet", "frontend_type": "checkbox", "frontend_readonly": True, "frontend_required": False}
    )

    maxUses: int = Field(
        default=1,
        ge=1,
        le=100,
        description="Maximum number of times this invitation can be used",
        json_schema_extra={"label": "Max. Verwendungen", "frontend_type": "number", "frontend_readonly": False, "frontend_required": False}
    )
    currentUses: int = Field(
        default=0,
        ge=0,
        description="Current number of times this invitation has been used",
        json_schema_extra={"label": "Aktuelle Verwendungen", "frontend_type": "number", "frontend_readonly": True, "frontend_required": False}
    )
