import json
from django.db import models
from django.conf import settings

from api.translation import __


class UserSchedulingPreference(models.Model):
    id = models.BigAutoField(primary_key=True)
    user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE,related_name="scheduling_preference")
    type = models.CharField(max_length=200)
    preference = models.SmallIntegerField(default=5)
    status = models.SmallIntegerField()

    STATUS_TO_CODE = {
        "active": 1,
        "inactive": 2,
    }
    # preference can be select, default as 5
    PREFERENCE = {1,2,3,4,5,6,7,8,9}

    TYPE = {
        'activity_preferred_start',
        'activity_preferred_usage',
        'module_preferred_start',
        'module_preferred_usage',
        'staff_preferred_start',
        'staff_preferred_usage',
        'staff_minimize_travelling',
        'location_preferred_start',
        'location_preferred_usage',
        'location_minimize_travelling',
        'location_best_fit',
        'student_set_preferred_start',
        'student_set_preferred_usage',
        'student_set_minimize_travelling',
    }

    # group for FE, so FE no need hardcode to group it
    TYPE_GROUP = {
        "activity": [
            'activity_preferred_start',
            'activity_preferred_usage',
        ],
        "module": [
            'module_preferred_start',
            'module_preferred_usage',
        ],
        "staff": [
            'staff_preferred_start',
            'staff_preferred_usage',
            'staff_minimize_travelling',
        ],
        "location": [
            'location_preferred_start',
            'location_preferred_usage',
            'location_minimize_travelling',
            'location_best_fit',
        ],
        "student_set": [
            'student_set_preferred_start',
            'student_set_preferred_usage',
            'student_set_minimize_travelling',
        ],
    }

    class Meta:
        db_table = "user_scheduling_preference"
        constraints = [
            models.UniqueConstraint(fields=["user", "type"], name="preference_unique_user_type")
        ]

    @staticmethod
    def get_setting(user_id):
        """
        wont store all settings to this table, so when user start adjust only will store the setting, else will used default
        """
        setting = {
            val: {
                "id": val,
                "name":__("attr."+val),
                "status": UserSchedulingPreference.STATUS_TO_CODE['active'],
                "preference": 5,
            }
            for val in UserSchedulingPreference.TYPE
        }

        custom_setting = UserSchedulingPreference.objects.filter(user_id=user_id).values_list('type', 'preference','status')
        # merge default_setting with custom setting
        for type, preference, status in custom_setting:
            if type in setting:
                setting[type]["preference"] = preference
                setting[type]["status"] = status

        return list(setting.values())

    @staticmethod
    def group_settings_data(settings_list):
        """
        @param settings_list: result from get_setting
        Format the data for FE
        """
        # 1. Convert the flat list into a quick lookup dictionary: {id: setting_dict}
        settings_lookup = {item["id"]: item for item in settings_list}

        # 2. Build the new structured dictionary
        grouped_result = {}

        for group_name, type_list in UserSchedulingPreference.TYPE_GROUP.items():
            # Build the wrapper structure for this group
            grouped_result[group_name] = {
                "name": __("attr." + group_name),  # Translates the group title (e.g., "group.avoid_double_booking")
                "type": []
            }

            # Populate the "type" array with matching settings objects
            for type_key in type_list:
                if type_key in settings_lookup:
                    grouped_result[group_name]["type"].append(settings_lookup[type_key])

        return list(grouped_result.values())

    @staticmethod
    def get_rules():
        rules = {
            "preference": UserSchedulingPreference.PREFERENCE,
            "status": [
                {
                    "id": val,
                    "name": __(f"attr.user_scheduling_preference_status_name.{val}")
                }
                for key, val in UserSchedulingPreference.STATUS_TO_CODE.items()
            ],
        }
        return rules

    @staticmethod
    def kafka_group_settings_data(settings_list):
        """
        @param settings_list: result from get_setting
        Format the data for Kafka
        """
        grouped_result = {
            item["id"]: item["preference"]
            for item in settings_list
            if item.get("status") == UserSchedulingPreference.STATUS_TO_CODE["active"]
        }
        return grouped_result
