"""Tests for members app models."""

import pytest
from django.db import IntegrityError

from members.models import Identity, Member

from .factories import IdentityFactory, MemberFactory


@pytest.mark.django_db
class TestMember:
    """Tests for the Member model."""

    def test_create_member(self):
        """Test creating a member with the factory."""
        member = MemberFactory()
        assert member.pk is not None
        assert member.display_name.startswith("Member")
        assert member.workspace is not None

    def test_member_str(self):
        """Test member string representation."""
        member = MemberFactory(display_name="Alice Smith")
        assert str(member) == "Alice Smith"

    def test_member_with_email(self):
        """Test member with email."""
        member = MemberFactory(email="alice@example.com")
        assert member.email == "alice@example.com"

    def test_member_without_email(self):
        """Test member without email."""
        member = MemberFactory(email="")
        assert member.email == ""

    def test_member_with_avatar_url(self):
        """Test member with avatar URL."""
        avatar = "https://avatars.example.com/alice.png"
        member = MemberFactory(avatar_url=avatar)
        assert member.avatar_url == avatar

    def test_member_without_avatar_url(self):
        """Test member without avatar URL."""
        member = MemberFactory(avatar_url="")
        assert member.avatar_url == ""

    def test_member_has_timestamps(self):
        """Test that member has created_at and updated_at."""
        member = MemberFactory()
        assert member.created_at is not None
        assert member.updated_at is not None

    def test_member_belongs_to_workspace(self):
        """Test member belongs to a workspace."""
        member = MemberFactory()
        assert member.workspace is not None
        assert member in member.workspace.members.all()

    def test_member_identities_relationship(self):
        """Test member can have multiple identities."""
        member = MemberFactory()
        IdentityFactory(member=member, provider="github")
        IdentityFactory(member=member, provider="slack")
        assert member.identities.count() == 2


@pytest.mark.django_db
class TestIdentity:
    """Tests for the Identity model."""

    def test_create_identity(self):
        """Test creating an identity with the factory."""
        identity = IdentityFactory()
        assert identity.pk is not None
        assert identity.provider is not None
        assert identity.member is not None

    def test_identity_str(self):
        """Test identity string representation."""
        identity = IdentityFactory(provider="github", handle="alice")
        assert str(identity) == "github:alice"

    def test_identity_provider_choices(self):
        """Test identity with different provider choices."""
        providers = [
            "slack",
            "discord",
            "github",
            "discourse",
            "twitter",
            "linkedin",
            "mastodon",
        ]
        for provider in providers:
            identity = IdentityFactory(provider=provider)
            assert identity.provider == provider

    def test_identity_unique_provider_external_id(self):
        """Test that provider + external_id must be unique."""
        IdentityFactory(provider="github", external_id="user-123")
        with pytest.raises(IntegrityError):
            IdentityFactory(provider="github", external_id="user-123")

    def test_identity_same_external_id_different_provider(self):
        """Test same external_id with different provider is allowed."""
        IdentityFactory(provider="github", external_id="123")
        identity2 = IdentityFactory(provider="slack", external_id="123")
        assert identity2.pk is not None

    def test_identity_has_timestamps(self):
        """Test that identity has created_at and updated_at."""
        identity = IdentityFactory()
        assert identity.created_at is not None
        assert identity.updated_at is not None

    def test_identity_belongs_to_member(self):
        """Test identity belongs to a member."""
        identity = IdentityFactory()
        assert identity.member is not None
        assert identity in identity.member.identities.all()

    def test_identity_deletion_cascades_from_member(self):
        """Test identity is deleted when member is deleted."""
        identity = IdentityFactory()
        member_id = identity.member.id
        identity_id = identity.id

        identity.member.delete()

        assert not Member.objects.filter(id=member_id).exists()
        assert not Identity.objects.filter(id=identity_id).exists()
