from bs4 import BeautifulSoup
from django.urls import reverse
from generic.models import UserProfile, UserGrades
from django.contrib.auth.models import Group

import pytest


@pytest.fixture
def create_cid_manager(db, django_user_model):
    user = django_user_model.objects.create_user(
        "cidmanager", "test@test.com", "password"
    )
    g = Group.objects.create(name="cid_user_manager")
    g.save()
    user.groups.add(g)
    return


@pytest.fixture
def create_user_grades(db):
    for i in range(1, 6):
        UserGrades.objects.create(name=f"ST{i}")


@pytest.fixture
def create_users(db, django_user_model, create_user_grades):
    users = [
        ("user1", "ST1", "email@email.com"),
        ("user2", "ST1", "email@email.com"),
        ("user3", "ST2", "email@email.com"),
        ("user4", "ST3", "email@email.com"),
    ]

    for name, grade, email in users:
        user = django_user_model.objects.create_user(name, email, "password")

        user.userprofile.grade = UserGrades.objects.get(name=grade)
        user.userprofile.peninsula_trainee = True
        user.userprofile.save()


def test_trainee_stuff(client, create_cid_manager, create_users):
    print(UserProfile.objects.all().count())

    assert UserProfile.objects.all().count() == 5
    print(UserProfile.objects.filter(peninsula_trainee=True))
    assert UserProfile.objects.filter(peninsula_trainee=True).count() == 4

    response = client.get(reverse(f"trainees"))
    assert response.status_code == 403

    client.login(username="user1", password="password")

    response = client.get(reverse(f"trainees"))
    assert response.status_code == 403

    client.login(username="cidmanager", password="password")

    response = client.get(reverse(f"trainees"))
    assert response.status_code == 200

    trainee_rows = BeautifulSoup(response.content, "html.parser").find_all(
        "tr", {"class": "trainee"}
    )
    print(trainee_rows)

    assert (
        len(trainee_rows) == UserProfile.objects.filter(peninsula_trainee=True).count()
    )


def test_bulk_edit_groups(client, create_cid_manager, create_users):
    from generic.models import UserUserGroup
    from django.contrib.auth import get_user_model
    User = get_user_model()

    client.login(username="cidmanager", password="password")

    group = UserUserGroup.objects.create(name="Test Group")

    user1 = User.objects.get(username="user1")
    user2 = User.objects.get(username="user2")

    # Bulk add to group
    response = client.post(
        reverse("generic:users_bulk_edit"),
        data={"selection": [user1.pk, user2.pk]},
        HTTP_HX_REQUEST="true",
        HTTP_HX_TRIGGER=f"add-group--{group.id}"
    )

    assert response.status_code == 200
    assert "Group added" in response.content.decode()
    assert "alert alert-success" in response.content.decode()

    user1.refresh_from_db()
    user2.refresh_from_db()
    assert group in user1.user_groups.all()
    assert group in user2.user_groups.all()

    # Bulk remove from group
    response = client.post(
        reverse("generic:users_bulk_edit"),
        data={"selection": [user1.pk, user2.pk]},
        HTTP_HX_REQUEST="true",
        HTTP_HX_TRIGGER=f"remove-group--{group.id}"
    )

    assert response.status_code == 200
    assert "Group removed" in response.content.decode()
    assert "alert alert-success" in response.content.decode()

    user1.refresh_from_db()
    user2.refresh_from_db()
    assert group not in user1.user_groups.all()
    assert group not in user2.user_groups.all()


def test_user_not_trainee_htmx(client, create_cid_manager, create_users):
    from django.contrib.auth import get_user_model
    User = get_user_model()

    client.login(username="cidmanager", password="password")
    user2 = User.objects.get(username="user2")
    assert user2.userprofile.peninsula_trainee is True

    # Call view via HTMX
    response = client.get(
        reverse("generic:user_not_trainee", kwargs={"user_id": user2.pk}),
        HTTP_HX_REQUEST="true"
    )

    assert response.status_code == 200
    assert response.content == b""

    user2.refresh_from_db()
    assert user2.userprofile.peninsula_trainee is False
