import uuid
from enum import Enum

from sqlalchemy import String, Boolean, ForeignKey, Enum as SQLEnum, UniqueConstraint
from sqlalchemy.orm import Mapped, mapped_column, relationship
from typing import TYPE_CHECKING

if TYPE_CHECKING:
    from domains.users.models import User

from db.base import Base

class GroupType(str, Enum):
    PUBLIC = "public"
    PRIVATE = "private"

class GroupMemberRole(str, Enum):
    MANAGER = "manager"
    MEMBER = "member"

class Group(Base):
    __tablename__ = "groups" # type: ignore

    name: Mapped[str] = mapped_column(
        String(100),
        nullable=False,
        index=True
    )

    type: Mapped[GroupType] = mapped_column(
        SQLEnum(GroupType, name="group_type"),
        default=GroupType.PUBLIC,
        nullable=False
    )

    is_active: Mapped[bool] = mapped_column(
        Boolean,
        default=True,
        index=True
    )
    
    owner_id: Mapped[uuid.UUID] = mapped_column(
        ForeignKey("users.id", ondelete="CASCADE"),
        nullable=False,
        index=True
    )

    # Relationship to members
    members: Mapped[list["GroupMember"]] = relationship(back_populates="group", cascade="all, delete-orphan")


class GroupMember(Base):
    __tablename__ = "group_members" # type: ignore
    __table_args__ = (
        UniqueConstraint("user_id", "group_id", name="uq_group_member"),
    )

    user_id: Mapped[uuid.UUID] = mapped_column(
        ForeignKey("users.id", ondelete="CASCADE"),
        index=True
    )

    group_id: Mapped[uuid.UUID] = mapped_column(
        ForeignKey("groups.id", ondelete="CASCADE"),
        index=True
    )

    role: Mapped[GroupMemberRole] = mapped_column(
        SQLEnum(GroupMemberRole, name="group_member_role"),
        default=GroupMemberRole.MEMBER,
        nullable=False
    )

    # Relationships
    group: Mapped["Group"] = relationship(back_populates="members")
    user: Mapped["User"] = relationship()
