"""Workspace + membership repositories.

Listing workspaces for a user goes through their memberships, so a user can only
ever see workspaces they belong to.
"""

from __future__ import annotations

import uuid

from sqlalchemy import select
from sqlalchemy.orm import Session

from legate.db.models.membership import Membership
from legate.db.models.workspace import Workspace
from legate.policy.roles import Role


def get_by_id(db: Session, workspace_id: uuid.UUID) -> Workspace | None:
    return db.get(Workspace, workspace_id)


def get_by_slug(db: Session, slug: str) -> Workspace | None:
    return db.scalars(select(Workspace).where(Workspace.slug == slug)).first()


def create(db: Session, *, name: str, slug: str, plan: str = "free") -> Workspace:
    workspace = Workspace(name=name, slug=slug, plan=plan, settings_json={})
    db.add(workspace)
    db.flush()
    return workspace


def list_for_user(db: Session, user_id: uuid.UUID) -> list[Workspace]:
    return list(
        db.scalars(
            select(Workspace)
            .join(Membership, Membership.workspace_id == Workspace.id)
            .where(Membership.user_id == user_id)
            .order_by(Workspace.created_at.asc())
        ).all()
    )


def add_member(
    db: Session,
    *,
    user_id: uuid.UUID,
    workspace_id: uuid.UUID,
    role: Role,
) -> Membership:
    membership = Membership(user_id=user_id, workspace_id=workspace_id, role=role)
    db.add(membership)
    db.flush()
    return membership


def get_membership(
    db: Session, *, user_id: uuid.UUID, workspace_id: uuid.UUID
) -> Membership | None:
    return db.scalars(
        select(Membership).where(
            Membership.user_id == user_id,
            Membership.workspace_id == workspace_id,
        )
    ).first()


def get_membership_by_id(
    db: Session, *, membership_id: uuid.UUID, workspace_id: uuid.UUID
) -> Membership | None:
    """Tenant-scoped fetch: a membership is only visible from within its workspace."""
    return db.scalars(
        select(Membership).where(
            Membership.id == membership_id,
            Membership.workspace_id == workspace_id,
        )
    ).first()


def list_members(db: Session, *, workspace_id: uuid.UUID) -> list[Membership]:
    return list(
        db.scalars(
            select(Membership)
            .where(Membership.workspace_id == workspace_id)
            .order_by(Membership.created_at.asc())
        ).all()
    )
