"""User and workspace context for operations."""

from __future__ import annotations

from dataclasses import dataclass
from uuid import UUID

from noteflow.domain.identity.roles import ProjectRole, WorkspaceRole


@dataclass(frozen=True)
class UserContext:
    """Current user context for an operation.

    Represent the authenticated user making a request.
    In local-first mode, this is the default local user.
    """

    user_id: UUID
    display_name: str
    email: str | None = None


@dataclass(frozen=True)
class WorkspaceContext:
    """Current workspace context for an operation.

    Represent the active workspace for resource scoping.
    In local-first mode, this is the default Personal workspace.
    """

    workspace_id: UUID
    workspace_name: str
    role: WorkspaceRole


@dataclass(frozen=True)
class ProjectContext:
    """Represent project context for an operation with role-based access.

    Represent a project within a workspace for finer-grained scoping
    and access control.

    Attributes:
        project_id: The project identifier.
        project_name: Human-readable project name.
        role: The user's role in this project.
    """

    project_id: UUID
    project_name: str
    role: ProjectRole


@dataclass(frozen=True)
class OperationContext:
    """Full context for an operation.

    Combine user identity, workspace scope, and optional project scope
    into a single context object for use across the application.
    """

    user: UserContext
    workspace: WorkspaceContext
    project: ProjectContext | None = None
    request_id: str | None = None

    @property
    def user_id(self) -> UUID:
        """Get the current user's ID."""
        return self.user.user_id

    @property
    def workspace_id(self) -> UUID:
        """Get the current workspace's ID."""
        return self.workspace.workspace_id

    @property
    def project_id(self) -> UUID | None:
        """Get the current project's ID if set."""
        return self.project.project_id if self.project else None

    def can_write(self) -> bool:
        """Check if user can write in current workspace."""
        return self.workspace.role.can_write()

    def is_admin(self) -> bool:
        """Check if user is admin/owner of current workspace."""
        return self.workspace.role.can_admin()

    def can_read_project(self) -> bool:
        """Check if user can read in current project.

        Workspace admin can always read. Otherwise requires project role.

        Returns:
            True if user has read access to the project.
        """
        if self.workspace.role.can_admin():
            return True
        return self.project.role.can_read() if self.project else False

    def can_write_project(self) -> bool:
        """Check if user can write in current project.

        Workspace admin can always write. Otherwise requires editor/admin role.

        Returns:
            True if user has write access to the project.
        """
        if self.workspace.role.can_admin():
            return True
        return self.project.role.can_write() if self.project else False

    def can_admin_project(self) -> bool:
        """Check if user can admin current project.

        Workspace admin is always project admin.

        Returns:
            True if user has admin access to the project.
        """
        if self.workspace.role.can_admin():
            return True
        return self.project.role.can_admin() if self.project else False
