"""Seed alumni Spotlight, Endorsement, and Broadcast rows."""

from __future__ import annotations

import random
from datetime import date, timedelta

from django.contrib.auth import get_user_model
from django.core.management.base import BaseCommand
from django.utils import timezone

from apps.alumni.profiles.models import AlumniProfile
from apps.alumni.recognition.models import (
    Broadcast,
    BroadcastAudience,
    BroadcastStatus,
    Endorsement,
    Spotlight,
    SpotlightCategory,
)
from apps.core.seeders.volumes import RECORD_COUNTS

User = get_user_model()

BROADCAST_BLUEPRINTS = [
    ("Quarterly alumni newsletter", "<p>Highlights from the last quarter, upcoming events, and featured spotlights.</p>"),
    ("Annual reunion — save the date", "<p>The annual reunion is scheduled — register now to secure your spot.</p>"),
    ("New mentorship cohort opening", "<p>Applications are open for the next mentorship cohort.</p>"),
    ("Call for nominations — Mentor of the Year", "<p>Nominate a mentor who has made an outstanding contribution.</p>"),
    ("Grant call: Women in Agricultural Research", "<p>A new grant is open to women researchers in agri-food systems.</p>"),
    ("Survey — share your career outcomes", "<p>Help us improve programmes by completing the 5-minute tracer survey.</p>"),
    ("Welcome to the 2026 cohort", "<p>A warm welcome to alumni who graduated in 2026.</p>"),
    ("Featured: AgriTech founders", "<p>This month we feature alumni building agritech ventures.</p>"),
    ("Job board update", "<p>20+ new opportunities added to the alumni job board.</p>"),
    ("Policy brief — climate-smart agriculture", "<p>A new policy brief is now available from our research network.</p>"),
]


class Command(BaseCommand):
    help = "Seed Spotlight, Endorsement, and Broadcast rows for the alumni module."

    def add_arguments(self, parser):
        parser.add_argument(
            "--volume",
            choices=("minimal", "demo", "heavy"),
            default="demo",
        )

    def handle(self, *args, **opts):
        tier = opts["volume"]
        counts = RECORD_COUNTS[tier]
        spotlights_target = counts["spotlights"]
        endorsements_per = counts["endorsements_per_spotlight"]
        broadcasts_target = counts["broadcasts"]
        random.seed(2026)

        profiles = list(AlumniProfile.objects.select_related("user")[:120])
        if not profiles:
            self.stdout.write(self.style.WARNING("No alumni profiles; skipping recognition."))
            return

        # Curators: ALUMNI_OFFICER or fall back to staff.
        curators = list(User.objects.filter(role="alumni_officer", is_active=True))
        if not curators:
            curators = list(User.objects.filter(is_staff=True)[:3])
        if not curators:
            curators = list(User.objects.filter(is_active=True)[:3])
        if not curators:
            self.stdout.write(self.style.WARNING("No curator users; skipping recognition."))
            return

        endorser_pool = list(User.objects.filter(is_active=True).order_by("?")[:200])

        # Spotlights — cycle (category, period_label) pairs.
        categories = list(SpotlightCategory.values)
        today = date.today()

        spotlights_created = 0
        endorsements_created = 0
        broadcasts_created = 0

        for i in range(spotlights_target):
            category = categories[i % len(categories)]
            # Walk back through months for period_label.
            months_back = i // len(categories)
            anchor = today.replace(day=1) - timedelta(days=30 * months_back)
            period_label = anchor.strftime("%Y-%m")

            if Spotlight.objects.filter(category=category, period_label=period_label).exists():
                continue

            profile = random.choice(profiles)
            curator = random.choice(curators)
            featured_from = anchor
            featured_until = anchor + timedelta(days=27)
            display_name = (
                f"{profile.user.first_name} {profile.user.last_name}".strip()
                or profile.user.email.split("@")[0]
            )

            try:
                spot = Spotlight.objects.create(
                    profile=profile,
                    category=category,
                    title=f"{display_name} — {SpotlightCategory(category).label}",
                    citation=(
                        f"<p>{display_name} is recognised for outstanding contribution in "
                        f"{SpotlightCategory(category).label.lower()}.</p>"
                    ),
                    period_label=period_label,
                    featured_from=featured_from,
                    featured_until=featured_until,
                    is_active=(months_back == 0),
                    curated_by=curator,
                )
            except Exception:  # noqa: BLE001 — unique-constraint guard
                continue
            spotlights_created += 1

            # Endorsements for this category/period.
            endorsers = random.sample(
                endorser_pool, k=min(endorsements_per + random.randint(-1, 3), len(endorser_pool))
            )
            for endorser in endorsers:
                if endorser.pk == profile.user.pk:
                    continue
                if Endorsement.objects.filter(
                    profile=profile, endorser=endorser, category=category, period_label=period_label
                ).exists():
                    continue
                Endorsement.objects.create(
                    profile=profile,
                    endorser=endorser,
                    category=category,
                    period_label=period_label,
                    citation=f"Outstanding work on {category.replace('_', ' ')} this period.",
                )
                endorsements_created += 1

        # Broadcasts — mixed states.
        now = timezone.now()
        for i in range(broadcasts_target):
            subject, body = BROADCAST_BLUEPRINTS[i % len(BROADCAST_BLUEPRINTS)]
            curator = random.choice(curators)
            status = random.choices(
                [BroadcastStatus.DRAFT, BroadcastStatus.SCHEDULED, BroadcastStatus.SENT],
                weights=[3, 3, 6],
                k=1,
            )[0]
            audience = random.choice(list(BroadcastAudience.values))
            audience_filter: dict = {}
            if audience == BroadcastAudience.BY_COUNTRY:
                audience_filter = {"country": random.choice(["UG", "KE", "TZ", "ZA"])}
            elif audience == BroadcastAudience.BY_GRADUATION_YEAR:
                audience_filter = {"year": random.choice([2020, 2021, 2022, 2023])}

            sent_at = None
            sent_count = 0
            scheduled_for = None
            if status == BroadcastStatus.SENT:
                sent_at = now - timedelta(days=random.randint(1, 90))
                sent_count = random.randint(40, 300)
            elif status == BroadcastStatus.SCHEDULED:
                scheduled_for = now + timedelta(days=random.randint(1, 30))

            Broadcast.objects.create(
                subject=f"{subject} — {now.year}",
                body_html=body,
                audience=audience,
                audience_filter=audience_filter,
                status=status,
                created_by=curator,
                scheduled_for=scheduled_for,
                sent_at=sent_at,
                sent_count=sent_count,
            )
            broadcasts_created += 1

        self.stdout.write(self.style.SUCCESS(
            f"Recognition seed: spotlights={spotlights_created} endorsements={endorsements_created} "
            f"broadcasts={broadcasts_created} (tier={tier})"
        ))
