"""Seed SME-Hub × M&EL indicators (FRSME-MEI008 → MEI010, MEI013).

Six indicators map onto a dedicated SME-Hub log frame anchored under the
existing IILMP baseline log frame. All indicators are quantitative and use
``source_module='smehub'`` so the M&EL upstream-event log groups them.

Idempotent — every row uses ``update_or_create`` keyed on a stable slug.

Indicator catalogue:

* ``smehub-businesses-registered`` — count of verified Businesses (FRSME-MEI008)
* ``smehub-percentage-incubated``  — verified businesses currently in a
  cohort / total verified businesses (FRSME-MEI009)
* ``smehub-partnerships-formed``   — formalised MoUs + AWARDED demand
  responses (FRSME-MEI010)
* ``smehub-deals-closed``           — DealAgreements formalised (FRSME-MEI013)
* ``smehub-jobs-created``           — Σ (current FTE+PTE) − baseline FTE+PTE
  per record, computed via ``apps.mel.tracking.smehub_employment``
  (FRSME-MEI013)
* ``smehub-funding-secured``        — Σ application + manual funding rows
  (FRSME-MEI013)
"""
from __future__ import annotations

from datetime import date
from decimal import Decimal

from apps.mel.indicators.models import (
    Indicator,
    IndicatorFrequency,
    IndicatorTarget,
    IndicatorType,
    LogFrame,
    LogFrameLevel,
    LogFrameRow,
)


# (level, title, parent_title_or_None, order)
_SMEHUB_ROWS: list[tuple[str, str, str | None, int]] = [
    (
        LogFrameLevel.OUTCOME,
        "SME-Hub entrepreneurs scaling and sustaining inclusive businesses",
        "Strengthened higher education, research & innovation across Africa",
        50,
    ),
    (
        LogFrameLevel.OUTPUT,
        "SME-Hub businesses registered, incubated and partnered",
        "SME-Hub entrepreneurs scaling and sustaining inclusive businesses",
        510,
    ),
    (
        LogFrameLevel.OUTPUT,
        "SME-Hub deals closed and funding secured",
        "SME-Hub entrepreneurs scaling and sustaining inclusive businesses",
        520,
    ),
    (
        LogFrameLevel.ACTIVITY,
        "Onboard and verify entrepreneurs / businesses",
        "SME-Hub businesses registered, incubated and partnered",
        5100,
    ),
    (
        LogFrameLevel.ACTIVITY,
        "Run incubation programmes, linkages and showcasing",
        "SME-Hub businesses registered, incubated and partnered",
        5101,
    ),
    (
        LogFrameLevel.ACTIVITY,
        "Facilitate deal rooms and funding pipelines",
        "SME-Hub deals closed and funding secured",
        5200,
    ),
]


# (code, name, level_title, unit, frequency, computation_method, baseline, target)
_SMEHUB_INDICATORS: list[tuple[str, str, str, str, str, str, Decimal, Decimal]] = [
    (
        "smehub-businesses-registered",
        "SME-Hub businesses registered (verified count)",
        "SME-Hub businesses registered, incubated and partnered",
        "businesses",
        IndicatorFrequency.MONTHLY,
        "COUNT(Business WHERE verification_status=verified) at period end.",
        Decimal("0"),
        Decimal("100"),
    ),
    (
        "smehub-percentage-incubated",
        "% of verified businesses currently incubated",
        "SME-Hub businesses registered, incubated and partnered",
        "%",
        IndicatorFrequency.QUARTERLY,
        "100 × COUNT(active CohortMembers with verified business) / "
        "COUNT(verified Businesses).",
        Decimal("0"),
        Decimal("40"),
    ),
    (
        "smehub-partnerships-formed",
        "Partnerships formed (MoUs + awarded demand responses)",
        "SME-Hub businesses registered, incubated and partnered",
        "partnerships",
        IndicatorFrequency.QUARTERLY,
        "COUNT(MoU WHERE status IN [formalised, amended]) + "
        "COUNT(DemandResponse WHERE status=awarded) per period.",
        Decimal("0"),
        Decimal("30"),
    ),
    (
        "smehub-deals-closed",
        "Deal-room agreements formalised",
        "SME-Hub deals closed and funding secured",
        "agreements",
        IndicatorFrequency.QUARTERLY,
        "COUNT(DealAgreement) created during the period.",
        Decimal("0"),
        Decimal("12"),
    ),
    (
        "smehub-jobs-created",
        "Jobs created (FTE + PTE delta against baseline)",
        "SME-Hub deals closed and funding secured",
        "jobs",
        IndicatorFrequency.SEMI_ANNUAL,
        "Σ max(0, latest_employment_snapshot − baseline) across SME-Hub "
        "tracking records. Latest snapshot per record taken from "
        "apps.mel.tracking.smehub_employment.compute_total_jobs_created().",
        Decimal("0"),
        Decimal("250"),
    ),
    (
        "smehub-funding-secured",
        "Funding secured (USD)",
        "SME-Hub deals closed and funding secured",
        "USD",
        IndicatorFrequency.QUARTERLY,
        "SUM(FundingApplication.funding_request_amount WHERE status=accepted) + "
        "SUM(ManualFundingRecord.amount) per period.",
        Decimal("0"),
        Decimal("500000"),
    ),
]


def seed_smehub_indicators() -> None:
    lf, _ = LogFrame.objects.get_or_create(
        slug="ruforum-iilmp-baseline",
        defaults={
            "name": "RUFORUM IILMP — Baseline Strategic Objective",
            "description": "Seeded by mel.indicators.seeders.indicators_seeder.",
            "programme": "RUFORUM IILMP",
        },
    )

    by_title: dict[str, LogFrameRow] = {
        row.title: row for row in lf.rows.all()
    }

    for level, title, parent_title, order in _SMEHUB_ROWS:
        parent = by_title.get(parent_title) if parent_title else None
        row, _ = LogFrameRow.objects.get_or_create(
            logframe=lf,
            title=title,
            defaults={
                "level": level,
                "parent": parent,
                "order": order,
            },
        )
        dirty = False
        if row.parent_id is None and parent is not None:
            row.parent = parent
            dirty = True
        if row.order != order:
            row.order = order
            dirty = True
        if dirty:
            row.save(update_fields=["parent", "order"])
        by_title[title] = row

    today = date.today()
    year = today.year
    quarter = (today.month - 1) // 3 + 1

    for code, name, level_title, unit, freq, calc, baseline, target in _SMEHUB_INDICATORS:
        row = by_title.get(level_title)
        if row is None:
            continue
        indicator, _ = Indicator.objects.update_or_create(
            code=code,
            defaults={
                "logframe_row": row,
                "name": name,
                "indicator_type": IndicatorType.QUANTITATIVE,
                "unit": unit,
                "frequency": freq,
                "source_module": "smehub",
                "auto_event_type": "",
                "data_source": "SME-Hub tracking records, computed by M&EL.",
                "calculation_method": calc,
                "is_active": True,
            },
        )
        if freq == IndicatorFrequency.SEMI_ANNUAL:
            half = 1 if today.month <= 6 else 2
            period_label = f"{year}-H{half}"
            start = date(year, 1 if half == 1 else 7, 1)
            end = date(year, 6 if half == 1 else 12, 30 if half == 1 else 31)
        elif freq == IndicatorFrequency.QUARTERLY:
            period_label = f"{year}-Q{quarter}"
            start_month = (quarter - 1) * 3 + 1
            start = date(year, start_month, 1)
            end_month = start_month + 2
            end = date(year, end_month, 28)
        else:  # MONTHLY (or anything else)
            period_label = today.strftime("%Y-%m")
            start = today.replace(day=1)
            end = today.replace(day=28)
        IndicatorTarget.objects.update_or_create(
            indicator=indicator,
            period_label=period_label,
            defaults={
                "period_start": start,
                "period_end": end,
                "baseline_value": baseline,
                "target_value": target,
            },
        )
