"""Tests for the annotations app – Bookmarks & Notes API."""

import pytest
from django.urls import reverse
from rest_framework import status
from rest_framework.test import APIClient

from apps.annotations.models import Bookmark, Note
from apps.books.models import Book, EBook
from apps.users.models import User


@pytest.fixture
def api_client() -> APIClient:
    return APIClient()


@pytest.fixture
def user() -> User:
    return User.objects.create_user(
        username="testuser",
        email="test@example.com",
        password="testpass123",
    )


@pytest.fixture
def other_user() -> User:
    return User.objects.create_user(
        username="other",
        email="other@example.com",
        password="testpass123",
    )


@pytest.fixture
def auth_client(api_client: APIClient, user: User) -> APIClient:
    api_client.force_authenticate(user=user)
    return api_client


@pytest.fixture
def book() -> Book:
    return Book.objects.create(
        title="Test Book",
        author="Test Author",
        total_pages=300,
    )


@pytest.fixture
def ebook(user: User) -> EBook:
    return EBook.objects.create(
        user=user,
        title="Test Ebook",
        author="Test Author",
        format="epub",
    )


@pytest.fixture
def bookmark(auth_client, user: User, ebook: EBook) -> Bookmark:
    return Bookmark.objects.create(
        user=user,
        ebook=ebook,
        epub_cfi="epubcfi(/6/4!/4/2,/1:0,/1:10)",
        chapter_index=2,
        chapter_title="Chapter 3",
        page=3,
        location_text="important passage",
        content="",
    )


@pytest.fixture
def note(auth_client, user: User, book: Book) -> Note:
    return Note.objects.create(
        user=user,
        book=book,
        page=15,
        location_text="highlighted section",
        content="This is my note about this section.",
    )


class TestBookmarkList:
    url = reverse("bookmark-list")

    def test_list_requires_auth(self, api_client: APIClient):
        response = api_client.get(self.url)
        assert response.status_code == status.HTTP_401_UNAUTHORIZED

    def test_list_returns_user_bookmarks_only(
        self, auth_client: APIClient, user: User, other_user: User, ebook: EBook
    ):
        Bookmark.objects.create(
            user=user,
            ebook=ebook,
            epub_cfi="epubcfi(/6/4!/4/2,/1:0,/1:5)",
            chapter_index=0,
            page=1,
        )
        other_ebook = EBook.objects.create(user=other_user, title="Other", format="epub")
        Bookmark.objects.create(
            user=other_user,
            ebook=other_ebook,
            epub_cfi="epubcfi(/6/4!/4/2,/2:0,/2:5)",
            chapter_index=0,
            page=1,
        )
        response = auth_client.get(self.url)
        assert response.status_code == status.HTTP_200_OK
        results = response.data["results"]
        assert len(results) == 1

    def test_filter_by_ebook(self, auth_client: APIClient, bookmark: Bookmark, ebook: EBook):
        response = auth_client.get(self.url, {"ebook": str(ebook.id)})
        assert response.status_code == status.HTTP_200_OK
        assert len(response.data["results"]) == 1


class TestBookmarkCreate:
    url = reverse("bookmark-list")

    def test_create_marker(self, auth_client: APIClient, ebook: EBook):
        data = {
            "ebook": ebook.id,
            "epub_cfi": "epubcfi(/6/4!/4/2,/1:0,/1:20)",
            "chapter_index": 1,
            "chapter_title": "Chapter 2",
            "location_text": "Selected text",
            "content": "My thought",
        }
        response = auth_client.post(self.url, data, format="json")
        assert response.status_code == status.HTTP_201_CREATED
        assert response.data["content"] == "My thought"
        assert response.data["ebook"] == ebook.id

    def test_create_bookmark_only_empty_content(self, auth_client: APIClient, ebook: EBook):
        data = {
            "ebook": ebook.id,
            "epub_cfi": "epubcfi(/6/4!/4/2,/3:0,/3:8)",
            "chapter_index": 0,
            "location_text": "Quote only",
            "content": "",
        }
        response = auth_client.post(self.url, data, format="json")
        assert response.status_code == status.HTTP_201_CREATED
        assert response.data["content"] == ""

    def test_duplicate_cfi_rejected(self, auth_client: APIClient, bookmark: Bookmark, ebook: EBook):
        data = {
            "ebook": ebook.id,
            "epub_cfi": bookmark.epub_cfi,
            "chapter_index": 0,
            "location_text": "dup",
        }
        response = auth_client.post(self.url, data, format="json")
        assert response.status_code == status.HTTP_400_BAD_REQUEST


class TestBookmarkDetail:
    def test_delete_bookmark(self, auth_client: APIClient, bookmark: Bookmark):
        url = reverse("bookmark-detail", args=[str(bookmark.id)])
        response = auth_client.delete(url)
        assert response.status_code == status.HTTP_204_NO_CONTENT
