"""View-level smoke tests for the assistant endpoints."""
from __future__ import annotations

import json
import uuid

import pytest
from django.test import Client
from django.urls import reverse


def _login(client, user):
    client.force_login(user)
    return client


@pytest.mark.django_db
def test_panel_requires_login():
    client = Client()
    resp = client.get(reverse("assistant:panel"))
    assert resp.status_code in (302, 403)


@pytest.mark.django_db
def test_panel_loads_for_authenticated_user(learner_user):
    client = _login(Client(), learner_user)
    resp = client.get(reverse("assistant:panel"))
    assert resp.status_code == 200
    assert b"assistant-form" in resp.content
    assert b"assistant-messages" in resp.content


@pytest.mark.django_db
def test_conversation_list_returns_history(learner_user):
    from apps.core.assistant.models import Conversation

    Conversation.objects.create(user=learner_user, title="Older chat")
    Conversation.objects.create(user=learner_user, title="Newer chat")
    client = _login(Client(), learner_user)
    resp = client.get(reverse("assistant:conversation_list"))
    assert resp.status_code == 200
    body = resp.content.decode()
    assert "Older chat" in body and "Newer chat" in body


@pytest.mark.django_db
def test_conversation_create_returns_chat_panel(learner_user):
    client = _login(Client(), learner_user)
    resp = client.post(reverse("assistant:conversation_create"))
    assert resp.status_code == 200
    assert b"assistant-form" in resp.content


@pytest.mark.django_db
def test_send_message_streams_sse_in_stub_mode(learner_user, settings):
    settings.OPENAI_API_KEY = ""
    from apps.core.assistant.models import Conversation, Message

    conv = Conversation.objects.create(user=learner_user, title="")
    client = _login(Client(), learner_user)
    resp = client.post(
        reverse("assistant:send_message", kwargs={"pk": conv.id}),
        data={"message": "Hello"},
    )
    assert resp.status_code == 200
    assert resp["Content-Type"].startswith("text/event-stream")
    body = b"".join(resp.streaming_content).decode()
    assert "event: user_saved" in body
    assert "event: token" in body
    assert "event: done" in body
    assert Message.objects.filter(conversation=conv, role="user").count() == 1
    assert Message.objects.filter(conversation=conv, role="assistant").count() == 1
    conv.refresh_from_db()
    assert conv.title  # auto-derived


@pytest.mark.django_db
def test_send_message_rejects_empty(learner_user):
    from apps.core.assistant.models import Conversation

    conv = Conversation.objects.create(user=learner_user, title="")
    client = _login(Client(), learner_user)
    resp = client.post(
        reverse("assistant:send_message", kwargs={"pk": conv.id}),
        data={"message": "   "},
    )
    assert resp.status_code == 400


@pytest.mark.django_db
def test_send_message_404_for_other_users_conversation(learner_user, alumni_user):
    from apps.core.assistant.models import Conversation

    conv = Conversation.objects.create(user=alumni_user, title="not yours")
    client = _login(Client(), learner_user)
    resp = client.post(
        reverse("assistant:send_message", kwargs={"pk": conv.id}),
        data={"message": "Hi"},
    )
    assert resp.status_code == 404


@pytest.mark.django_db
def test_rate_limit_returns_429(learner_user, settings, monkeypatch):
    settings.OPENAI_API_KEY = ""
    from apps.core.assistant.models import Conversation

    monkeypatch.setattr(
        "apps.core.assistant.views.check_and_consume",
        lambda user, **kw: False,
    )
    conv = Conversation.objects.create(user=learner_user, title="")
    client = _login(Client(), learner_user)
    resp = client.post(
        reverse("assistant:send_message", kwargs={"pk": conv.id}),
        data={"message": "Hello"},
    )
    assert resp.status_code == 429
