"""
    Filter functions for media and user lists.
"""


def filter_medias(self, media_items, filtration=True, quiet=False, is_comment=False):
    if filtration:
        if not quiet:
            self.logger.info("Received {} medias.".format(len(media_items)))
        if not is_comment:
            media_items = _filter_medias_not_liked(media_items)
            if self.max_likes_to_like:
                media_items = _filter_medias_nlikes(
                    media_items, self.max_likes_to_like, self.min_likes_to_like)
        else:
            media_items = _filter_medias_not_commented(self, media_items)
        if not quiet:
            msg = "After filtration {} medias left."
            self.logger.info(msg.format(len(media_items)))
    return _get_media_ids(media_items)


def _filter_medias_not_liked(media_items):
    not_liked_medias = []
    for media in media_items:
        if 'has_liked' in media and not media['has_liked']:
            not_liked_medias.append(media)
    return not_liked_medias


def _filter_medias_not_commented(self, media_items):
    not_commented_medias = []
    for media in media_items:
        if media.get('comment_count', 0) > 0 and media.get('comments'):
            my_comments = [comment for comment in media['comments']
                           if comment['user_id'] == self.user_id]
            if my_comments:
                continue
        not_commented_medias.append(media)
    return not_commented_medias


def _filter_medias_nlikes(media_items, max_likes_to_like, min_likes_to_like):
    filtered_medias = []
    for media in media_items:
        if 'like_count' in media:
            if media['like_count'] < max_likes_to_like and media['like_count'] > min_likes_to_like:
                filtered_medias.append(media)
    return filtered_medias


def _get_media_ids(media_items):
    result = []
    for media in media_items:
        if 'pk' in media:
            result.append(media['pk'])
    return result


def check_media(self, media_id):
    if self.api.media_info(media_id):
        medias = self.api.last_json["items"]

        if search_blacklist_hashtags_in_media(self, media_id):
            msg = 'Blacklist hashtag found in media, skipping!'
            self.console_print(msg, 'red')
            return False

        if self.filter_medias(medias, quiet=True):
            return check_user(self, self.get_media_owner(media_id))
        return False

    msg = 'Media ID error!'
    self.console_print(msg, 'red')
    return False


# Filter users

def search_stop_words_in_user(self, user_info):
    text = ''
    if 'biography' in user_info:
        text += user_info['biography'].lower()

    if 'username' in user_info:
        text += user_info['username'].lower()

    if 'full_name' in user_info:
        text += user_info['full_name'].lower()

    for stop_word in self.stop_words:
        if stop_word in text:
            return True

    return False


def search_blacklist_hashtags_in_media(self, media_id):
    media_info = self.get_media_info(media_id)
    text = media_info[0]['caption']['text'] if media_info[0]['caption'] else ''

    media_comments = self.get_media_comments(media_id)
    comments_number = min(6, len(media_comments))

    for i in range(0, comments_number):
        text += ''.join(media_comments[i]['text'])

    return any((h in text) for h in self.blacklist_hashtags)


def check_user(self, user_id, unfollowing=False):
    if not self.filter_users and not unfollowing:
        return True

    self.small_delay()
    user_id = self.convert_to_user_id(user_id)

    if not user_id:
        self.console_print('not user_id, skipping!', 'red')
        return False
    if user_id in self.whitelist:
        self.console_print('`user_id` in `self.whitelist`.', 'green')
        return True
    if user_id in self.blacklist:
        self.console_print('`user_id` in `self.blacklist`.', 'red')
        return False

    if user_id == str(self.user_id):
        self.console_print("`user_id` equals bot's `user_id`, skipping!", 'green')
        return False

    if user_id in self.following:
        if not unfollowing:
            # Log to Console
            self.console_print('Already following, skipping!', 'red')
        return False

    user_info = self.get_user_info(user_id)
    if not user_info:
        self.console_print('not `user_info`, skipping!', 'red')
        return False

    msg = 'USER_NAME: {username}, FOLLOWER: {followers}, FOLLOWING: {following}'
    follower_count = user_info["follower_count"]
    following_count = user_info["following_count"]
    self.console_print(msg.format(
        username=user_info["username"],
        followers=follower_count,
        following=following_count
    ))

    skipped = self.skipped_file
    followed = self.followed_file

    if not unfollowing:
        if self.filter_previously_followed and user_id in followed.list:
            self.console_print('info: account previously followed, skipping!', 'red')
            return False
    if "has_anonymous_profile_picture" in user_info and self.filter_users_without_profile_photo:
        if user_info["has_anonymous_profile_picture"]:
            self.console_print('info: account DOES NOT HAVE A PROFILE PHOTO, skipping! ', 'red')
            skipped.append(user_id)
            return False
    if "is_private" in user_info and self.filter_private_users:
        if user_info["is_private"]:
            self.console_print('info: account is PRIVATE, skipping! ', 'red')
            skipped.append(user_id)
            return False
    if "is_business" in user_info and self.filter_business_accounts:
        if user_info["is_business"]:
            self.console_print('info: is BUSINESS, skipping!', 'red')
            skipped.append(user_id)
            return False
    if "is_verified" in user_info and self.filter_verified_accounts:
        if user_info["is_verified"]:
            self.console_print('info: is VERIFIED, skipping !', 'red')
            skipped.append(user_id)
            return False

    if follower_count < self.min_followers_to_follow:
        msg = 'follower_count < bot.min_followers_to_follow, skipping!'
        self.console_print(msg, 'red')
        skipped.append(user_id)
        return False
    if follower_count > self.max_followers_to_follow:
        msg = 'follower_count > bot.max_followers_to_follow, skipping!'
        self.console_print(msg, 'red')
        skipped.append(user_id)
        return False
    if user_info["following_count"] < self.min_following_to_follow:
        msg = 'following_count < bot.min_following_to_follow, skipping!'
        self.console_print(msg, 'red')
        skipped.append(user_id)
        return False
    if user_info["following_count"] > self.max_following_to_follow:
        msg = 'following_count > bot.max_following_to_follow, skipping!'
        self.console_print(msg, 'red')
        skipped.append(user_id)
        return False
    try:
        if follower_count / following_count > self.max_followers_to_following_ratio:
            msg = 'follower_count / following_count > bot.max_followers_to_following_ratio, skipping!'
            self.console_print(msg, 'red')
            skipped.append(user_id)
            return False
        if following_count / follower_count > self.max_following_to_followers_ratio:
            msg = 'following_count / follower_count > bot.max_following_to_followers_ratio, skipping!'
            self.console_print(msg, 'red')
            skipped.append(user_id)
            return False
    except ZeroDivisionError:
        self.console_print('ZeroDivisionError: division by zero', 'red')
        return False

    if 'media_count' in user_info and user_info["media_count"] < self.min_media_count_to_follow:
        msg = 'media_count < bot.min_media_count_to_follow, BOT or INACTIVE, skipping!'
        self.console_print(msg, 'red')
        skipped.append(user_id)
        return False

    if search_stop_words_in_user(self, user_info):
        msg = '`bot.search_stop_words_in_user` found in user, skipping!'
        self.console_print(msg, 'red')
        skipped.append(user_id)
        return False

    return True


def check_not_bot(self, user_id):
    """ Filter bot from real users. """
    self.small_delay()
    user_id = self.convert_to_user_id(user_id)
    if not user_id:
        return False
    if user_id in self.whitelist:
        return True
    if user_id in self.blacklist:
        return False

    user_info = self.get_user_info(user_id)
    if not user_info:
        return True  # closed acc

    skipped = self.skipped_file
    if "following_count" in user_info and user_info["following_count"] > self.max_following_to_block:
        msg = 'following_count > bot.max_following_to_block, skipping!'
        self.console_print(msg, 'red')
        skipped.append(user_id)
        return False  # massfollower

    if search_stop_words_in_user(self, user_info):
        msg = '`bot.search_stop_words_in_user` found in user, skipping!'
        skipped.append(user_id)
        return False

    return True
