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

class DeliveryTrackingConsumer(AsyncJsonWebsocketConsumer):
    async def connect(self):
        self.booking_id = self.scope['url_route']['kwargs']['booking_id']
        self.room_group_name = f'delivery_tracking_{self.booking_id}'

        # Join room group
        await self.channel_layer.group_add(
            self.room_group_name,
            self.channel_name
        )

        await self.accept()

    async def disconnect(self, close_code):
        # Leave room group
        await self.channel_layer.group_discard(
            self.room_group_name,
            self.channel_name
        )

    # Receive message from WebSocket
    async def receive_json(self, content):
        # Can handle messages received from websocket and broadcast them
        await self.channel_layer.group_send(
            self.room_group_name,
            {
                'type': 'delivery_message',
                'message': content
            }
        )

    # Receive message from room group
    async def delivery_message(self, event):
        # Send message to WebSocket
        await self.send_json(event['message'])

    # Handle location update type events
    async def location_update(self, event):
        await self.send_json({
            'type': 'location_update',
            'latitude': event.get('latitude'),
            'longitude': event.get('longitude')
        })

class OrderPaymentStatusConsumer(AsyncJsonWebsocketConsumer):
    async def connect(self):
        self.booking_id = self.scope['url_route']['kwargs']['booking_id']
        self.room_group_name = f'payment_status_{self.booking_id}'

        # Join room group
        await self.channel_layer.group_add(
            self.room_group_name,
            self.channel_name
        )

        await self.accept()

    async def disconnect(self, close_code):
        # Leave room group
        await self.channel_layer.group_discard(
            self.room_group_name,
            self.channel_name
        )

    # Receive message from room group
    async def payment_status_update(self, event):
        # Send message to WebSocket
        await self.send_json({
            'type': 'payment_status_update',
            'payment_status': event.get('payment_status'),
            'booking_id': event.get('booking_id')
        })

class LiveOrdersConsumer(AsyncJsonWebsocketConsumer):
    async def connect(self):
        self.room_group_name = 'live_orders'
        await self.channel_layer.group_add(
            self.room_group_name,
            self.channel_name
        )
        await self.accept()

    async def disconnect(self, close_code):
        await self.channel_layer.group_discard(
            self.room_group_name,
            self.channel_name
        )

    async def receive_json(self, content):
        """
        Inbound frames pushed by Aahar's WsClient (one-shot frames):
          - order.status_update   live KOT status -> update AaharOrderSync + Booking
          - order.from_restaurant / order.running_update  full order snapshots
        Then rebroadcast to any connected HotelFinder dashboards.
        """
        event_type = content.get('type')
        if event_type == 'order.status_update':
            order_id = content.get('order_id')
            new_status = content.get('status')
            if order_id and new_status:
                from .views import apply_aahar_order_status
                await database_sync_to_async(apply_aahar_order_status)(order_id, new_status)

        # Rebroadcast raw event to HotelFinder dashboards listening on this group.
        await self.channel_layer.group_send(
            self.room_group_name,
            {"type": "new_order", "payload": content}
        )

    async def new_order(self, event):
        await self.send_json(event)
