from django.test import Client
from django.urls import reverse
from scrobbles.models import Scrobble


class TestExerciseViews:
    def test_exercise_list_anonymous_redirects(self, db):
        client = Client()
        response = client.get(reverse("workouts:exercise_list"))
        assert response.status_code == 302

    def test_exercise_list_authenticated(self, db, user, exercise):
        client = Client()
        client.force_login(user)
        response = client.get(reverse("workouts:exercise_list"))
        assert response.status_code == 200
        assert "Deadlift" in response.content.decode()

    def test_exercise_detail(self, db, user, exercise):
        client = Client()
        client.force_login(user)
        response = client.get(
            reverse("workouts:exercise_detail", kwargs={"slug": exercise.uuid})
        )
        assert response.status_code == 200
        assert "Deadlift" in response.content.decode()


class TestWorkoutRoutineViews:
    def test_routine_list(self, db, user, workout_routine, workout_scrobble):
        client = Client()
        client.force_login(user)
        response = client.get(reverse("workouts:workout_routine_list"))
        assert response.status_code == 200

    def test_routine_detail(self, db, user, workout_routine, workout_scrobble):
        client = Client()
        client.force_login(user)
        response = client.get(
            reverse(
                "workouts:workout_routine_detail",
                kwargs={"slug": workout_routine.uuid},
            )
        )
        assert response.status_code == 200
        assert "Test Routine" in response.content.decode()


class TestWorkoutScrobbleViews:
    def test_scrobble_detail_shows_workouts(self, db, user, workout_scrobble):
        client = Client()
        client.force_login(user)
        response = client.get(workout_scrobble.get_absolute_url())
        assert response.status_code == 200
        assert b"Workout Details" in response.content

    def test_scrobble_post_imperial_conversion(
        self, db, user, workout_scrobble, exercise
    ):
        user.profile.weigh_in_units = "imperial"
        user.profile.save()
        client = Client()
        client.force_login(user)
        response = client.post(
            workout_scrobble.get_absolute_url(),
            {
                "duration_minutes": "45",
                "bodyweight_kg": "180.5",
                "workouts_exercise_id": [str(exercise.id)],
                "workouts_sets": ["4"],
                "workouts_reps": ["8"],
                "workouts_weight": ["100"],
                "workouts_notes": [""],
            },
        )
        assert response.status_code == 302
        updated = Scrobble.objects.get(pk=workout_scrobble.pk)
        log = updated.log
        assert log["bodyweight_kg"] == round(180.5 * 0.45359237, 2)
        assert log["workouts"][0]["weight_kg"] == round(100 * 0.45359237, 2)

    def test_scrobble_post_metric_no_conversion(
        self, db, user, workout_scrobble, exercise
    ):
        user.profile.weigh_in_units = "metric"
        user.profile.save()
        client = Client()
        client.force_login(user)
        response = client.post(
            workout_scrobble.get_absolute_url(),
            {
                "duration_minutes": "45",
                "bodyweight_kg": "80.5",
                "workouts_exercise_id": [str(exercise.id)],
                "workouts_sets": ["4"],
                "workouts_reps": ["8"],
                "workouts_weight": ["50"],
                "workouts_notes": [""],
            },
        )
        assert response.status_code == 302
        updated = Scrobble.objects.get(pk=workout_scrobble.pk)
        log = updated.log
        assert log["bodyweight_kg"] == 80.5
        assert log["workouts"][0]["weight_kg"] == 50.0
