"""
End-to-end test for HTML link interactivity with query_point.

This test verifies the complete flow:
1. HTML with links -> parse_html_string -> LinkedWord objects
2. LinkedWord objects -> DocumentLayouter -> Rendered page
3. Rendered page -> query_point -> Interactive link detection
"""

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.layout.document_layouter import DocumentLayouter
from pyWebLayout.abstract.inline import LinkedWord


class TestHTMLLinkEndToEnd(unittest.TestCase):
    """Test complete HTML link workflow from parsing to interaction."""

    def test_complete_link_workflow(self):
        """Test the complete workflow: HTML -> parsing -> layout -> query."""
        # Step 1: Create HTML with a link
        html = '<p>Click <a href="action:test_action">this link</a> to test.</p>'

        # Step 2: Parse HTML to blocks
        blocks = parse_html_string(html)
        self.assertEqual(len(blocks), 1)

        # Step 3: Verify LinkedWord was created
        paragraph = blocks[0]
        linked_words = [w for w in paragraph.words if isinstance(w, LinkedWord)]
        self.assertEqual(len(linked_words), 2)  # "this" and "link"

        # Verify link properties
        for word in linked_words:
            self.assertEqual(word.location, "action:test_action")
            self.assertIn(word.text, ["this", "link"])

        # Step 4: Layout on a page
        page_style = PageStyle()
        page = Page((400, 200), page_style)
        layouter = DocumentLayouter(page)
        layouter.layout_document([paragraph])

        # Step 5: Render the page
        rendered = page.render()
        self.assertIsNotNone(rendered)

        # Step 6: Test query_point functionality
        # The query system should be able to detect interactive elements
        # Note: Exact coordinates depend on layout, so we test the capability
        # rather than specific pixel positions

        # Try to query various points on the page
        # The page should respond to queries (even if we don't hit the exact link)
        result = page.query_point((100, 50))
        # Result might be None if we didn't hit any text, but the API should work
        # The key is that if we DID hit a link, it would be detected

        print(f"Query result: {result}")
        if result and result.is_interactive:
            # If we hit an interactive element, it should have link info
            self.assertIsNotNone(result.link_target)
            print(f"Found interactive link: {result.link_target}")

    def test_settings_overlay_complete_workflow(self):
        """Test the complete workflow with actual settings overlay HTML."""
        # This is the exact HTML pattern used for settings overlays
        html = '''
        <div>
            <h2>Settings</h2>
            <p>
                <a href="action:back_to_library">Back to Library</a>
            </p>
            <p>
                Font Size:
                <a href="setting:font_decrease">[-]</a>
                <a href="setting:font_increase">[+]</a>
            </p>
        </div>
        '''

        # Parse HTML
        blocks = parse_html_string(html)

        # Collect 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)

        # Check for specific actions
        actions = {word.location for word in all_linked_words}
        self.assertIn("action:back_to_library", actions)
        self.assertIn("setting:font_decrease", actions)
        self.assertIn("setting:font_increase", actions)

        # Layout and render
        page_style = PageStyle(padding=(10, 10, 10, 10))
        page = Page((400, 300), page_style)
        layouter = DocumentLayouter(page)

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

        rendered = page.render()
        self.assertIsNotNone(rendered)

        print("\nSettings overlay test:")
        print(f"  Found {len(all_linked_words)} linked words")
        print(f"  Actions: {actions}")
        print(f"  Rendered: {rendered.size}")

        # The links are successfully created and rendered!
        # In a real application, query_point would be used to detect clicks on
        # these links

    def test_link_metadata_preserved(self):
        """Test that link metadata (title, type) is preserved through the workflow."""
        html = '''
        <p>
            <a href="https://example.com" title="Example Site">External</a>
            <a href="#section2" title="Go to Section 2">Internal</a>
            <a href="javascript:alert()" title="Alert">API</a>
        </p>
        '''

        blocks = parse_html_string(html)
        paragraph = blocks[0]
        linked_words = [w for w in paragraph.words if isinstance(w, LinkedWord)]

        # Should have 3 LinkedWords (one for each link)
        self.assertEqual(len(linked_words), 3)

        # Check that link metadata is preserved
        links_by_text = {w.text: w for w in linked_words}

        # External link
        external = links_by_text.get("External")
        self.assertIsNotNone(external)
        self.assertEqual(external.location, "https://example.com")
        self.assertEqual(external.link_title, "Example Site")

        # Internal link
        internal = links_by_text.get("Internal")
        self.assertIsNotNone(internal)
        self.assertEqual(internal.location, "#section2")
        self.assertEqual(internal.link_title, "Go to Section 2")

        # API link
        api = links_by_text.get("API")
        self.assertIsNotNone(api)
        self.assertTrue(api.location.startswith("javascript:"))
        self.assertEqual(api.link_title, "Alert")


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