"""ITs for the voice mute-persistence endpoint (POST /voice/mute).

Mute is stamped on `User.voice_muted_at` so a my-sea voice mute survives in-sea
navigation/refresh + anchors the 3-min auto-disconnect window (user-spec
2026-05-30). The endpoint just sets/clears the timestamp; the 3-min enforcement
+ rejoin-mute live client-side (burger-btn.js).
"""

import json

from django.test import TestCase
from django.urls import reverse
from django.utils import timezone

from apps.lyric.models import User


class VoiceMuteViewTest(TestCase):
    def setUp(self):
        self.user = User.objects.create(email="mute@test.io", username="muter")
        self.client.force_login(self.user)
        self.url = reverse("voice_mute")

    def _post(self, muted):
        return self.client.post(
            self.url, data=json.dumps({"muted": muted}),
            content_type="application/json")

    def test_requires_login(self):
        self.client.logout()
        self.assertEqual(self._post(True).status_code, 302)

    def test_get_returns_405(self):
        self.assertEqual(self.client.get(self.url).status_code, 405)

    def test_invalid_json_returns_400(self):
        resp = self.client.post(self.url, data="not json",
                                content_type="application/json")
        self.assertEqual(resp.status_code, 400)

    def test_mute_true_stamps_timestamp(self):
        before = timezone.now()
        resp = self._post(True)
        self.assertEqual(resp.status_code, 200)
        self.user.refresh_from_db()
        self.assertIsNotNone(self.user.voice_muted_at)
        self.assertGreaterEqual(self.user.voice_muted_at, before)
        # Response echoes the ISO timestamp for the client's 3-min window.
        self.assertEqual(
            resp.json()["muted_at"], self.user.voice_muted_at.isoformat())

    def test_mute_false_clears_timestamp(self):
        self.user.voice_muted_at = timezone.now()
        self.user.save(update_fields=["voice_muted_at"])
        resp = self._post(False)
        self.assertEqual(resp.status_code, 200)
        self.user.refresh_from_db()
        self.assertIsNone(self.user.voice_muted_at)
        self.assertIsNone(resp.json()["muted_at"])

    def test_re_mute_restamps_now(self):
        # Re-muting after an earlier mute restarts the 3-min window (a fresh
        # `now`), the intended behaviour for an unmute→re-mute.
        old = timezone.now() - timezone.timedelta(minutes=2)
        self.user.voice_muted_at = old
        self.user.save(update_fields=["voice_muted_at"])
        self._post(True)
        self.user.refresh_from_db()
        self.assertGreater(self.user.voice_muted_at, old)

    def test_missing_muted_key_treated_as_false(self):
        self.user.voice_muted_at = timezone.now()
        self.user.save(update_fields=["voice_muted_at"])
        resp = self.client.post(self.url, data=json.dumps({}),
                                content_type="application/json")
        self.assertEqual(resp.status_code, 200)
        self.user.refresh_from_db()
        self.assertIsNone(self.user.voice_muted_at)
