from django.http import JsonResponse
from django.shortcuts import redirect
from django.db import transaction
from django.template.response import TemplateResponse
from .models import Room
from .services import get_room_occupancy, get_active_tenants,get_room_tenants
from django.views import View
from paymentlog.models import PaymentLog
from paymentlog.services import generate_electricity_log_instances
import logging

logger = logging.getLogger(__name__)


class RoomDetailsView(View):
    template_name = 'room/room_details.html'
    def get(self, request, room_id):
        room = Room.objects.get(pk=room_id)  # type: ignore
        active_tenants = get_active_tenants(room.id)
        room_tenants = get_room_tenants(room.id)

        context = {
            'room': room,
            'active_tenants': active_tenants,
            'room_tenants': room_tenants
        }
        return TemplateResponse(request, self.template_name, context)


class UpdateElectricityReadingView(View):
    def post(self, request, room_id):
        current_reading = int(request.POST.get('current_electricity_reading', 0))
        with transaction.atomic(): # type: ignore
            # Lock the room object to prevent race conditions
            room = Room.objects.select_for_update().get(pk=room_id) # type: ignore

            electricity_payment_logs = generate_electricity_log_instances(room.pk, current_reading)
            PaymentLog.objects.bulk_create(electricity_payment_logs) # type: ignore

            # update last reading of room
            room.last_electricity_reading = current_reading
            room.save()

        return redirect(f'/room/room/room/{room_id}')



def find_rooms(request):
    hostel_id = request.GET.get('hostel_id')
    single_sharing = request.GET.get('single_sharing') == "yes"

    # Use select_related to optimize the query
    rooms = Room.objects.select_related('hostel').filter(hostel_id=hostel_id) # type: ignore


    data = [{
        "id": room.id,
        "name": f"{room.hostel.name} - Room {room.room_number}",
        "is_available": room.is_bookable
    } for room in rooms]

    data_to_return = []

    if(single_sharing):
        for room in data:
            occupancy = get_room_occupancy(room["id"])
            if occupancy == 0:
                data_to_return.append(room)
    else:
        data_to_return = data

    return JsonResponse(data_to_return, safe=False)


def find_room(request, room_id):
    room = Room.objects.get(pk=room_id) # type: ignore

    data = {
        "id": room.id,
        "name": f"{room.hostel.name} - Room {room.room_number}",
        "is_available": room.is_bookable,
        "last_electricity_reading": room.last_electricity_reading
    }

    return JsonResponse(data, safe=False)
