from django.core.management.base import BaseCommand

from api.models import TtStaff, TtLocation, TtStudentSet, TtActivityTemplate
from api.utils import convert_to_redis_week, bulk_sync_to_redis
from backend.redis_client import redis_client

class Command(BaseCommand):
    def handle(self, *args, **options):
        redis_data={
            "insert":{},
            "update":{},
        }
        redis_staff_table = "staff"
        redis_location_table = "location"
        redis_student_set_table = "student_set"

        # update staff allocated_activity_ids
        staffs = TtStaff.objects.all().prefetch_related("ttactivity_set")
        for staff in staffs:
            activity_set = staff.ttactivity_set.all()
            activity_ids = []
            for activity in activity_set:
                activity_ids.append(activity.id)

            redis_data["update"].setdefault(redis_staff_table, []).append({
                "id": staff.id,
                "allocated_activity_ids": activity_ids,
            })

        # update location allocated_activity_ids
        locations = TtLocation.objects.all().prefetch_related("ttactivity_set")
        for location in locations:
            activity_set = location.ttactivity_set.all()
            activity_ids = []
            for activity in activity_set:
                activity_ids.append(activity.id)

            redis_data["update"].setdefault(redis_location_table, []).append({
                "id": location.id,
                "allocated_activity_ids": activity_ids,
            })

        # update student_set allocated_activity_ids
        student_sets = TtStudentSet.objects.all().prefetch_related("activity")
        for student_set in student_sets:
            activity_set = student_set.activity.all()
            activity_ids = []
            for activity in activity_set:
                activity_ids.append(activity.id)

            redis_data["update"].setdefault(redis_student_set_table, []).append({
                "id": student_set.id,
                "allocated_activity_ids": activity_ids,
            })

        # insert all template into redis
        redis_activity_template_table = "activity_template"
        redis_activity_template_column = [
            "id", "code", "name", "desc", "planned_size", "slot_required", "activity_type_id", "duration",
            "department_id", "module_id", "academic_term_id",
            "week_pattern_id", "week_pattern", "availability_id", "availability_pattern",
            "start_preference_id", "start_preference_pattern", "usage_preference_id", "usage_preference_pattern",
            "staff_requirement_type", "staff_required_no", "staff_preset", "staff_suitability_id",
            "location_requirement_type", "location_required_no", "location_preset", "location_suitability_id", "status"
        ]
        activity_templates = (
            TtActivityTemplate.objects.all()
            .prefetch_related(
                "week",
                "location",
                "location_suitability",
                "staff",
                "staff_suitability",
            )
        )
        for activity_template in activity_templates:
            week_ids = list(template_week.id for template_week in activity_template.week.all() )
            week_pattern_for_redis = convert_to_redis_week(week_ids)
            redis_activity_template_data = {}
            for column in redis_activity_template_column:
                match column:
                    case "week_pattern":
                        redis_activity_template_data[column] = week_pattern_for_redis
                    case "staff_suitability_id":
                        suitability_list = list(activity_template.staff_suitability.all())
                        redis_activity_template_data[column] = suitability_list[0].id if suitability_list else None
                    case "location_suitability_id":
                        suitability_list = list(activity_template.location_suitability.all())
                        redis_activity_template_data[column] = suitability_list[0].id if suitability_list else None
                    case "staff_preset":
                        redis_activity_template_data[column] = [s.id for s in activity_template.staff.all()]
                    case "location_preset":
                        redis_activity_template_data[column] = [l.id for l in activity_template.location.all()]
                    case "staff_required_no":
                        redis_activity_template_data[column] = activity_template.staff_requirement
                    case "location_required_no":
                        redis_activity_template_data[column] = activity_template.location_requirement
                    case "usage_preference_id" | "availability_id" | "start_preference_id" | "week_pattern_id":
                        # jose request if no id, dun store null, want to store "0"
                        value = getattr(activity_template, column)
                        redis_activity_template_data[column] = 0 if value in (None, "") else value
                    case _:
                        redis_activity_template_data[column] = getattr(activity_template, column)
            redis_data["insert"].setdefault(redis_activity_template_table, []).append(redis_activity_template_data)

        bulk_sync_to_redis(redis_client, redis_data)




