""" Display followers' departures and arrivals """

import logging
import datetime
from typing import List

from django.core.management.base import BaseCommand, CommandError
from django.db.utils import DatabaseError
from django.utils import timezone

from moderation.models import (
    Follower,
    SocialUser,
    Category,
    UserCategoryRelationship,
)
from community.models import Community
from bot.tweepy_api import get_api
from moderation.social import update_social_ids

logger = logging.getLogger(__name__)


def display_socialusers(qs):
    return " ".join([f'@{su.screen_name_tag()}' for su in qs])

class Command(BaseCommand):
    help = "Display followers' departures and arrivals"

    def add_arguments(self, parser):
        parser.add_argument('community', type=str)
        parser.add_argument(
            "-d",
            "--days",
            type=int,
            help="Since this number of days"
        )
        parser.add_argument(
            '--update',
            action='store_true',
            help="Update followers' list",
        )

    def handle(self, *args, **options):
        community_name: str = options['community']
        days: int =  options['days'] or 1
        delta = datetime.timedelta(days=days)
        cutoff_dt: datetime = timezone.now() - delta 
        try:
            community = Community.objects.get(name=community_name)
        except Community.DoesNotExist as e:
            logger.error(e)
            self.stdout.write(
                self.style.ERROR(
                    f'Community {community_name} does not exist.'
                )
            )
            return
        bot_su = community.account.socialuser
        if options["update"]:
            update_social_ids(
                bot_su,
                cached=False,
                bot_screen_name=bot_su.screen_name_tag(),
                relationship='followers',
            )
        try:
            followers_now = Follower.objects.filter(user=bot_su).latest()
            logger.debug(
                f'{followers_now=} '
                f'{followers_now.id_list=}'
                f'{len(followers_now.id_list)=}'
            )
        except Follower.DoesNotExist:
            self.stdout.write(
                self.style.ERROR(
                    f'No Follower entry for {bot_su}.'
                    'Use --update flag to create one.'
                )
            )
            return
        try:
            followers_then = Follower.objects.filter(
                user=bot_su,
                created__lte=cutoff_dt,
            ).latest()
            logger.debug(
                f'{followers_then=} '
                f'{followers_then.id_list=} '
                f'{len(followers_then.id_list)=}'
            )
        except Follower.DoesNotExist:
            self.stdout.write(
                self.style.ERROR(
                    f'No Follower entry for {bot_su} existed more than {days} '
                    'ago.'
                )
            )
            return
        arrivals = set(followers_now.id_list) - set(followers_then.id_list)
        logger.debug(arrivals)
        departures = set(followers_then.id_list) - set(followers_now.id_list)
        logger.debug(departures)
        arrivals_qs = SocialUser.objects.filter(user_id__in=arrivals)
        logger.debug(arrivals_qs)
        departures_qs = SocialUser.objects.filter(user_id__in=departures)
        logger.debug(departures_qs)
        self.stdout.write(
            self.style.SUCCESS(
                f'New followers of {bot_su.screen_name_tag()} '
                f'since {days} day(s) ago:\n'
                f'{display_socialusers(arrivals_qs) or None}\n'
                f'Users who unfollowed {bot_su.screen_name_tag()} '
                f'since {days} day(s) ago:\n'
                f'{display_socialusers(departures_qs) or None}\n'
            )
        )
@@ -473,16 +473,46 @@
 cial_ids
+%0Afrom tweepy import TweepError
 %0A%0Alogger
@@ -574,73 +574,339 @@
 s(qs
-):%0A    return %22 %22.join(%5Bf'@%7Bsu.screen_name_tag()%7D' for su in qs%5D)
+, api, check_user=False):%0A    _str = %22%22%0A    for su in qs:%0A        screen_name = su.screen_name_tag()%0A        _str+=f'@%7Bscreen_name%7D'%0A        if check_user:%0A            try:%0A                api.get_user(screen_name)%0A            except TweepError as e:%0A                _str+= f': %7Be%5B0%5D%5B%22message%22%5D%7D'%0A        _str+='%5Cn'%0A    return _str
 %0A%0Acl
@@ -3747,24 +3747,81 @@
 artures_qs)%0A
+        api=get_api(username=community.account.username)%0A
         self
@@ -3827,32 +3827,32 @@
 f.stdout.write(%0A
-
             self
@@ -4023,24 +4023,47 @@
 (arrivals_qs
+, api, check_user=False
 ) or None%7D%5Cn
@@ -4170,32 +4170,32 @@
  day(s) ago:%5Cn'%0A
-
                 
@@ -4230,16 +4230,38 @@
 tures_qs
+, api, check_user=True
 ) or Non

improve turnover command