"""Render smoke tests for the M&E SRS UI surfaces added in this sweep.

Ensures every new/changed page renders (HTTP 200) with realistic data so a
template crash can't slip through. UI is guided by the shared topnav / dashboard
shell (page_header_text + breadcrumb + card + mel_badge).

Do NOT run under a parallel pytest — the test_iilmp DB collides.
"""
from __future__ import annotations

from decimal import Decimal

import pytest
from django.contrib.auth import get_user_model
from django.urls import reverse

from apps.mel.indicators.models import (
    DataPoint,
    DisaggregationCategory,
    Indicator,
    IndicatorFrequency,
    LogFrame,
    LogFrameLevel,
    LogFrameRow,
    OutputType,
)

User = get_user_model()
pytestmark = pytest.mark.django_db


@pytest.fixture
def officer():
    return User.objects.create_user(
        email="ui-officer@example.com", password="x", role="mel_officer",
    )


@pytest.fixture
def framework():
    lf = LogFrame.objects.create(
        name="UI Framework", slug="ui-fw", code="SO-1", planning_period="2024–2028",
    )
    impact = LogFrameRow.objects.create(
        logframe=lf, level=LogFrameLevel.IMPACT, title="Impact",
    )
    outcome = LogFrameRow.objects.create(
        logframe=lf, level=LogFrameLevel.OUTCOME, title="Intermediate Outcome", parent=impact,
    )
    uni = LogFrameRow.objects.create(
        logframe=lf, level=LogFrameLevel.OUTPUT, title="Uni Output",
        parent=outcome, output_type=OutputType.UNIVERSITY,
    )
    sec = LogFrameRow.objects.create(
        logframe=lf, level=LogFrameLevel.OUTPUT, title="Sec Output",
        parent=outcome, output_type=OutputType.SECRETARIAT,
    )
    ind = Indicator.objects.create(
        logframe_row=uni, code="ui-ind", name="Farmers", definition="d",
        unit="x", calculation_method="c", data_source="m",
        frequency=IndicatorFrequency.QUARTERLY,
    )
    return lf, uni, ind


def test_logframe_detail_renders_hierarchy(client, officer, framework):
    lf, uni, ind = framework
    client.force_login(officer)
    resp = client.get(reverse("mel_indicators:logframe_detail", kwargs={"slug": lf.slug}))
    assert resp.status_code == 200
    body = resp.content.decode()
    assert "Strategic Objective" in body
    assert "University" in body and "Secretariat" in body


def test_row_create_and_edit_forms_render(client, officer, framework):
    lf, uni, ind = framework
    client.force_login(officer)
    resp = client.get(
        reverse("mel_indicators:logframe_row_create") + f"?logframe={lf.pk}"
    )
    assert resp.status_code == 200
    resp = client.get(
        reverse("mel_indicators:logframe_row_edit", kwargs={"pk": uni.pk})
    )
    assert resp.status_code == 200


def test_disaggregation_pages_render(client, officer, framework):
    lf, uni, ind = framework
    cat = DisaggregationCategory.objects.create(indicator=ind, name="Gender")
    client.force_login(officer)
    resp = client.get(
        reverse("mel_indicators:indicator_disaggregation", kwargs={"code": ind.code})
    )
    assert resp.status_code == 200
    assert "Gender" in resp.content.decode()
    resp = client.get(
        reverse(
            "mel_indicators:disaggregation_values",
            kwargs={"code": ind.code, "pk": cat.pk},
        )
    )
    assert resp.status_code == 200


def test_indicator_detail_with_clarification_renders(client, officer, framework):
    lf, uni, ind = framework
    DataPoint.objects.create(
        indicator=ind, period_label="2026-Q1", value=Decimal("5"),
        status=DataPoint.Status.NEEDS_CLARIFICATION,
        clarification_note="Please recheck",
    )
    client.force_login(officer)
    resp = client.get(reverse("mel_indicators:indicator_detail", kwargs={"code": ind.code}))
    assert resp.status_code == 200
    assert "Clarification requested" in resp.content.decode()


def test_tracking_dashboard_renders(client, officer):
    client.force_login(officer)
    resp = client.get(reverse("mel_tracking:tracking_dashboard"))
    assert resp.status_code == 200


# ---------------------------------------------------------------------------
# 2026-07-14 verification sweep — new surfaces render
# ---------------------------------------------------------------------------


def test_validation_queue_renders(client, officer, framework):
    lf, uni, ind = framework
    DataPoint.objects.create(
        indicator=ind, period_label="2026-Q1", value=Decimal("4"),
    )
    DataPoint.objects.create(
        indicator=ind, period_label="2026-Q2", value=Decimal("5"),
        status=DataPoint.Status.NEEDS_CLARIFICATION, clarification_note="check",
    )
    client.force_login(officer)
    resp = client.get(reverse("mel_indicators:validation_queue"))
    assert resp.status_code == 200
    body = resp.content.decode()
    assert "Data validation" in body
    assert "Schedule field verification" in body


def test_corrective_action_register_renders(client, officer, framework):
    from django.contrib.contenttypes.models import ContentType

    from apps.mel.tracking.models import CorrectiveAction

    lf, uni, ind = framework
    CorrectiveAction.objects.create(
        subject_type=ContentType.objects.get_for_model(Indicator),
        subject_id=ind.pk,
        title="Fix data pipeline",
        severity="high",
        root_cause="cause",
        action_plan="plan",
        owner=officer,
    )
    client.force_login(officer)
    resp = client.get(reverse("mel_tracking:corrective_action_list"))
    assert resp.status_code == 200
    body = resp.content.decode()
    assert "Corrective actions" in body
    assert "Fix data pipeline" in body


def test_compliance_alert_form_renders(client, officer):
    client.force_login(officer)
    resp = client.get(reverse("mel_reports:compliance_alert_create"))
    assert resp.status_code == 200
    assert b"Record a compliance issue" in resp.content


def test_scheduled_reports_carries_tab_strip(client, officer):
    client.force_login(officer)
    resp = client.get(reverse("mel_reports:scheduled_reports"))
    assert resp.status_code == 200
    body = resp.content.decode()
    assert "Schedules" in body and "Compliance" in body  # tab strip present


def test_topnav_lists_srs_surfaces(client, officer):
    client.force_login(officer)
    resp = client.get(reverse("core:dashboard"))
    assert resp.status_code == 200
    body = resp.content.decode()
    for label in (
        "Strategic Objectives",
        "Data validation",
        "Compliance &amp; actions",
        "Reports &amp; Feedback",
    ):
        assert label in body, f"topnav missing {label}"


def test_indicator_list_header_says_indicators(client, officer, framework):
    client.force_login(officer)
    resp = client.get(reverse("mel_indicators:indicator_list"))
    assert resp.status_code == 200
    body = resp.content.decode()
    assert "KPI framework" not in body
