"""
Integration tests for EbookReader highlighting functionality.

Tests the highlighting API in EbookReader including:
- highlight_word()
- highlight_selection()
- remove_highlight()
- list_highlights()
- get_highlights_for_current_page()
- clear_highlights()
- Highlight rendering on pages
"""

import unittest
import tempfile
import shutil
from pathlib import Path

from PIL import Image

from dreader.application import EbookReader
from pyWebLayout.core.highlight import HighlightColor


class TestEbookReaderHighlighting(unittest.TestCase):
    """Test EbookReader highlighting API"""

    def setUp(self):
        """Create temporary directories and reader"""
        self.temp_dir = tempfile.mkdtemp()
        self.bookmarks_dir = Path(self.temp_dir) / "bookmarks"
        self.highlights_dir = Path(self.temp_dir) / "highlights"

        self.reader = EbookReader(
            page_size=(800, 1000),
            bookmarks_dir=str(self.bookmarks_dir),
            highlights_dir=str(self.highlights_dir)
        )

    def tearDown(self):
        """Clean up"""
        self.reader.close()
        shutil.rmtree(self.temp_dir)

    def test_highlight_manager_not_initialized_before_load(self):
        """Test that highlight manager is None before loading a book"""
        self.assertIsNone(self.reader.highlight_manager)

    def test_highlight_manager_initialized_after_load(self):
        """Test that highlight manager is initialized after loading"""
        success = self.reader.load_epub("tests/data/test.epub")
        self.assertTrue(success)
        self.assertIsNotNone(self.reader.highlight_manager)
        self.assertEqual(self.reader.highlight_manager.document_id, "test")

    def test_highlight_word_without_book(self):
        """Test highlighting returns None when no book loaded"""
        highlight_id = self.reader.highlight_word(100, 100)
        self.assertIsNone(highlight_id)

    def test_highlight_word(self):
        """Test highlighting a word at a pixel location"""
        success = self.reader.load_epub("tests/data/test.epub")
        self.assertTrue(success)

        # Get a page to ensure content is rendered
        page_img = self.reader.get_current_page()
        self.assertIsNotNone(page_img)

        # Try to highlight a word (coordinates may not hit text in test)
        highlight_id = self.reader.highlight_word(
            200, 300,
            color=HighlightColor.YELLOW.value,
            note="Test highlight"
        )

        # If we hit text, should return an ID
        if highlight_id:
            self.assertIsInstance(highlight_id, str)
            self.assertGreater(len(highlight_id), 0)

            # Verify it was added
            highlights = self.reader.list_highlights()
            self.assertGreater(len(highlights), 0)

    def test_highlight_selection(self):
        """Test highlighting a range of words"""
        success = self.reader.load_epub("tests/data/test.epub")
        self.assertTrue(success)

        # Get a page
        page_img = self.reader.get_current_page()
        self.assertIsNotNone(page_img)

        # Try to highlight a selection
        highlight_id = self.reader.highlight_selection(
            start=(100, 200),
            end=(400, 250),
            color=HighlightColor.BLUE.value,
            tags=["selection", "test"]
        )

        # If selection hit text, should return an ID
        if highlight_id:
            self.assertIsInstance(highlight_id, str)

            highlights = self.reader.list_highlights()
            found = False
            for h in highlights:
                if h.id == highlight_id:
                    found = True
                    self.assertEqual(h.color, HighlightColor.BLUE.value)
                    self.assertIn("selection", h.tags)
                    break
            self.assertTrue(found)

    def test_list_highlights_empty(self):
        """Test listing highlights when none exist"""
        success = self.reader.load_epub("tests/data/test.epub")
        self.assertTrue(success)

        highlights = self.reader.list_highlights()
        self.assertEqual(len(highlights), 0)

    def test_remove_highlight(self):
        """Test removing a highlight"""
        success = self.reader.load_epub("tests/data/test.epub")
        self.assertTrue(success)

        page_img = self.reader.get_current_page()

        # Create a highlight directly via manager for testing
        from pyWebLayout.core.highlight import Highlight

        highlight = Highlight(
            id="test-highlight",
            bounds=[(100, 200, 50, 15)],
            color=HighlightColor.YELLOW.value,
            text="Test"
        )
        self.reader.highlight_manager.add_highlight(highlight)

        # Verify it exists
        self.assertEqual(len(self.reader.list_highlights()), 1)

        # Remove it
        result = self.reader.remove_highlight("test-highlight")
        self.assertTrue(result)

        # Verify it's gone
        self.assertEqual(len(self.reader.list_highlights()), 0)

    def test_remove_nonexistent_highlight(self):
        """Test removing a highlight that doesn't exist"""
        success = self.reader.load_epub("tests/data/test.epub")
        self.assertTrue(success)

        result = self.reader.remove_highlight("nonexistent")
        self.assertFalse(result)

    def test_clear_highlights(self):
        """Test clearing all highlights"""
        success = self.reader.load_epub("tests/data/test.epub")
        self.assertTrue(success)

        # Add some highlights directly
        from pyWebLayout.core.highlight import Highlight

        for i in range(3):
            highlight = Highlight(
                id=f"test-{i}",
                bounds=[(100 + i * 50, 200, 50, 15)],
                color=HighlightColor.YELLOW.value,
                text=f"Word{i}"
            )
            self.reader.highlight_manager.add_highlight(highlight)

        self.assertEqual(len(self.reader.list_highlights()), 3)

        self.reader.clear_highlights()
        self.assertEqual(len(self.reader.list_highlights()), 0)

    def test_get_highlights_for_current_page(self):
        """Test getting highlights for current page"""
        success = self.reader.load_epub("tests/data/test.epub")
        self.assertTrue(success)

        # Add highlights at different locations
        from pyWebLayout.core.highlight import Highlight

        # On page
        highlight1 = Highlight(
            id="on-page",
            bounds=[(100, 200, 50, 15)],
            color=HighlightColor.YELLOW.value,
            text="OnPage"
        )

        # Off page (beyond page height)
        highlight2 = Highlight(
            id="off-page",
            bounds=[(100, 5000, 50, 15)],
            color=HighlightColor.YELLOW.value,
            text="OffPage"
        )

        self.reader.highlight_manager.add_highlight(highlight1)
        self.reader.highlight_manager.add_highlight(highlight2)

        # Get highlights for current page
        page_highlights = self.reader.get_highlights_for_current_page()

        # Should only get the on-page highlight
        self.assertEqual(len(page_highlights), 1)
        self.assertEqual(page_highlights[0].id, "on-page")

    def test_get_current_page_with_highlights(self):
        """Test that get_current_page renders highlights"""
        success = self.reader.load_epub("tests/data/test.epub")
        self.assertTrue(success)

        # Get page without highlights
        page_no_highlights = self.reader.get_current_page(include_highlights=False)
        self.assertIsNotNone(page_no_highlights)

        # Add a highlight
        from pyWebLayout.core.highlight import Highlight

        highlight = Highlight(
            id="test",
            bounds=[(100, 200, 50, 15)],
            color=HighlightColor.YELLOW.value,
            text="Test"
        )
        self.reader.highlight_manager.add_highlight(highlight)

        # Get page with highlights
        page_with_highlights = self.reader.get_current_page(include_highlights=True)
        self.assertIsNotNone(page_with_highlights)

        # Both should be valid images
        self.assertIsInstance(page_no_highlights, Image.Image)
        self.assertIsInstance(page_with_highlights, Image.Image)

        # Should have same size
        self.assertEqual(page_no_highlights.size, page_with_highlights.size)

    def test_highlight_persistence(self):
        """Test that highlights persist across reader instances"""
        # Load book and add highlight
        success = self.reader.load_epub("tests/data/test.epub")
        self.assertTrue(success)

        from pyWebLayout.core.highlight import Highlight

        highlight = Highlight(
            id="persistent",
            bounds=[(100, 200, 50, 15)],
            color=HighlightColor.YELLOW.value,
            text="Persisted"
        )
        self.reader.highlight_manager.add_highlight(highlight)
        self.assertEqual(len(self.reader.list_highlights()), 1)

        # Close reader
        self.reader.close()

        # Create new reader for same book
        new_reader = EbookReader(
            page_size=(800, 1000),
            bookmarks_dir=str(self.bookmarks_dir),
            highlights_dir=str(self.highlights_dir)
        )
        success = new_reader.load_epub("tests/data/test.epub")
        self.assertTrue(success)

        # Should load existing highlights
        highlights = new_reader.list_highlights()
        self.assertEqual(len(highlights), 1)
        self.assertEqual(highlights[0].id, "persistent")
        self.assertEqual(highlights[0].text, "Persisted")

        new_reader.close()

    def test_render_highlights_helper(self):
        """Test the _render_highlights helper method"""
        success = self.reader.load_epub("tests/data/test.epub")
        self.assertTrue(success)

        # Create a simple test image
        from PIL import Image as PILImage
        test_img = PILImage.new('RGB', (100, 100), color='white')

        from pyWebLayout.core.highlight import Highlight

        highlights = [
            Highlight(
                id="h1",
                bounds=[(10, 10, 30, 20)],
                color=(255, 255, 0, 100),
                text="Test"
            )
        ]

        # Render highlights
        result_img = self.reader._render_highlights(test_img, highlights)

        self.assertIsNotNone(result_img)
        self.assertIsInstance(result_img, PILImage.Image)
        self.assertEqual(result_img.size, test_img.size)
        # Result should preserve the input mode
        self.assertEqual(result_img.mode, 'RGB')


if __name__ == '__main__':
    unittest.main()
