"""
Seed a realistic RUFORUM IILMP log frame with indicators and targets,
then populate actual data points from live grant/award data.

Run: python manage.py seed_mel_targets
Run with clear: python manage.py seed_mel_targets --clear
"""
from __future__ import annotations

from datetime import date
from decimal import Decimal

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

User = get_user_model()

LOGFRAME_SLUG = "ruforum-iilmp-strategic-plan-2024-2028"

# Indicator definitions: (code, name, unit, calc, target_2024, target_2025, target_2026)
INDICATORS = [
    # ── Scholarships ────────────────────────────────────────────────────
    {
        "code": "SCH-001",
        "name": "Number of MSc scholarships awarded annually",
        "unit": "scholarships",
        "level": "output",
        "outcome_title": "Strengthened human capacity in agricultural sciences",
        "target_2024": 10, "target_2025": 20, "target_2026": 30,
        "source_module": "rims",
        "call_type": "scholarship",
    },
    {
        "code": "SCH-002",
        "name": "% of scholarship awardees who are female",
        "unit": "%",
        "level": "output",
        "outcome_title": "Strengthened human capacity in agricultural sciences",
        "target_2024": 40, "target_2025": 45, "target_2026": 50,
        "source_module": "rims",
        "call_type": "scholarship",
        "is_gender": True,
    },
    {
        "code": "SCH-003",
        "name": "Number of African countries represented in scholarship cohort",
        "unit": "countries",
        "level": "output",
        "outcome_title": "Strengthened human capacity in agricultural sciences",
        "target_2024": 5, "target_2025": 8, "target_2026": 12,
        "source_module": "rims",
        "call_type": "scholarship",
        "is_countries": True,
    },
    {
        "code": "SCH-004",
        "name": "% of scholarship awardees with a declared disability",
        "unit": "%",
        "level": "output",
        "outcome_title": "Strengthened human capacity in agricultural sciences",
        "target_2024": 5, "target_2025": 8, "target_2026": 10,
        "source_module": "rims",
        "call_type": "scholarship",
        "is_disability": True,
    },
    # ── Research Grants ──────────────────────────────────────────────────
    {
        "code": "RG-001",
        "name": "Number of research grants awarded annually",
        "unit": "grants",
        "level": "output",
        "outcome_title": "Increased agricultural research and innovation",
        "target_2024": 5, "target_2025": 10, "target_2026": 15,
        "source_module": "rims",
        "call_type": "grant",
    },
    {
        "code": "RG-002",
        "name": "% of research grant principal investigators who are female",
        "unit": "%",
        "level": "output",
        "outcome_title": "Increased agricultural research and innovation",
        "target_2024": 30, "target_2025": 35, "target_2026": 40,
        "source_module": "rims",
        "call_type": "grant",
        "is_gender": True,
    },
    {
        "code": "RG-003",
        "name": "Number of countries with active research grantees",
        "unit": "countries",
        "level": "output",
        "outcome_title": "Increased agricultural research and innovation",
        "target_2024": 4, "target_2025": 7, "target_2026": 10,
        "source_module": "rims",
        "call_type": "grant",
        "is_countries": True,
    },
    # ── Fellowships ──────────────────────────────────────────────────────
    {
        "code": "FEL-001",
        "name": "Number of fellowships awarded annually",
        "unit": "fellowships",
        "level": "output",
        "outcome_title": "Enhanced leadership and professional development",
        "target_2024": 8, "target_2025": 15, "target_2026": 20,
        "source_module": "rims",
        "call_type": "fellowship",
    },
    {
        "code": "FEL-002",
        "name": "% of fellowship awardees who are female",
        "unit": "%",
        "level": "output",
        "outcome_title": "Enhanced leadership and professional development",
        "target_2024": 40, "target_2025": 45, "target_2026": 50,
        "source_module": "rims",
        "call_type": "fellowship",
        "is_gender": True,
    },
    # ── Cross-cutting ────────────────────────────────────────────────────
    {
        "code": "CC-001",
        "name": "Total number of African countries reached across all programmes",
        "unit": "countries",
        "level": "outcome",
        "outcome_title": "Broad and inclusive African programme reach",
        "target_2024": 10, "target_2025": 15, "target_2026": 20,
        "source_module": "rims",
        "call_type": None,
        "is_countries": True,
        "cross_cutting": True,
    },
    {
        "code": "CC-002",
        "name": "Total awards made across all programme types",
        "unit": "awards",
        "level": "outcome",
        "outcome_title": "Broad and inclusive African programme reach",
        "target_2024": 23, "target_2025": 45, "target_2026": 65,
        "source_module": "rims",
        "call_type": None,
        "cross_cutting": True,
    },
    {
        "code": "CC-003",
        "name": "Overall % of awardees who are female across all programmes",
        "unit": "%",
        "level": "outcome",
        "outcome_title": "Broad and inclusive African programme reach",
        "target_2024": 38, "target_2025": 42, "target_2026": 48,
        "source_module": "rims",
        "call_type": None,
        "is_gender": True,
        "cross_cutting": True,
    },
    {
        "code": "CC-004",
        "name": "Total number of awardees with declared disability",
        "unit": "people",
        "level": "outcome",
        "outcome_title": "Broad and inclusive African programme reach",
        "target_2024": 3, "target_2025": 6, "target_2026": 10,
        "source_module": "rims",
        "call_type": None,
        "is_disability": True,
        "cross_cutting": True,
    },
]


class Command(BaseCommand):
    help = "Seed RUFORUM IILMP MEL results framework, indicators, targets and actual data points"

    def add_arguments(self, parser):
        parser.add_argument("--clear", action="store_true",
                            help="Delete the seeded log frame and recreate")

    def handle(self, *args, **options):
        from apps.mel.indicators.models import (
            DataPoint, Indicator, IndicatorFrequency, IndicatorTarget,
            IndicatorType, LogFrame, LogFrameLevel, LogFrameRow,
        )
        from apps.rims.grants.models import Application, GrantCall
        from apps.core.countries import to_country_name

        if options["clear"]:
            LogFrame.objects.filter(slug=LOGFRAME_SLUG).delete()
            self.stdout.write(self.style.WARNING("Cleared seeded log frame."))

        if LogFrame.objects.filter(slug=LOGFRAME_SLUG).exists():
            self.stdout.write(self.style.WARNING(
                "Log frame already exists. Run --clear first to recreate."
            ))
            # Still refresh data points
            self._refresh_data_points()
            return

        director = User.objects.filter(role="program_director").first()
        today = date.today()

        # ── Create log frame ──────────────────────────────────────────────
        lf = LogFrame.objects.create(
            name="RUFORUM IILMP Strategic Plan 2024–2028",
            slug=LOGFRAME_SLUG,
            description=(
                "Integrated IILMP programme log frame covering scholarships, "
                "research grants, and fellowships across sub-Saharan Africa."
            ),
            programme="IILMP",
            owner=director,
            period_start=date(2024, 1, 1),
            period_end=date(2028, 12, 31),
            status="active",
        )
        self.stdout.write(f"  LogFrame: {lf.name}")

        # ── Impact row ────────────────────────────────────────────────────
        impact = LogFrameRow.objects.create(
            logframe=lf,
            level=LogFrameLevel.IMPACT,
            title="Improved agricultural productivity and food security across Africa through strengthened human capital and research",
            order=0,
        )

        # ── Outcome rows (unique titles) ──────────────────────────────────
        outcome_map = {}
        outcome_titles = list(dict.fromkeys(
            ind["outcome_title"] for ind in INDICATORS
        ))
        for i, title in enumerate(outcome_titles):
            row = LogFrameRow.objects.create(
                logframe=lf,
                parent=impact,
                level=LogFrameLevel.OUTCOME,
                title=title,
                order=i,
            )
            outcome_map[title] = row
            self.stdout.write(f"  Outcome: {title}")

        # ── Output rows + indicators ──────────────────────────────────────
        output_map = {}
        for ind_def in INDICATORS:
            outcome_row = outcome_map[ind_def["outcome_title"]]
            level = ind_def.get("level", "output")

            if level == "output":
                output_title = f"Output: {ind_def['outcome_title']}"
                if output_title not in output_map:
                    out_row = LogFrameRow.objects.create(
                        logframe=lf,
                        parent=outcome_row,
                        level=LogFrameLevel.OUTPUT,
                        title=output_title,
                        order=0,
                    )
                    output_map[output_title] = out_row
                parent_row = output_map[output_title]
            else:
                parent_row = outcome_row

            indicator = Indicator.objects.create(
                logframe_row=parent_row,
                code=ind_def["code"],
                name=ind_def["name"],
                unit=ind_def["unit"],
                indicator_type=IndicatorType.QUANTITATIVE,
                calculation_method=f"Computed from RIMS grants module — source_module: rims",
                data_source="RIMS grants pipeline (awards, applications, profiles)",
                frequency=IndicatorFrequency.ANNUAL,
                source_module="rims",
                responsible=director,
                is_active=True,
            )
            self.stdout.write(f"  Indicator [{indicator.code}]: {indicator.name}")

            # Create targets for 2024, 2025, 2026
            for year, target_val in [
                (2024, ind_def["target_2024"]),
                (2025, ind_def["target_2025"]),
                (2026, ind_def["target_2026"]),
            ]:
                IndicatorTarget.objects.create(
                    indicator=indicator,
                    period_label=f"FY{year}",
                    period_start=date(year, 1, 1),
                    period_end=date(year, 12, 31),
                    target_value=Decimal(str(target_val)),
                    original_target_value=Decimal(str(target_val)),
                )

        self.stdout.write(self.style.SUCCESS("  Targets created."))
        self._refresh_data_points()

    def _refresh_data_points(self):
        """Compute actual values from live grant data and write DataPoints."""
        from apps.mel.indicators.models import (
            DataPoint, Indicator, IndicatorTarget,
        )
        from apps.rims.grants.models import Application, GrantCall
        from django.db.models import Count
        from django.utils import timezone

        self.stdout.write("  Computing actual data points from grants data...")

        awarded_apps = Application.objects.filter(
            status=Application.Status.AWARDED
        ).select_related("scholarship_profile", "call")

        current_year = date.today().year
        period_label = f"FY{current_year}"

        def get_or_create_dp(indicator, target, value):
            DataPoint.objects.update_or_create(
                indicator=indicator,
                period_label=period_label,
                source_module="rims",
                source_event="seed_mel_targets",
                defaults={
                    "value": Decimal(str(round(value, 2))),
                    "target": target,
                    "status": "verified",
                    "qualitative_note": f"Auto-computed from RIMS grants data on {date.today()}",
                }
            )

        for indicator in Indicator.objects.filter(source_module="rims"):
            target = IndicatorTarget.objects.filter(
                indicator=indicator,
                period_label=period_label,
            ).first()
            if not target:
                continue

            code = indicator.code
            ind_def = next((i for i in INDICATORS if i["code"] == code), None)
            if not ind_def:
                continue

            call_type = ind_def.get("call_type")
            cross_cutting = ind_def.get("cross_cutting", False)

            if call_type:
                qs = awarded_apps.filter(call__call_type=call_type)
            else:
                qs = awarded_apps

            total = qs.count()

            if ind_def.get("is_gender"):
                female = qs.filter(scholarship_profile__gender="female").count()
                value = round(female / total * 100, 1) if total else 0
            elif ind_def.get("is_countries"):
                value = float(
                    qs.exclude(scholarship_profile__country_of_origin="")
                    .exclude(scholarship_profile__isnull=True)
                    .values_list("scholarship_profile__country_of_origin", flat=True)
                    .distinct().count()
                )
            elif ind_def.get("is_disability"):
                if indicator.unit == "%":
                    dis = qs.filter(scholarship_profile__have_physical_disability=True).count()
                    value = round(dis / total * 100, 1) if total else 0
                else:
                    value = float(qs.filter(scholarship_profile__have_physical_disability=True).count())
            else:
                value = float(total)

            get_or_create_dp(indicator, target, value)
            self.stdout.write(
                f"    [{code}] {indicator.name[:40]}... → actual: {value} / target: {target.target_value}"
            )

        self.stdout.write(self.style.SUCCESS("  Data points refreshed."))
