"""
Tests for CSS Extraction (REQ-tv-d00002).

Each test function documents which assertion it verifies in its docstring.
The Elspais reporter extracts these references for traceability.
"""

from pathlib import Path

import pytest


class TestCSSFileLocation:
    """Tests for CSS file extraction location."""

    def test_css_extracted_to_styles_file(self):
        """
        REQ-tv-d00002-A: All CSS rules SHALL be extracted from Python string
        literals to a standalone `styles.css` file located at
        `templates/partials/styles.css`.
        """
        import trace_view.html as html_module
        html_path = Path(html_module.__file__).parent
        styles_path = html_path / "templates" / "partials" / "styles.css"

        assert styles_path.exists(), f"styles.css must exist at {styles_path}"
        assert styles_path.is_file(), "styles.css must be a file"

        content = styles_path.read_text()
        assert len(content) > 0, "styles.css must not be empty"


class TestCSSContent:
    """Tests for CSS content completeness."""

    def test_css_contains_all_original_methods_styles(self):
        """
        REQ-tv-d00002-B: The CSS file SHALL contain all styling currently
        generated by the following methods: `_generate_side_panel_css()`,
        `_generate_code_viewer_css()`, `_generate_legend_modal_css()`,
        and `_generate_file_picker_modal_css()`.
        """
        import trace_view.html as html_module
        html_path = Path(html_module.__file__).parent
        styles_path = html_path / "templates" / "partials" / "styles.css"

        content = styles_path.read_text()

        # Key selectors that should be present from each original method
        # Side panel (uses .side-panel class)
        assert ".side-panel" in content or "#req-panel" in content, \
            "Missing side panel styles"
        assert ".req-card" in content, "Missing requirement card styles"

        # Code viewer
        assert ".code-viewer" in content or "#code-viewer" in content, \
            "Missing code viewer styles"

        # Legend modal
        assert ".legend" in content or "legend" in content.lower(), \
            "Missing legend modal styles"

        # File picker modal
        assert ".file-picker" in content or "file-picker" in content, \
            "Missing file picker modal styles"


class TestCSSValidity:
    """Tests for CSS validity and IDE support."""

    def test_css_is_valid_document(self):
        """
        REQ-tv-d00002-C: The CSS file SHALL be a valid CSS document that can
        be parsed by standard CSS tools and linters.
        """
        import trace_view.html as html_module
        html_path = Path(html_module.__file__).parent
        styles_path = html_path / "templates" / "partials" / "styles.css"

        content = styles_path.read_text()

        # Basic validity checks
        # Count braces - should be balanced
        open_braces = content.count('{')
        close_braces = content.count('}')
        assert open_braces == close_braces, \
            f"Unbalanced braces: {open_braces} open, {close_braces} close"

        # Should not contain Python string artifacts
        assert '"""' not in content, "CSS should not contain Python docstrings"
        assert "'''" not in content, "CSS should not contain Python strings"
        assert "f'" not in content and 'f"' not in content, \
            "CSS should not contain Python f-strings"

    def test_css_has_proper_structure_for_ide(self):
        """
        REQ-tv-d00002-D: The CSS file SHALL be readable by IDEs with proper
        syntax highlighting and autocomplete support.
        """
        import trace_view.html as html_module
        html_path = Path(html_module.__file__).parent
        styles_path = html_path / "templates" / "partials" / "styles.css"

        content = styles_path.read_text()

        # File should have proper CSS structure
        # At least one rule with selector and properties
        assert '{' in content and '}' in content, "Must have CSS rules"
        assert ':' in content, "Must have CSS properties"
        assert ';' in content, "Must have CSS property terminators"


class TestCSSLoading:
    """Tests for CSS loading at render time."""

    def test_css_loaded_at_render_time(self, htmlerator):
        """
        REQ-tv-d00002-E: CSS content SHALL be loaded from the file at
        template render time.
        """
        html = htmlerator.generate()

        # CSS should be present in the generated HTML
        assert "<style>" in html.lower() or "<style " in html.lower(), \
            "Generated HTML must contain style tags"

        # Should contain actual CSS content
        import trace_view.html as html_module
        html_path = Path(html_module.__file__).parent
        styles_path = html_path / "templates" / "partials" / "styles.css"
        css_content = styles_path.read_text()

        # At least some CSS selectors should be in the output
        # (checking a few key selectors)
        assert ".container" in html or ".req-item" in html or ".badge" in html, \
            "CSS content should be embedded in HTML"


class TestCSSEquivalence:
    """Tests for visual equivalence with original."""

    def test_css_produces_identical_output(self, htmlerator):
        """
        REQ-tv-d00002-F: The extracted CSS SHALL produce visually identical
        output to the current inline CSS generation.
        """
        # This is a regression test - output should match baseline
        # For now, verify that the key layout classes are present
        html = htmlerator.generate(embed_content=True)

        # Key layout elements that must be styled correctly
        key_classes = [
            ".app-layout",
            ".main-content",
            ".container",
            ".req-item",
            ".req-header",
            ".badge",
        ]

        import trace_view.html as html_module
        html_path = Path(html_module.__file__).parent
        styles_path = html_path / "templates" / "partials" / "styles.css"
        css_content = styles_path.read_text()

        for cls in key_classes:
            assert cls in css_content, f"Missing key class: {cls}"


class TestNoDuplication:
    """Tests for no CSS duplication."""

    def test_no_duplicate_css_between_file_and_inline(self, htmlerator):
        """
        REQ-tv-d00002-G: CSS selectors and rules SHALL NOT be duplicated
        between the extracted file and any remaining inline styles.
        """
        html = htmlerator.generate()

        # Count style tag occurrences
        import re
        style_matches = re.findall(r'<style[^>]*>(.*?)</style>', html, re.DOTALL | re.IGNORECASE)

        if len(style_matches) > 1:
            # If there are multiple style blocks, verify no duplication
            all_selectors = []
            for style_content in style_matches:
                # Extract selectors (simplified check)
                selectors = re.findall(r'([.#]?[\w-]+)\s*\{', style_content)
                all_selectors.extend(selectors)

            # Check for duplicates
            seen = set()
            for selector in all_selectors:
                assert selector not in seen, f"Duplicate selector: {selector}"
                seen.add(selector)


class TestCSSFormatting:
    """Tests for CSS formatting standards."""

    def test_css_uses_consistent_formatting(self):
        """
        REQ-tv-d00002-H: The CSS file SHALL use consistent formatting:
        4-space indentation, one property per line, and blank lines
        between rule blocks.
        """
        import trace_view.html as html_module
        html_path = Path(html_module.__file__).parent
        styles_path = html_path / "templates" / "partials" / "styles.css"

        content = styles_path.read_text()
        lines = content.split('\n')

        # Check for 4-space indentation (at least some lines should use it)
        indented_lines = [l for l in lines if l.startswith('    ') and not l.startswith('     ')]
        assert len(indented_lines) > 0, "Should use 4-space indentation"

        # Properties should generally be on separate lines
        # Count lines with multiple property declarations
        multi_prop_lines = [l for l in lines if l.count(':') > 1 and l.count(';') > 1]
        # Allow some, but most should be one per line
        assert len(multi_prop_lines) < len(lines) * 0.1, \
            "Most properties should be on separate lines"
