"""
Chat & File Service Tests — Pytest Configuration.
"""
import uuid

import pytest
from rest_framework.test import APIClient
from django.contrib.auth import get_user_model

from apps.core.tenant.models import Tenant, Domain
from apps.services.chat.models import (
    Channel,
    ChannelMember,
    Message,
    UserPresence,
    ChannelType,
    ChannelVisibility,
    MemberRole,
    MemberStatus,
    MessageType,
)

User = get_user_model()


# ══════════════════════════════════════════════════════════════
# Core Fixtures
# ══════════════════════════════════════════════════════════════

@pytest.fixture
def tenant(db):
    """Get or create the public tenant for tests."""
    tenant = Tenant.objects.filter(schema_name='public').first()
    if not tenant:
        tenant = Tenant.objects.create(
            name='Public',
            slug='public',
            schema_name='public',
        )
        Domain.objects.get_or_create(
            domain='localhost',
            defaults={'tenant': tenant, 'is_primary': True},
        )
    return tenant


@pytest.fixture
def user(db, tenant):
    """Create a test user (owner of channels)."""
    email = f'chatuser_{uuid.uuid4().hex[:8]}@example.com'
    return User.objects.create_user(
        email=email,
        password='testpass123',
        tenant=tenant,
        first_name='علی',
        last_name='محمدی',
    )


@pytest.fixture
def other_user(db, tenant):
    """Create a second test user."""
    email = f'chatother_{uuid.uuid4().hex[:8]}@example.com'
    return User.objects.create_user(
        email=email,
        password='testpass123',
        tenant=tenant,
        first_name='سارا',
        last_name='احمدی',
    )


@pytest.fixture
def third_user(db, tenant):
    """Create a third test user."""
    email = f'chatthird_{uuid.uuid4().hex[:8]}@example.com'
    return User.objects.create_user(
        email=email,
        password='testpass123',
        tenant=tenant,
        first_name='رضا',
        last_name='حسینی',
    )


@pytest.fixture
def api_client():
    """Create an unauthenticated API client."""
    return APIClient()


@pytest.fixture
def authenticated_client(api_client, user):
    """Create an authenticated API client for the primary user."""
    api_client.force_authenticate(user=user)
    return api_client


@pytest.fixture
def other_authenticated_client(other_user):
    """Create an authenticated API client for the secondary user."""
    client = APIClient()
    client.force_authenticate(user=other_user)
    return client


# ══════════════════════════════════════════════════════════════
# Chat Fixtures
# ══════════════════════════════════════════════════════════════

@pytest.fixture
def group_channel(db, tenant, user):
    """Create a group channel owned by the primary user."""
    channel = Channel.objects.create(
        tenant=tenant,
        name='تیم توسعه',
        slug=f'dev-team-{uuid.uuid4().hex[:6]}',
        channel_type=ChannelType.GROUP,
        visibility=ChannelVisibility.PRIVATE,
        created_by=user,
    )
    ChannelMember.objects.create(
        tenant=tenant,
        channel=channel,
        user=user,
        role=MemberRole.OWNER,
        status=MemberStatus.ACTIVE,
    )
    return channel


@pytest.fixture
def public_channel(db, tenant, user):
    """Create a public channel."""
    channel = Channel.objects.create(
        tenant=tenant,
        name='اطلاعیه‌ها',
        slug=f'announcements-{uuid.uuid4().hex[:6]}',
        channel_type=ChannelType.PUBLIC,
        visibility=ChannelVisibility.PUBLIC,
        created_by=user,
    )
    ChannelMember.objects.create(
        tenant=tenant,
        channel=channel,
        user=user,
        role=MemberRole.OWNER,
        status=MemberStatus.ACTIVE,
    )
    return channel


@pytest.fixture
def direct_channel(db, tenant, user, other_user):
    """Create a direct-message channel between user and other_user."""
    channel = Channel.objects.create(
        tenant=tenant,
        name=f'{user.first_name} - {other_user.first_name}',
        slug=f'dm-{uuid.uuid4().hex[:6]}',
        channel_type=ChannelType.DIRECT,
        visibility=ChannelVisibility.PRIVATE,
        created_by=user,
        max_members=2,
    )
    ChannelMember.objects.create(
        tenant=tenant,
        channel=channel,
        user=user,
        role=MemberRole.MEMBER,
        status=MemberStatus.ACTIVE,
    )
    ChannelMember.objects.create(
        tenant=tenant,
        channel=channel,
        user=other_user,
        role=MemberRole.MEMBER,
        status=MemberStatus.ACTIVE,
    )
    return channel


@pytest.fixture
def channel_with_other_member(group_channel, tenant, other_user):
    """Group channel that includes the other_user as member."""
    ChannelMember.objects.create(
        tenant=tenant,
        channel=group_channel,
        user=other_user,
        role=MemberRole.MEMBER,
        status=MemberStatus.ACTIVE,
    )
    return group_channel


@pytest.fixture
def message(db, tenant, group_channel, user):
    """Create a text message in the group channel."""
    return Message.objects.create(
        tenant=tenant,
        channel=group_channel,
        sender=user,
        message_type=MessageType.TEXT,
        content='سلام! این یک پیام تست است.',
    )


@pytest.fixture
def multiple_messages(db, tenant, group_channel, user, other_user):
    """Create several messages for pagination testing."""
    channel_with_members = group_channel
    # Ensure other_user is a member
    ChannelMember.objects.get_or_create(
        tenant=tenant,
        channel=channel_with_members,
        user=other_user,
        defaults={
            'role': MemberRole.MEMBER,
            'status': MemberStatus.ACTIVE,
        },
    )
    msgs = []
    for i in range(15):
        sender = user if i % 2 == 0 else other_user
        msgs.append(
            Message.objects.create(
                tenant=tenant,
                channel=channel_with_members,
                sender=sender,
                message_type=MessageType.TEXT,
                content=f'پیام شماره {i + 1}',
            )
        )
    return msgs
