"""Seed fake scholarship applicants onto an existing call for pipeline testing."""
from __future__ import annotations

import random
from datetime import timedelta

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

from apps.rims.grants.models import Application, GrantCall, ScholarshipApplicationProfile, Review

User = get_user_model()

RUFORUM_COUNTRIES = [
    ("UGA", "Uganda"), ("KEN", "Kenya"), ("TZA", "Tanzania"), ("ETH", "Ethiopia"),
    ("RWA", "Rwanda"), ("GHA", "Ghana"), ("NGA", "Nigeria"), ("ZMB", "Zambia"),
    ("MWI", "Malawi"), ("MOZ", "Mozambique"), ("ZWE", "Zimbabwe"), ("SEN", "Senegal"),
    ("CMR", "Cameroon"), ("BFA", "Burkina Faso"), ("MLI", "Mali"), ("NER", "Niger"),
]

PROGRAMMES = [
    "MSc Agribusiness & Innovation",
    "MSc Agricultural Technology",
    "MSc Crop Science",
    "MSc Animal Science",
    "MSc Food Science & Technology",
    "MSc Agricultural Economics",
    "MSc Soil Science",
    "MSc Plant Pathology",
]

DISABILITIES = [
    "Visual impairment",
    "Hearing impairment",
    "Mobility impairment",
    "Speech impairment",
]

STATUSES = [
    Application.Status.SUBMITTED,
    Application.Status.SUBMITTED,
    Application.Status.SUBMITTED,
    Application.Status.UNDER_REVIEW,
    Application.Status.UNDER_REVIEW,
    Application.Status.SHORTLISTED,
    Application.Status.REJECTED,
    Application.Status.INELIGIBLE,
]

FIRST_NAMES = [
    "Amara", "Kofi", "Fatima", "Abebe", "Wanjiru", "Tendai", "Adaeze", "Kwame",
    "Miriam", "Ibrahim", "Grace", "Emmanuel", "Aisha", "Patrick", "Blessing",
    "Moses", "Lydia", "Samuel", "Esther", "Joseph", "Agnes", "Daniel", "Ruth",
    "Michael", "Patience", "David", "Mercy", "John", "Hope", "Peter", "Faith",
    "James", "Charity", "Paul", "Joy", "Thomas", "Peace", "Andrew", "Praise",
    "George", "Comfort", "Francis", "Lovely", "Charles", "Stella", "Robert",
    "Cynthia", "Richard", "Sandra", "Henry",
]

LAST_NAMES = [
    "Okonkwo", "Mwangi", "Otieno", "Mensah", "Diallo", "Nkosi", "Banda",
    "Kimani", "Osei", "Dlamini", "Kamau", "Asante", "Mutua", "Nkrumah",
    "Abubakar", "Chukwu", "Zawadi", "Nakato", "Ssemakula", "Tumusiime",
    "Mugisha", "Kiggundu", "Namukasa", "Sekandi", "Byamukama", "Atuhaire",
    "Muhwezi", "Tusiime", "Rwabuhungu", "Kabagambe",
]


class Command(BaseCommand):
    help = "Seed 50 fake scholarship applicants onto a call for pipeline testing"

    def add_arguments(self, parser):
        parser.add_argument("--slug", default="call-for-applications-for-msc-agic-tech",
                            help="Call slug to seed applicants onto")
        parser.add_argument("--count", type=int, default=50,
                            help="Number of applicants to create")
        parser.add_argument("--clear", action="store_true",
                            help="Remove previously seeded test applicants first")

    def handle(self, *args, **options):
        slug = options["slug"]
        count = options["count"]

        try:
            call = GrantCall.objects.get(slug=slug)
        except GrantCall.DoesNotExist:
            raise CommandError(f"No call with slug '{slug}' found.")

        if options["clear"]:
            deleted = User.objects.filter(email__endswith="@seed.test").delete()
            self.stdout.write(self.style.WARNING(f"Cleared seeded users: {deleted}"))

        created = 0
        for i in range(count):
            first = random.choice(FIRST_NAMES)
            last = random.choice(LAST_NAMES)
            email = f"applicant.{first.lower()}.{last.lower()}.{i}@seed.test"

            if User.objects.filter(email=email).exists():
                continue

            user = User.objects.create_user(
                email=email,
                password="SeedPass@2024",
                first_name=first,
                last_name=last,
            )

            country_code, _ = random.choice(RUFORUM_COUNTRIES)
            gender = random.choices(["male", "female"], weights=[45, 55])[0]
            has_disability = random.choices([True, False, None], weights=[8, 75, 17])[0]

            submitted_at = timezone.now() - timedelta(days=random.randint(1, 60))
            status = random.choice(STATUSES)

            app = Application.objects.create(
                call=call,
                applicant=user,
                status=status,
                submitted_at=submitted_at if status != Application.Status.DRAFT else None,
                eligibility_passed=status not in [Application.Status.INELIGIBLE],
                proposal="Sample proposal text for pipeline testing.",
            )

            ScholarshipApplicationProfile.objects.create(
                application=app,
                gender=gender,
                country_of_origin=country_code,
                country_of_residence=country_code,
                country_of_birth=country_code,
                degree_programme=random.choice(PROGRAMMES),
                gpa=round(random.uniform(2.5, 4.0), 2),
                have_physical_disability=has_disability,
                physical_disability=random.choice(DISABILITIES) if has_disability else "",
                people_in_house=random.randint(3, 10),
                date_of_birth=timezone.now().date().replace(
                    year=timezone.now().year - random.randint(20, 30)
                ),
            )

            # Add a review score for under_review and shortlisted
            if status in [Application.Status.UNDER_REVIEW, Application.Status.SHORTLISTED]:
                reviewer = User.objects.filter(email__contains="ruforum").first()
                if reviewer:
                    Review.objects.create(
                        application=app,
                        reviewer=reviewer,
                        total_score=round(random.uniform(40, 95), 1),
                        submitted_at=submitted_at + timedelta(days=random.randint(1, 10)),
                        recommendation_code=random.choice(["approve", "revise", "reject", "hold"]),
                    )

            created += 1
            if created % 10 == 0:
                self.stdout.write(f"  Created {created}/{count}...")

        self.stdout.write(self.style.SUCCESS(
            f"Done. Created {created} applicants on call '{call.title}'."
        ))
