from __future__ import annotations

import pytest
from django.contrib.auth import get_user_model

from apps.alumni.profiles.models import AlumniProfile
from apps.alumni.profiles.search import search_alumni
from apps.core.authentication.models import UserProfile

User = get_user_model()


def _make_alumnus(*, first, last, employer="", position="", headline="", tags=None, country=""):
    user = User.objects.create_user(
        email=f"{first.lower()}.{last.lower()}@example.com", password="pw"
    )
    user.first_name, user.last_name = first, last
    user.save()
    if country:
        UserProfile.objects.update_or_create(user=user, defaults={"country": country})
    return AlumniProfile.objects.create(
        user=user,
        current_employer=employer,
        current_position=position,
        headline=headline,
        expertise_tags=tags or [],
        visibility_consent=True,
    )


@pytest.mark.django_db
def test_search_vector_populated_by_trigger():
    p = _make_alumnus(
        first="Aisha",
        last="Mwangi",
        employer="Kenya Agronomy Council",
        position="Research lead",
        headline="Soil systems for smallholders",
        tags=["agronomy", "soil"],
    )
    p.refresh_from_db()
    # Trigger fires on insert — search_vector must be non-null + queryable.
    matches = list(search_alumni(query="agronomy"))
    assert p in matches


@pytest.mark.django_db
def test_quoted_phrase_matches_exact():
    target = _make_alumnus(
        first="Boris",
        last="Okello",
        employer="Climate Initiative",
        position="Programme officer",
        headline="climate resilience for farmers",
        tags=["climate", "policy"],
    )
    _make_alumnus(
        first="Cindy",
        last="Nkurunziza",
        employer="Soil Lab",
        position="Technician",
        headline="soil science",
        tags=["agronomy"],
    )
    results = list(search_alumni(query='"climate resilience"'))
    assert target in results


@pytest.mark.django_db
def test_or_returns_union():
    a = _make_alumnus(
        first="Daniel",
        last="Asante",
        headline="agronomy lead",
        tags=["agronomy"],
    )
    b = _make_alumnus(
        first="Eunice",
        last="Banda",
        headline="policy researcher",
        tags=["policy"],
    )
    _make_alumnus(
        first="Faisal",
        last="Cheruiyot",
        headline="finance specialist",
        tags=["finance"],
    )
    results = list(search_alumni(query="agronomy OR policy"))
    assert a in results and b in results
    assert len(results) == 2


@pytest.mark.django_db
def test_negative_operator_excludes_matches():
    keep = _make_alumnus(
        first="Grace",
        last="Mubarak",
        headline="agronomy in Kenya",
        tags=["agronomy"],
    )
    drop = _make_alumnus(
        first="Henry",
        last="Iqbal",
        headline="agronomy in Uganda focus",
        tags=["agronomy"],
    )
    results = list(search_alumni(query="agronomy -uganda"))
    assert keep in results
    assert drop not in results


@pytest.mark.django_db
def test_visibility_gate_excludes_non_consenting():
    target = _make_alumnus(
        first="Iris",
        last="Jaba",
        headline="agronomy lead",
        tags=["agronomy"],
    )
    target.visibility_consent = False
    target.save()
    results = list(search_alumni(query="agronomy"))
    assert target not in results


@pytest.mark.django_db
def test_combined_keyword_and_country_filter_narrows():
    a = _make_alumnus(
        first="Joy",
        last="Kamau",
        headline="agronomy in Kenya",
        tags=["agronomy"],
        country="Kenya",
    )
    _make_alumnus(
        first="Kiprop",
        last="Lang",
        headline="agronomy in Uganda",
        tags=["agronomy"],
        country="Uganda",
    )
    results = list(search_alumni(query="agronomy", country="Kenya"))
    assert a in results
    assert len(results) == 1
