"""Seed default report templates + a sample generated report.

Idempotent. Uses the baseline logframe produced by
``apps.mel.indicators.seeders.indicators_seeder`` as the default scope.
"""
from __future__ import annotations

import logging
from datetime import date, timedelta

from django.utils import timezone

from apps.mel.indicators.models import LogFrame
from apps.mel.reports.models import (
    Report,
    ReportStatus,
    ReportTemplate,
    ReportType,
)

logger = logging.getLogger(__name__)


# (slug, name, report_type, sections, schedule_cron, description)
_TEMPLATES: list[tuple[str, str, str, list[str], str, str]] = [
    (
        "ruforum-quarterly-portfolio",
        "Quarterly portfolio report",
        ReportType.QUARTERLY,
        ["indicator_rollup", "activity_summary", "variance_table", "output_snapshot", "compliance"],
        "0 6 1 */3 *",  # 06:00 on the 1st every 3 months
        "Consolidated quarterly view of the IILMP baseline log-frame — indicator RAG, activity pipeline, variance causes, and compliance alerts.",
    ),
    (
        "ruforum-annual-donor",
        "Annual donor report",
        ReportType.ANNUAL,
        ["indicator_rollup", "variance_table", "output_snapshot", "compliance"],
        "0 7 10 1 *",  # 07:00 on 10 Jan annually
        "Year-end snapshot for donors — performance against targets, variance explanations, and compliance audit summary.",
    ),
    (
        "ruforum-thematic-spotlight",
        "Thematic indicator spotlight",
        ReportType.THEMATIC,
        ["indicator_rollup", "variance_table"],
        "",
        "Ad-hoc thematic deep-dive — single- or multi-indicator narrative with variance analysis. Generated on demand.",
    ),
    (
        "ruforum-project-closeout",
        "Project close-out report",
        ReportType.PROJECT,
        ["indicator_rollup", "activity_summary", "output_snapshot", "variance_table", "compliance"],
        "",
        "End-of-project summary for individual grants/projects. Generated manually at close-out.",
    ),
    (
        "ruforum-compliance-watch",
        "Compliance watch",
        ReportType.AD_HOC,
        ["compliance", "variance_table"],
        "0 5 * * 1",  # 05:00 every Monday
        "Compliance-focused weekly pulse — RED indicators, open corrective actions, and severity trends.",
    ),
]


def seed_report_templates() -> list[ReportTemplate]:
    """Create/update the default ReportTemplate catalogue."""
    # Default scope: the baseline log frame from the indicators seeder.
    default_logframe = LogFrame.objects.filter(slug="ruforum-iilmp-baseline").first()

    seeded: list[ReportTemplate] = []
    for slug, name, report_type, sections, cron, description in _TEMPLATES:
        tpl, _ = ReportTemplate.objects.update_or_create(
            slug=slug,
            defaults={
                "name": name,
                "report_type": report_type,
                "logframe": default_logframe,
                "sections": sections,
                "schedule_cron": cron,
                "description": description,
                "is_active": True,
            },
        )
        seeded.append(tpl)
    logger.info("mel.seed report templates=%s", len(seeded))
    return seeded


def seed_sample_report() -> Report | None:
    """Generate one published sample report for the current quarter.

    Gives the dashboard realistic data on first boot without waiting for the
    scheduled task. Uses the quarterly-portfolio template.
    """
    template = ReportTemplate.objects.filter(slug="ruforum-quarterly-portfolio").first()
    if template is None or template.logframe_id is None:
        return None

    from apps.mel.reports.services import (
        generate_report,
        publish_report,
        render_all,
    )

    today = date.today()
    q = (today.month - 1) // 3 + 1
    period_label = f"{today.year}-Q{q}"
    period_start = date(today.year, (q - 1) * 3 + 1, 1)
    # Last day of the quarter (approximate with month-end of the 3rd month).
    last_month = (q - 1) * 3 + 3
    period_end = (
        date(today.year, 12, 31)
        if last_month == 12
        else date(today.year, last_month + 1, 1) - timedelta(days=1)
    )

    # Idempotency — generate_report() calls update_or_create() which trips the
    # G14 published-report lock signal when re-seeding against an existing DB
    # (the prior boot already moved the row to PUBLISHED). If a published copy
    # for this template+period exists, leave it alone.
    existing = Report.objects.filter(
        template=template,
        period_label=period_label,
        status=ReportStatus.PUBLISHED,
    ).first()
    if existing is not None:
        return existing

    report = generate_report(
        template=template,
        period_label=period_label,
        period_start=period_start,
        period_end=period_end,
        narrative=(
            "Seed report — generated automatically by seed_mel so the dashboard "
            "renders with realistic content on first boot."
        ),
    )
    # Render artefacts (PDF is best-effort if WeasyPrint native deps are missing).
    render_all(report)
    # Move it to PUBLISHED so the feedback ReportReview channel seeding fires.
    if report.status != ReportStatus.PUBLISHED:
        publish_report(report)
    return report


def seed_reports() -> None:
    seed_report_templates()
    seed_sample_report()
