from __future__ import annotations

from datetime import date, timedelta

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

from apps.alumni.profiles.models import AlumniProfile
from apps.alumni.recognition.models import Endorsement, Spotlight, SpotlightCategory

User = get_user_model()


@pytest.fixture
def alumni_profile(db, alumni_user):
    return AlumniProfile.objects.create(user=alumni_user, visibility_consent=True)


@pytest.mark.django_db
def test_spotlight_list_is_public(client, alumni_profile, alumni_officer_user):
    Spotlight.objects.create(
        profile=alumni_profile,
        category=SpotlightCategory.NEWSLETTER,
        title="Featured today",
        citation="Some citation",
        period_label="2026",
        featured_from=date.today() - timedelta(days=1),
        featured_until=date.today() + timedelta(days=30),
        curated_by=alumni_officer_user,
    )
    resp = client.get(reverse("alumni_recognition:spotlight_list"))
    assert resp.status_code == 200
    assert b"Featured today" in resp.content


@pytest.mark.django_db
def test_endorse_view_creates_endorsement(client, alumni_profile, alumni_user):
    endorser = User.objects.create_user(email="endorser@example.com", password="pw")
    client.force_login(endorser)
    resp = client.post(
        reverse("alumni_recognition:endorse", kwargs={"profile_pk": alumni_profile.pk}),
        {
            "category": SpotlightCategory.MENTOR_OF_MONTH,
            "period_label": "2026-04",
            "citation": "Great mentor",
        },
    )
    assert resp.status_code in {302, 200}
    assert Endorsement.objects.filter(
        profile=alumni_profile, endorser=endorser, period_label="2026-04"
    ).exists()


@pytest.mark.django_db
def test_endorse_view_blocks_self_endorsement(client, alumni_profile, alumni_user):
    client.force_login(alumni_user)
    resp = client.post(
        reverse("alumni_recognition:endorse", kwargs={"profile_pk": alumni_profile.pk}),
        {
            "category": SpotlightCategory.MENTOR_OF_MONTH,
            "period_label": "2026-04",
        },
    )
    assert resp.status_code in {302, 200}
    assert not Endorsement.objects.filter(profile=alumni_profile, endorser=alumni_user).exists()


@pytest.mark.django_db
def test_cockpit_denied_for_non_staff(client, alumni_user):
    client.force_login(alumni_user)
    resp = client.get(reverse("alumni_recognition:cockpit"))
    # UserPassesTestMixin returns 403 by default
    assert resp.status_code == 403


@pytest.mark.django_db
def test_cockpit_allowed_for_alumni_officer(client, alumni_officer_user):
    client.force_login(alumni_officer_user)
    resp = client.get(reverse("alumni_recognition:cockpit"))
    assert resp.status_code == 200


@pytest.mark.django_db
def test_publish_spotlight_view_creates_row(client, alumni_profile, alumni_officer_user):
    client.force_login(alumni_officer_user)
    today = date.today()
    resp = client.post(
        reverse("alumni_recognition:publish_spotlight"),
        {
            "profile_pk": alumni_profile.pk,
            "category": SpotlightCategory.PARTNER_OF_YEAR,
            "period_label": "2026",
            "title": "Outstanding partner",
            "citation": "Their work changed soils across East Africa.",
            "featured_from": today.isoformat(),
            "featured_until": (today + timedelta(days=180)).isoformat(),
        },
    )
    assert resp.status_code in {302, 200}
    assert Spotlight.objects.filter(
        profile=alumni_profile,
        category=SpotlightCategory.PARTNER_OF_YEAR,
        period_label="2026",
    ).exists()
