import logging

from django.contrib.auth import get_user_model
from django.core.management.base import BaseCommand
from django.utils import timezone
from trends.trends import TREND_REGISTRY
from trends.utils import compute_and_save_trend, get_supported_periods

logger = logging.getLogger(__name__)
User = get_user_model()


class Command(BaseCommand):
    help = "Compute trends for all users (or a specific user)"

    def add_arguments(self, parser):
        parser.add_argument(
            "--user-id",
            type=int,
            help="Compute trends for a specific user only",
        )

    def handle(self, *args, **options):
        if options["user_id"]:
            user = User.objects.filter(id=options["user_id"]).first()
            if not user:
                self.stderr.write(
                    self.style.ERROR(f"User with id {options['user_id']} not found")
                )
                return
            users = [user]
        else:
            users = User.objects.filter(is_active=True)

        total_users = len(users)
        self.stdout.write(f"Computing trends for {total_users} user(s)...")

        overall_start = timezone.now()
        ok_count = 0
        fail_count = 0
        skipped_count = 0

        for user in users:
            try:
                profile = user.profile
                if profile.trends_disabled:
                    self.stdout.write(
                        self.style.WARNING(
                            f"  {user} ({user.id}): trends disabled globally, skipping"
                        )
                    )
                    skipped_count += len(TREND_REGISTRY)
                    continue
                disabled_trends = set(profile.disabled_trends or [])
            except Exception:
                disabled_trends = set()

            active_slugs = [
                s for s in TREND_REGISTRY if s not in disabled_trends
            ]
            total_trends = len(active_slugs)
            self.stdout.write(
                f"  {user} ({user.id}): {total_trends} trends ("
                f"{len(disabled_trends & set(TREND_REGISTRY.keys()))} disabled)..."
            )
            user_start = timezone.now()
            user_ok = 0
            user_fail = 0

            for idx, slug in enumerate(active_slugs, start=1):
                periods = get_supported_periods(slug)
                self.stdout.write(f"    [{idx}/{total_trends}] {slug}...\n")
                for period in periods:
                    trend_start = timezone.now()
                    self.stdout.write(f"      {period}... ", ending="")
                    try:
                        elapsed = compute_and_save_trend(user, slug, period)
                        self.stdout.write(self.style.SUCCESS(f"OK ({elapsed:.1f}s)"))
                        user_ok += 1
                    except Exception as e:
                        elapsed = (timezone.now() - trend_start).total_seconds()
                        self.stdout.write(
                            self.style.ERROR(f"FAILED after {elapsed:.1f}s: {e}")
                        )
                        user_fail += 1

            user_elapsed = (timezone.now() - user_start).total_seconds()
            self.stdout.write(
                self.style.SUCCESS(
                    f"  {user}: {user_ok} OK, {user_fail} failed "
                    f"({user_elapsed:.1f}s total)"
                )
            )
            ok_count += user_ok
            fail_count += user_fail

        overall_elapsed = (timezone.now() - overall_start).total_seconds()
        self.stdout.write(
            self.style.SUCCESS(
                f"Done! {ok_count} OK, {fail_count} failed, {skipped_count} skipped "
                f"({overall_elapsed:.1f}s across {total_users} user(s))"
            )
        )
