"""
Test HTML link interactivity when rendering pages.

This test verifies that HTML links parsed via parse_html_string() are
properly interactive and can be queried/detected when rendered on a page.
"""

import unittest
from pyWebLayout.io.readers.html_extraction import parse_html_string
from pyWebLayout.concrete.page import Page
from pyWebLayout.style.page_style import PageStyle
from pyWebLayout.abstract.inline import LinkedWord


class TestHTMLLinkInteractivity(unittest.TestCase):
    """Test that HTML links are interactive when rendered."""

    def test_simple_link_parsing(self):
        """Test that parse_html_string creates LinkedWord objects for links."""
        html = '''
        <div>
            <p>Click <a href="action:back_to_library">here</a> to go back.</p>
            <p>Or visit <a href="setting:font_increase">this setting</a>.</p>
        </div>
        '''

        blocks = parse_html_string(html)

        # Should have 2 paragraphs
        self.assertEqual(len(blocks), 2)

        # First paragraph - check for LinkedWord
        para1_words = list(blocks[0].words)
        linked_words_1 = [w for w in para1_words if isinstance(w, LinkedWord)]

        # "here" should be a LinkedWord
        self.assertEqual(len(linked_words_1), 1)
        self.assertEqual(linked_words_1[0].text, "here")
        self.assertEqual(linked_words_1[0].location, "action:back_to_library")

        # Second paragraph
        para2_words = list(blocks[1].words)
        linked_words_2 = [w for w in para2_words if isinstance(w, LinkedWord)]

        # "this" and "setting" should be LinkedWords
        self.assertEqual(len(linked_words_2), 2)
        link_texts = [w.text for w in linked_words_2]
        self.assertIn("this", link_texts)
        self.assertIn("setting", link_texts)

    def test_link_rendering_on_page(self):
        """Test that links are properly rendered and detectable on a page."""
        from pyWebLayout.layout.document_layouter import DocumentLayouter

        html = '''
        <div>
            <h1>Settings</h1>
            <p>Font Size: <a href="setting:font_decrease">-</a> | <a href="setting:font_increase">+</a></p>
            <p><a href="action:back_to_library">Back to Library</a></p>
        </div>
        '''

        blocks = parse_html_string(html)

        # Create a page and use DocumentLayouter to properly layout blocks
        page_style = PageStyle()
        page = Page((600, 800), page_style)
        layouter = DocumentLayouter(page)

        # Layout all blocks
        for block in blocks:
            layouter.layout_document([block])

        # Render the page
        rendered_image = page.render()

        # Verify the page rendered
        self.assertIsNotNone(rendered_image)
        self.assertEqual(rendered_image.size, (600, 800))

        # Now verify we can detect the links via query_point
        # We need to find the positions of the linked words
        found_links = []

        # Scan the blocks for LinkedWords
        for block in blocks:
            if hasattr(block, 'words'):
                for word in block.words:
                    if isinstance(word, LinkedWord):
                        found_links.append({
                            'text': word.text,
                            'location': word.location,
                            'link_type': word.link_type
                        })

        # Verify we found the expected links
        # -, +, Back, to, Library (5 LinkedWords total)
        self.assertGreater(len(found_links), 0, "Should find at least some LinkedWords")

        link_locations = [link['location'] for link in found_links]
        self.assertIn("setting:font_decrease", link_locations)
        self.assertIn("setting:font_increase", link_locations)
        self.assertIn("action:back_to_library", link_locations)

    def test_link_query_point_detection(self):
        """Test that query_point can detect links on a rendered page."""
        from pyWebLayout.layout.document_layouter import DocumentLayouter

        html = '''
        <p>Click <a href="action:test">here</a> to test.</p>
        '''

        blocks = parse_html_string(html)

        # Create a page
        page_style = PageStyle()
        page = Page((400, 200), page_style)
        layouter = DocumentLayouter(page)

        # Layout the block
        for block in blocks:
            layouter.layout_document([block])

        # Get the rendered canvas
        _ = page.draw  # Ensure canvas exists

        # Find the LinkedWord in the blocks
        link_word = None
        for block in blocks:
            if hasattr(block, 'words'):
                for word in block.words:
                    if isinstance(word, LinkedWord) and word.location == "action:test":
                        link_word = word
                        break

        # Verify we found the link
        self.assertIsNotNone(link_word)
        self.assertEqual(link_word.text, "here")
        self.assertEqual(link_word.location, "action:test")

        # Test that query_point can detect the link
        # Try querying a point in the middle of the page where text should be
        # Note: The exact coordinates depend on the layout, but we can test the API
        result = page.query_point((100, 50))
        if result:
            # If we hit something, verify we can access its properties
            self.assertIsNotNone(result.object_type)
            # Link detection would show is_interactive=True for links
            if result.is_interactive:
                self.assertIsNotNone(result.link_target)

    def test_settings_overlay_button_html(self):
        """Test the specific HTML pattern used for settings overlay buttons."""
        # This is the pattern used in the settings overlay
        html = '''
        <div>
            <h2 style="text-align: center; font-size: 18px; font-weight: bold; margin: 10px 0;">Settings</h2>
            <p style="padding: 15px; margin: 5px 0; background-color: #dc3545; text-align: center;
                      border-radius: 5px;">
                <a href="action:back_to_library"
                   style="text-decoration: none; color: white; font-weight: bold; font-size: 14px;">
                   ◄ Back to Library</a>
            </p>
            <p style="padding: 10px; margin: 5px 0; background-color: #f8f9fa; border-radius: 5px;">
                <span style="font-weight: bold;">Font Size: 100%</span><br>
                <a href="setting:font_decrease" style="text-decoration: none; color: #007bff; margin: 0 10px;">[-]</a>
                <a href="setting:font_increase" style="text-decoration: none; color: #007bff; margin: 0 10px;">[+]</a>
            </p>
        </div>
        '''

        blocks = parse_html_string(html)

        # Find all LinkedWords
        all_linked_words = []
        for block in blocks:
            if hasattr(block, 'words'):
                for word in block.words:
                    if isinstance(word, LinkedWord):
                        all_linked_words.append(word)

        # Verify we found the expected links
        self.assertGreater(
            len(all_linked_words),
            0,
            "Should find LinkedWords in settings HTML")

        # Check for specific link targets
        link_targets = {word.location for word in all_linked_words}

        self.assertIn("action:back_to_library", link_targets,
                      "Should find 'Back to Library' link")
        self.assertIn("setting:font_decrease", link_targets,
                      "Should find font decrease link")
        self.assertIn("setting:font_increase", link_targets,
                      "Should find font increase link")

        # Verify the link texts
        back_to_library_words = [w for w in all_linked_words
                                 if w.location == "action:back_to_library"]
        self.assertGreater(len(back_to_library_words), 0,
                           "Should have words linked to back_to_library action")

        # Print debug info
        print(f"\nFound {len(all_linked_words)} linked words:")
        for word in all_linked_words:
            print(f"  - '{word.text}' -> {word.location}")


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