"""User configuration models for Teams Phone Graph API responses.

These models represent the Teams User Configuration data from Microsoft Graph API.
All models use `extra="forbid"` for strict contract validation to detect API changes.
"""

from datetime import datetime
from enum import Enum
from typing import Optional

from pydantic import BaseModel, ConfigDict, Field


class AccountType(str, Enum):
    """User account type in Microsoft Teams.

    Attributes:
        USER: Standard user account.
        RESOURCE_ACCOUNT: Resource account (e.g., auto attendant, call queue).
        GUEST: Guest user account.
        SFB_ON_PREM_USER: Skype for Business on-premises user.
        INELIGIBLE_USER: User not eligible for Teams Phone (e.g., no license).
        UNKNOWN: Unknown account type.
    """

    USER = "user"
    RESOURCE_ACCOUNT = "resourceAccount"
    GUEST = "guest"
    SFB_ON_PREM_USER = "sfbOnPremUser"
    INELIGIBLE_USER = "ineligibleUser"
    UNKNOWN = "unknown"


class TelephoneNumber(BaseModel):
    """A telephone number assigned to a user.

    Attributes:
        telephone_number: The phone number in E.164 format (e.g., "+13235533696").
        assignment_category: Assignment category (e.g., "primary", "alternate").
    """

    model_config = ConfigDict(extra="forbid", populate_by_name=True)

    telephone_number: str = Field(alias="telephoneNumber")
    assignment_category: str = Field(alias="assignmentCategory")


class PolicyAssignmentDetail(BaseModel):
    """Details of a policy assignment to a user.

    Attributes:
        display_name: Human-readable policy name.
        assignment_type: How the policy was assigned (e.g., "direct", "group").
        policy_id: Unique identifier for the policy.
        group_id: Group ID if assigned via group (optional).
    """

    model_config = ConfigDict(extra="forbid", populate_by_name=True)

    display_name: str = Field(alias="displayName")
    assignment_type: str = Field(alias="assignmentType")
    policy_id: str = Field(alias="policyId")
    group_id: Optional[str] = Field(alias="groupId", default=None)


class EffectivePolicyAssignment(BaseModel):
    """An effective policy assignment on a user.

    Represents a single policy type and its assignment details.

    Attributes:
        policy_type: Type of the policy (e.g., "TeamsCallingPolicy", "TenantDialPlan").
        policy_assignment: Details of how the policy is assigned.
    """

    model_config = ConfigDict(extra="forbid", populate_by_name=True)

    policy_type: str = Field(alias="policyType")
    policy_assignment: PolicyAssignmentDetail = Field(alias="policyAssignment")


class UserConfiguration(BaseModel):
    """Teams user configuration from Microsoft Graph API.

    Represents a user's Teams Phone configuration including phone numbers,
    policies, and voice enablement status.

    Attributes:
        id: User's Entra object ID (GUID).
        user_principal_name: User's UPN (email format).
        tenant_id: Microsoft Entra tenant ID.
        display_name: User's display name.
        account_type: Type of user account.
        is_enterprise_voice_enabled: Whether enterprise voice is enabled.
        feature_types: List of enabled features (e.g., "Teams", "CallingPlan").
        telephone_numbers: List of assigned telephone numbers.
        effective_policy_assignments: List of effective policy assignments.
        created_date_time: When the user configuration was created.
        modified_date_time: When the user configuration was last modified.
    """

    model_config = ConfigDict(extra="forbid", populate_by_name=True)

    id: str
    user_principal_name: str = Field(alias="userPrincipalName")
    tenant_id: str = Field(alias="tenantId")
    display_name: Optional[str] = Field(alias="displayName", default=None)
    account_type: AccountType = Field(alias="accountType")
    is_enterprise_voice_enabled: bool = Field(alias="isEnterpriseVoiceEnabled")
    feature_types: list[str] = Field(alias="featureTypes", default=[])
    telephone_numbers: list[TelephoneNumber] = Field(
        alias="telephoneNumbers", default=[]
    )
    effective_policy_assignments: list[EffectivePolicyAssignment] = Field(
        alias="effectivePolicyAssignments", default=[]
    )
    created_date_time: Optional[datetime] = Field(alias="createdDateTime", default=None)
    modified_date_time: Optional[datetime] = Field(
        alias="modifiedDateTime", default=None
    )
