import json
from channels.generic.websocket import AsyncWebsocketConsumer
from channels.db import database_sync_to_async

from smoothschedule.identity.users.models import User
from .models import Ticket, TicketComment
from .serializers import TicketSerializer, TicketCommentSerializer # Import your serializers


@database_sync_to_async
def get_user_tenant_info(user):
    """Get tenant info from user in a sync context."""
    if hasattr(user, 'tenant') and user.tenant:
        return {
            'has_tenant': True,
            'schema_name': user.tenant.schema_name,
        }
    return {'has_tenant': False, 'schema_name': None}


class BaseConsumer(AsyncWebsocketConsumer):
    async def connect(self):
        print(f"WebSocket Connect: User={self.scope['user']}, Auth={self.scope['user'].is_authenticated}")
        if self.scope["user"].is_authenticated:
            user = self.scope["user"]

            # Get tenant info asynchronously to avoid SynchronousOnlyOperation
            tenant_info = await get_user_tenant_info(user)

            # Add user to a group for their tenant
            if tenant_info['has_tenant']:
                self.tenant_group_name = f'tenant_{tenant_info["schema_name"]}'
                await self.channel_layer.group_add(
                    self.tenant_group_name,
                    self.channel_name
                )

            # Add user to their personal group
            self.user_group_name = f'user_{user.id}'
            await self.channel_layer.group_add(
                self.user_group_name,
                self.channel_name
            )
            await self.accept()
        else:
            await self.close()

    async def disconnect(self, close_code):
        if hasattr(self, 'tenant_group_name'):
            await self.channel_layer.group_discard(
                self.tenant_group_name,
                self.channel_name
            )
        if hasattr(self, 'user_group_name'):
            await self.channel_layer.group_discard(
                self.user_group_name,
                self.channel_name
            )

    async def receive(self, text_data):
        # Consumers are read-only for now, no client-to-server messages expected
        pass

    async def send_json(self, event):
        """Helper to send JSON message to client"""
        await self.send(text_data=json.dumps(event['message']))

class TicketConsumer(BaseConsumer):
    async def connect(self):
        await super().connect()
        if self.scope["user"].is_authenticated:
            # Add user to groups for tickets they are involved with (creator or assignee)
            # This is more complex, might be better handled by signals pushing to user/tenant groups
            pass 

    async def disconnect(self, close_code):
        await super().disconnect(close_code)
        # Clean up any ticket-specific groups if necessary

    async def ticket_message(self, event):
        """Receive message from ticket group and send to WebSocket"""
        await self.send_json(event)

class NotificationConsumer(BaseConsumer):
    async def notification_message(self, event):
        """Receive message from notification group and send to WebSocket"""
        await self.send_json(event)
