from datetime import date

from django.core.management.base import BaseCommand
from django.db import transaction, connection

from api.models import TtStaff, TtLocation, TtStudentSet, TtActivityTemplate, TtActivity, TtModule, TtAcademicTerm, \
    TtActivityTemplateWeek, TtSetting
from api.utils import convert_to_redis_week, bulk_sync_to_redis, recalculate_resource_map, get_resource_map_redis_data
from backend.redis_client import redis_client

class Command(BaseCommand):
    def handle(self, *args, **options):
        setting_params = {
            "slot_per_week",
            "minute_per_slot",
        }
        settings = TtSetting.get_multiple_setting(setting_params)
        slot_per_week = int(settings["slot_per_week"])

        academic_term_code = 65
        academic_term = TtAcademicTerm.objects.filter(code=academic_term_code).prefetch_related("week").first()
        if academic_term:
            week_pattern = list(academic_term.week.values_list("id", flat=True))

            staff_ids = set()
            location_ids = set()
            student_set_ids = set()

            staff_with_affected_week = {}
            location_with_affected_week = {}
            student_set_with_affected_week = {}

            staffs = TtStaff.objects.all()
            locations = TtLocation.objects.all()
            student_sets = TtStudentSet.objects.filter(academic_term_id=academic_term.id)

            staff_count = 0
            location_count = 0
            student_set_count = 0
            for staff in staffs:
                if staff.id not in staff_with_affected_week:
                    staff_count += 1
                    staff_with_affected_week[staff.id] = set()
                staff_with_affected_week[staff.id].update(week_pattern)
                staff_ids.add(staff.id)

            for location in locations:
                if location.id not in location_with_affected_week:
                    location_count += 1
                    location_with_affected_week[location.id] = set()
                location_with_affected_week[location.id].update(week_pattern)
                location_ids.add(location.id)

            for student_set in student_sets:
                if student_set.id not in student_set_with_affected_week:
                    student_set_count += 1
                    student_set_with_affected_week[student_set.id] = set()
                student_set_with_affected_week[student_set.id].update(week_pattern)
                student_set_ids.add(student_set.id)

            # Filter out entries with empty sets to prevent passing {id: []} to the function
            staff_with_affected_week = {k: v for k, v in staff_with_affected_week.items() if v}
            location_with_affected_week = {k: v for k, v in location_with_affected_week.items() if v}
            student_set_with_affected_week = {k: v for k, v in student_set_with_affected_week.items() if v}

            redis_staff_table = "staff"
            redis_location_table = "location"
            redis_student_set_table = "student_set"
            redis_data = {
                "update": {}
            }
            # recalculate resource map for affected_week
            if staff_with_affected_week:
                recalculate_resource_map("staff",staff_with_affected_week,slot_per_week)
                redis_data["update"][redis_staff_table] = get_resource_map_redis_data("staff",staff_ids)
            print("staff:"+str(staff_count))
            if location_with_affected_week:
                recalculate_resource_map("location",location_with_affected_week,slot_per_week)
                redis_data["update"][redis_location_table] = get_resource_map_redis_data("location",location_ids)
            print("location:"+str(location_count))
            if student_set_with_affected_week:
                recalculate_resource_map("student_set",student_set_with_affected_week,slot_per_week)
                redis_data["update"][redis_student_set_table] = get_resource_map_redis_data("student_set",student_set_ids)
            print("student_set:"+str(student_set_count))

            bulk_sync_to_redis(redis_client, redis_data)
