from random import sample
from dostadmin import app_logger
from dostadmin.db_model.user_attributes import UserAttributes
from dostadmin.services.experiment.experiment_service import ExperimentService
from dostadmin.services.user_attributes.user_attribute_service import (
    UserAttributeService,
)
import json

user_attribute_service = UserAttributeService()
experiment_service = ExperimentService()


class GroupAssignment:
    def get_eligible_experience_for_user_attribute_conditions(
        self, experiences_without_group, user_attribute_condition
    ):
        eligible_experiences = []
        user_attribute_dict = {}
        user_attributes = UserAttributes.query.get_all_user_attributes()

        for user_attribute in user_attributes:
            user_id = user_attribute.user_id
            user_attribute_dict[user_id] = user_attribute

        for experience in experiences_without_group:
            try:
                user_id = experience.user_id
                user_attribute = user_attribute_dict[user_id]
                condition_value = json.loads(user_attribute_condition.value)
                conditions_list = condition_value.get("condition")
                if user_attribute_service.is_user_attribute_fulfilling_the_condition(
                    user_attribute, conditions_list
                ):
                    eligible_experiences.append(experience)
            except Exception as error:
                app_logger.error(
                    f"Group Assignment: Exception occurred while fetching attribute for user_id {user_id}. Error message: {error}"
                )
            continue

        return eligible_experiences

    def get_eligible_experience_for_user_percentage_conditions(
        self, experiences, user_percentage_conditions
    ):
        eligible_experiences = []
        num_experiences = len(experiences)
        for index, condition in enumerate(user_percentage_conditions):
            percentage = int(condition.value) / 100
            num_assigned = int(num_experiences * percentage)
            assigned_experiences = sample(experiences, num_assigned)
            remaining_experiences = [
                exp for exp in experiences if exp not in assigned_experiences
            ]
            experiences = remaining_experiences

            for experience in assigned_experiences:
                eligible_experiences.append(
                    {
                        "experience": experience,
                        "experiment_id": condition.experiment_id,
                        "group_name": condition.experiment_group_name,
                    }
                )

            if index == len(user_percentage_conditions) - 1 and remaining_experiences:
                for experience in remaining_experiences:
                    eligible_experiences.append(
                        {
                            "experience": experience,
                            "experiment_id": condition.experiment_id,
                            "group_name": condition.experiment_group_name,
                        }
                    )

        return eligible_experiences
