"""
Sprint 44 Tests: Workspace panel close button fixes (PR #413).

Covers:
- index.html: mobile-close-btn now calls handleWorkspaceClose() instead of
  closeWorkspacePanel(), so hitting X while a file is open returns you to the
  file browser rather than collapsing the whole panel.
- boot.js: syncWorkspacePanelUI() hides #btnClearPreview (the X icon) on
  desktop when no file preview is open, eliminating the duplicate X that
  appeared alongside the chevron collapse button.
- boot.js: handleWorkspaceClose() logic — clears preview when one is visible,
  closes panel otherwise (existing function, confirmed wired to both buttons).
"""
import pathlib
import re
import unittest

REPO = pathlib.Path(__file__).parent.parent
HTML = (REPO / "static" / "index.html").read_text(encoding="utf-8")
BOOT_JS = (REPO / "static" / "boot.js").read_text(encoding="utf-8")


class TestMobileCloseButtonBehavior(unittest.TestCase):
    """mobile-close-btn must call handleWorkspaceClose(), not closeWorkspacePanel()."""

    def test_mobile_close_btn_calls_handle_workspace_close(self):
        """mobile-close-btn onclick must be handleWorkspaceClose(), not closeWorkspacePanel()."""
        m = re.search(r'class="[^"]*mobile-close-btn[^"]*"[^>]*>', HTML)
        self.assertIsNotNone(m, "mobile-close-btn element not found in index.html")
        btn_html = m.group(0)
        self.assertIn(
            'onclick="handleWorkspaceClose()"',
            btn_html,
            "mobile-close-btn must call handleWorkspaceClose() so that hitting X "
            "while a file is open closes the file first, not the whole panel",
        )

    def test_mobile_close_btn_does_not_call_close_workspace_panel_directly(self):
        """mobile-close-btn must NOT call closeWorkspacePanel() directly."""
        m = re.search(r'class="[^"]*mobile-close-btn[^"]*"[^>]*>', HTML)
        self.assertIsNotNone(m, "mobile-close-btn element not found in index.html")
        btn_html = m.group(0)
        self.assertNotIn(
            'onclick="closeWorkspacePanel()"',
            btn_html,
            "mobile-close-btn must not call closeWorkspacePanel() directly — "
            "it would bypass the two-step close logic and collapse the panel even "
            "when a file is being viewed",
        )

    def test_handle_workspace_close_defined_in_boot_js(self):
        """handleWorkspaceClose() must be defined in boot.js."""
        self.assertIn(
            "function handleWorkspaceClose()",
            BOOT_JS,
            "handleWorkspaceClose() is missing from boot.js",
        )

    def test_handle_workspace_close_clears_preview_first(self):
        """handleWorkspaceClose() must call clearPreview() when a preview is visible."""
        # The function must check for visible preview and call clearPreview
        self.assertIn(
            "clearPreview()",
            BOOT_JS,
            "handleWorkspaceClose() must call clearPreview() when preview is visible",
        )
    def test_handle_workspace_close_falls_back_to_close_panel(self):
        """handleWorkspaceClose() must call closeWorkspacePanel() as fallback."""
        # Find the function start and extract until the closing brace by scanning
        start = BOOT_JS.find("function handleWorkspaceClose()")
        self.assertNotEqual(start, -1, "handleWorkspaceClose() not found in boot.js")
        # Extract a generous window after the function start
        fn_window = BOOT_JS[start : start + 400]
        self.assertIn(
            "closeWorkspacePanel()",
            fn_window,
            "handleWorkspaceClose() must call closeWorkspacePanel() as its fallback path",
        )


class TestDesktopNoDuplicateXButton(unittest.TestCase):
    """On desktop, only one X/close control should appear at a time."""

    def test_sync_workspace_panel_ui_hides_clear_preview_on_desktop(self):
        """syncWorkspacePanelUI() must set display:none on btnClearPreview when no preview and desktop."""
        self.assertIn(
            "clearBtn.style.display",
            BOOT_JS,
            "syncWorkspacePanelUI() must control clearBtn.style.display to hide it "
            "on desktop when no file preview is open",
        )

    def test_clear_preview_hidden_when_no_preview(self):
        """The display toggle for btnClearPreview must key off hasPreview."""
        # Expect something like: clearBtn.style.display=hasPreview?'':'none'
        # or clearBtn.style.display = hasPreview ? '' : 'none'
        pattern = r"clearBtn\.style\.display\s*=\s*hasPreview"
        self.assertRegex(
            BOOT_JS,
            pattern,
            "btnClearPreview display must be conditioned on hasPreview in "
            "syncWorkspacePanelUI() to avoid a duplicate X on desktop",
        )

    def test_clear_preview_toggle_only_applied_on_desktop(self):
        """The display toggle must be guarded by !isCompact so mobile is unaffected."""
        # Expect: if(!isCompact) clearBtn.style.display=...
        pattern = r"isCompact.*clearBtn\.style\.display|clearBtn\.style\.display.*isCompact"
        self.assertRegex(
            BOOT_JS,
            pattern,
            "btnClearPreview display toggle must be guarded by isCompact so the "
            "mobile X button visibility is not accidentally affected",
        )

    def test_btnclearpreview_exists_in_html(self):
        """#btnClearPreview must still exist in the HTML (not removed)."""
        self.assertIn(
            'id="btnClearPreview"',
            HTML,
            "#btnClearPreview must remain in index.html",
        )

    def test_btncollapseWorkspacepanel_exists_in_html(self):
        """#btnCollapseWorkspacePanel (chevron) must still exist in the HTML."""
        self.assertIn(
            'id="btnCollapseWorkspacePanel"',
            HTML,
            "#btnCollapseWorkspacePanel must remain in index.html",
        )


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