"""Seed Activities + Output deliverables + a sample CorrectiveAction.

Scoped to the baseline log frame seeded by
``apps.mel.indicators.seeders.indicators_seeder``. Idempotent: re-running only
creates missing rows.
"""
from __future__ import annotations

import logging
from datetime import date, timedelta
from decimal import Decimal

from django.contrib.contenttypes.models import ContentType

from apps.mel.indicators.models import (
    LogFrame,
    LogFrameLevel,
    LogFrameRow,
)
from apps.mel.tracking.models import (
    Activity,
    ActivityStatus,
    CorrectiveAction,
    CorrectiveActionStatus,
    OutputDeliverable,
    OutputDeliverableStatus,
)

logger = logging.getLogger(__name__)


# (activity_name, parent_activity_row_title, status, start_offset_days, end_offset_days, deviation_reason)
_ACTIVITIES: list[tuple[str, str, str, int, int, str]] = [
    (
        "2026 Q2 — Grants call launch",
        "Issue grant calls and manage the award lifecycle",
        ActivityStatus.IN_PROGRESS,
        -30,
        45,
        "",
    ),
    (
        "2026 Q2 — Grants review panel",
        "Issue grant calls and manage the award lifecycle",
        ActivityStatus.PLANNED,
        30,
        75,
        "",
    ),
    (
        "2026 — Scholar intake cohort",
        "Administer scholarship selection and stipend disbursement",
        ActivityStatus.IN_PROGRESS,
        -60,
        60,
        "",
    ),
    (
        "Q1 repository QA sweep",
        "Curate, QA, and publish documents in the digital repository",
        ActivityStatus.DELAYED,
        -90,
        -15,
        "QA reviewers partially unavailable — extending deadline by 3 weeks.",
    ),
    (
        "New course authoring sprint — April",
        "Author and deliver online courses",
        ActivityStatus.COMPLETED,
        -45,
        -5,
        "",
    ),
]

# (output_title, parent_output_row_title, target_quantity, achieved_quantity, unit, due_offset_days)
_OUTPUTS: list[tuple[str, str, Decimal, Decimal, str, int]] = [
    (
        "Grant awards issued (2026 Q2)",
        "Grants awarded to researchers and institutions",
        Decimal("25"),
        Decimal("18"),
        "awards",
        20,
    ),
    (
        "Repository documents published (April)",
        "Research outputs published to the RUFORUM repository",
        Decimal("30"),
        Decimal("22"),
        "documents",
        -5,
    ),
    (
        "REP courses launched (Q2)",
        "Courses delivered via the Regional E-Learning Platform",
        Decimal("6"),
        Decimal("4"),
        "courses",
        15,
    ),
    (
        "PhD scholars supported (2026 cohort)",
        "Scholars supported through PhD / MSc fellowships",
        Decimal("40"),
        Decimal("26"),
        "scholars",
        60,
    ),
]


def seed_tracking() -> None:
    lf = LogFrame.objects.filter(slug="ruforum-iilmp-baseline").first()
    if lf is None:
        logger.info("mel.seed tracking skipped — baseline log frame not seeded yet.")
        return

    today = date.today()
    rows_by_title = {
        r.title: r for r in LogFrameRow.objects.filter(logframe=lf)
    }

    # Activities ----------------------------------------------------------
    created_activities: list[Activity] = []
    for name, parent_title, status, start_off, end_off, deviation in _ACTIVITIES:
        parent_row = rows_by_title.get(parent_title)
        if parent_row is None or parent_row.level != LogFrameLevel.ACTIVITY:
            continue
        defaults = {
            "status": status,
            "scheduled_start": today + timedelta(days=start_off),
            "scheduled_end": today + timedelta(days=end_off),
            "deviation_flag": status == ActivityStatus.DELAYED,
            "deviation_reason": deviation,
        }
        if status == ActivityStatus.IN_PROGRESS:
            defaults["actual_start"] = today + timedelta(days=start_off)
        elif status == ActivityStatus.COMPLETED:
            defaults["actual_start"] = today + timedelta(days=start_off)
            defaults["actual_end"] = today + timedelta(days=end_off)
        activity, _ = Activity.objects.update_or_create(
            logframe_row=parent_row,
            name=name,
            defaults=defaults,
        )
        created_activities.append(activity)

    # Output deliverables -------------------------------------------------
    created_outputs: list[OutputDeliverable] = []
    for title, parent_title, target_q, achieved_q, unit, due_off in _OUTPUTS:
        parent_row = rows_by_title.get(parent_title)
        if parent_row is None or parent_row.level != LogFrameLevel.OUTPUT:
            continue
        percent = float(achieved_q) / float(target_q) * 100 if target_q else 0
        if percent >= 100:
            status = OutputDeliverableStatus.COMPLETED
        elif due_off < 0 and percent < 100:
            status = OutputDeliverableStatus.OVERDUE
        elif achieved_q > 0:
            status = OutputDeliverableStatus.IN_PROGRESS
        else:
            status = OutputDeliverableStatus.DRAFT
        deliverable, _ = OutputDeliverable.objects.update_or_create(
            logframe_row=parent_row,
            title=title,
            defaults={
                "target_quantity": target_q,
                "achieved_quantity": achieved_q,
                "unit": unit,
                "due_date": today + timedelta(days=due_off),
                "status": status,
            },
        )
        created_outputs.append(deliverable)

    # Seed one CorrectiveAction tied to the delayed QA sweep activity.
    delayed = next(
        (a for a in created_activities if a.status == ActivityStatus.DELAYED),
        None,
    )
    if delayed is not None:
        ct = ContentType.objects.get_for_model(Activity)
        CorrectiveAction.objects.update_or_create(
            subject_type=ct,
            subject_id=delayed.pk,
            title=f"Recover schedule for '{delayed.name}'",
            defaults={
                "root_cause": delayed.deviation_reason or "Activity past scheduled end.",
                "action_plan": (
                    "Reallocate 2 reviewers from the April backlog; re-baseline "
                    "deadline; communicate revised timeline to stakeholders."
                ),
                "due_date": today + timedelta(days=21),
                "status": CorrectiveActionStatus.IN_PROGRESS,
            },
        )

    logger.info(
        "mel.seed tracking activities=%s outputs=%s",
        len(created_activities), len(created_outputs),
    )
