class Hybrid001AlphaRecommender(BaseRecommender):
    """Hybrid001AlphaRecommender recommender"""

    RECOMMENDER_NAME = "Hybrid001AlphaRecommender"

    def __init__(self, URM_train, UCM, cold_users, warm_users):
        super(Hybrid001AlphaRecommender, self).__init__(URM_train)
        self.warm_recommender = ItemKNNCFRecommender(URM_train)
        self.cold_recommender = UserKNNCBFRecommender(UCM, URM_train)
        self.cold_users = cold_users
        self.warm_users = warm_users

    def fit(self):
        self.warm_recommender.fit(topK=12, shrink=16)
        self.cold_recommender.fit(topK=11000, shrink=2)

    def recommend(self,
                  user_id_array,
                  cutoff=None,
                  remove_seen_flag=True,
                  items_to_compute=None,
                  remove_top_pop_flag=False,
                  remove_CustomItems_flag=False,
                  return_scores=False):
        if user_id_array in self.warm_users:
            return self.warm_recommender.recommend(user_id_array,
                                                   cutoff=cutoff)
        if user_id_array in self.cold_users:
            return self.cold_recommender.recommend(user_id_array,
                                                   cutoff=cutoff)
class Hybrid003AlphaRecommender(BaseRecommender):
    """Hybrid003AlphaRecommender recommender"""

    RECOMMENDER_NAME = "Hybrid003AlphaRecommender"

    def __init__(self, data: DataObject):
        super(Hybrid003AlphaRecommender, self).__init__(data.urm_train)
        self.data = data
        self.poco_warm_recommender = Hybrid101AlphaRecommender(data)
        self.quasi_warm_recommender = Hybrid102AlphaRecommender(data)
        # self.warm_recommender = ItemKNNCFRecommender(data.urm_train)
        # self.warm_recommender = Hybrid105AlphaRecommender(data)
        self.warm_recommender = RP3betaRecommender(data.urm_train)
        self.warm_7_recommender = ItemKNNCFRecommender(data.urm_train)
        self.warm_8_recommender = Hybrid108AlphaRecommender(data)
        self.warm_9_recommender = Hybrid109AlphaRecommender(data)
        self.cold_recommender = Hybrid100AlphaRecommender(data)

    def fit(self):
        self.cold_recommender.fit()
        self.poco_warm_recommender.fit()
        self.quasi_warm_recommender.fit()
        # self.warm_recommender.fit(topK=30, shrink=30, feature_weighting="none", similarity="jaccard")
        self.warm_recommender.fit(topK=20, alpha=0.16, beta=0.24)
        self.warm_7_recommender.fit(topK=12,
                                    shrink=15,
                                    feature_weighting="none",
                                    similarity="jaccard")
        self.warm_8_recommender.fit()
        self.warm_9_recommender.fit()

    def recommend(self,
                  user_id_array,
                  cutoff=None,
                  remove_seen_flag=True,
                  items_to_compute=None,
                  remove_top_pop_flag=False,
                  remove_CustomItems_flag=False,
                  return_scores=False):
        if user_id_array in self.data.ids_ultra_cold_users:
            return self.cold_recommender.recommend(user_id_array,
                                                   cutoff=cutoff)
        elif user_id_array in self.data.urm_train_users_by_type[0][1]:
            return self.cold_recommender.recommend(user_id_array,
                                                   cutoff=cutoff)
        elif user_id_array in self.data.urm_train_users_by_type[1][1]:
            return self.poco_warm_recommender.recommend(user_id_array,
                                                        cutoff=cutoff)
        elif user_id_array in self.data.urm_train_users_by_type[2][1]:
            return self.quasi_warm_recommender.recommend(user_id_array,
                                                         cutoff=cutoff)
        elif user_id_array in self.data.urm_train_users_by_type[3][1]:
            return self.warm_recommender.recommend(user_id_array,
                                                   cutoff=cutoff)
        elif user_id_array in self.data.urm_train_users_by_type[4][1]:
            return self.warm_recommender.recommend(user_id_array,
                                                   cutoff=cutoff)
        elif user_id_array in self.data.urm_train_users_by_type[5][1]:
            return self.warm_recommender.recommend(user_id_array,
                                                   cutoff=cutoff)
        elif user_id_array in self.data.urm_train_users_by_type[6][1]:
            return self.warm_recommender.recommend(user_id_array,
                                                   cutoff=cutoff)
        elif user_id_array in self.data.urm_train_users_by_type[7][1]:
            return self.warm_7_recommender.recommend(user_id_array,
                                                     cutoff=cutoff)
        elif user_id_array in self.data.urm_train_users_by_type[8][1]:
            return self.warm_8_recommender.recommend(user_id_array,
                                                     cutoff=cutoff)
        elif user_id_array in self.data.urm_train_users_by_type[9][1]:
            return self.warm_9_recommender.recommend(user_id_array,
                                                     cutoff=cutoff)
        elif user_id_array in self.data.ids_cold_user:
            return self.cold_recommender.recommend(user_id_array,
                                                   cutoff=cutoff)