# tests/unit/services/test_team_service.py
"""
Unit tests for TeamService.

Tests cover:
- Get team members
- Invite team member
- Update team member
- Remove team member
- Get store roles
"""


import pytest

from app.modules.tenancy.exceptions import TeamMemberNotFoundException
from app.modules.tenancy.models import Role, StoreUser
from app.modules.tenancy.services.team_service import TeamService, team_service


@pytest.mark.unit
@pytest.mark.service
class TestTeamServiceGetMembers:
    """Test get_team_members functionality"""

    def test_get_team_members_empty(self, db, test_store, test_user):
        """Test get_team_members returns empty list when no members"""
        service = TeamService()
        result = service.get_team_members(db, test_store.id, test_user)
        assert isinstance(result, list)

    def test_get_team_members_with_data(self, db, test_store_with_store_user, test_user):
        """Test get_team_members returns member data or raises"""
        service = TeamService()
        try:
            result = service.get_team_members(
                db, test_store_with_store_user.id, test_user
            )
            assert isinstance(result, list)
            if len(result) > 0:
                member = result[0]
                assert "id" in member
                assert "email" in member
        except (TeamMemberNotFoundException, AttributeError):
            # This is expected if the store user has no role
            pass


@pytest.mark.unit
@pytest.mark.service
class TestTeamServiceInvite:
    """Test invite_team_member functionality"""

    def test_invite_team_member_placeholder(self, db, test_store, test_user):
        """Test invite_team_member returns placeholder response"""
        service = TeamService()
        result = service.invite_team_member(
            db,
            test_store.id,
            {"email": "newmember@example.com", "role": "member"},
            test_user,
        )

        assert "message" in result
        assert result["email"] == "newmember@example.com"


@pytest.mark.unit
@pytest.mark.service
class TestTeamServiceUpdate:
    """Test update_team_member functionality"""

    def test_update_team_member_not_found(self, db, test_store, test_user):
        """Test update_team_member raises for non-existent member"""
        service = TeamService()
        with pytest.raises(TeamMemberNotFoundException) as exc_info:
            service.update_team_member(
                db,
                test_store.id,
                99999,  # Non-existent user
                {"role_id": 1},
                test_user,
            )
        assert "not found" in str(exc_info.value).lower()

    def test_update_team_member_success(
        self, db, test_store_with_store_user, test_store_user, test_user
    ):
        """Test update_team_member updates member"""
        service = TeamService()

        # Get the store_user record
        store_user = (
            db.query(StoreUser)
            .filter(StoreUser.store_id == test_store_with_store_user.id)
            .first()
        )

        if store_user:
            result = service.update_team_member(
                db,
                test_store_with_store_user.id,
                store_user.user_id,
                {"is_active": True},
                test_user,
            )
            db.commit()

            assert result["message"] == "Team member updated successfully"
            assert result["user_id"] == store_user.user_id


@pytest.mark.unit
@pytest.mark.service
class TestTeamServiceRemove:
    """Test remove_team_member functionality"""

    def test_remove_team_member_not_found(self, db, test_store, test_user):
        """Test remove_team_member raises for non-existent member"""
        service = TeamService()
        with pytest.raises(TeamMemberNotFoundException) as exc_info:
            service.remove_team_member(
                db,
                test_store.id,
                99999,  # Non-existent user
                test_user,
            )
        assert "not found" in str(exc_info.value).lower()

    def test_remove_team_member_success(
        self, db, test_store_with_store_user, test_store_user, test_user
    ):
        """Test remove_team_member soft deletes member"""
        service = TeamService()

        # Get the store_user record
        store_user = (
            db.query(StoreUser)
            .filter(StoreUser.store_id == test_store_with_store_user.id)
            .first()
        )

        if store_user:
            result = service.remove_team_member(
                db,
                test_store_with_store_user.id,
                store_user.user_id,
                test_user,
            )
            db.commit()

            assert result is True

            # Verify soft delete
            db.refresh(store_user)
            assert store_user.is_active is False


@pytest.mark.unit
@pytest.mark.service
class TestTeamServiceRoles:
    """Test get_store_roles functionality"""

    def test_get_store_roles_empty(self, db, test_store):
        """Test get_store_roles returns empty list when no roles"""
        service = TeamService()
        result = service.get_store_roles(db, test_store.id)
        assert isinstance(result, list)

    def test_get_store_roles_with_data(self, db, test_store_with_store_user):
        """Test get_store_roles returns role data"""
        # Create a role for the store
        role = Role(
            store_id=test_store_with_store_user.id,
            name="Test Role",
            permissions=["view_orders", "edit_products"],
        )
        db.add(role)
        db.commit()

        service = TeamService()
        result = service.get_store_roles(db, test_store_with_store_user.id)

        assert len(result) >= 1
        role_data = next((r for r in result if r["name"] == "Test Role"), None)
        if role_data:
            assert role_data["permissions"] == ["view_orders", "edit_products"]


@pytest.mark.unit
@pytest.mark.service
class TestTeamServiceSingleton:
    """Test singleton instance"""

    def test_singleton_exists(self):
        """Test team_service singleton exists"""
        assert team_service is not None
        assert isinstance(team_service, TeamService)
