"""
Tests for static file serving (CSS, JS).

This module tests that CSS and JavaScript files are properly served
through FastAPI's static files mounting.
"""
import pytest
from httpx import ASGITransport, AsyncClient

from src.server.fastapi_app import app


@pytest.fixture
async def client():
    """Create an async test client for the FastAPI app."""
    transport = ASGITransport(app=app)
    async with AsyncClient(
        transport=transport,
        base_url="http://test",
        follow_redirects=True,
    ) as ac:
        yield ac


class TestCSSFileServing:
    """Test CSS file serving functionality."""

    @pytest.mark.asyncio
    async def test_styles_css_accessible(self, client):
        """Test that styles.css is accessible."""
        response = await client.get("/static/css/styles.css")
        
        assert response.status_code == 200
        assert "text/css" in response.headers.get("content-type", "")
        assert len(response.text) > 0

    @pytest.mark.asyncio
    async def test_ux_features_css_accessible(self, client):
        """Test that ux_features.css is accessible."""
        response = await client.get("/static/css/ux_features.css")
        
        assert response.status_code == 200
        assert "text/css" in response.headers.get("content-type", "")
        assert len(response.text) > 0

    @pytest.mark.asyncio
    async def test_css_contains_expected_variables(self, client):
        """Test that CSS variables are defined in base/variables.css."""
        # Variables are now in a separate module file
        response = await client.get("/static/css/base/variables.css")
        
        assert response.status_code == 200
        content = response.text
        
        # Check for Fluent UI design system variables
        assert "--color-bg-primary:" in content
        assert "--color-accent:" in content
        assert "--font-family:" in content
        assert "--spacing-" in content
        assert "--border-radius-" in content

    @pytest.mark.asyncio
    async def test_css_contains_dark_theme_support(self, client):
        """Test that dark theme support is in base/variables.css."""
        # Dark theme variables are now in a separate module file
        response = await client.get("/static/css/base/variables.css")
        
        assert response.status_code == 200
        content = response.text
        
        # Check for dark theme variables
        assert '[data-theme="dark"]' in content

    @pytest.mark.asyncio
    async def test_css_contains_responsive_design(self, client):
        """Test that CSS files contain responsive design media queries."""
        # Responsive styles are now in utilities/responsive.css
        response = await client.get("/static/css/utilities/responsive.css")
        assert response.status_code == 200
        assert "@media" in response.text

        # Test ux_features.css
        response = await client.get("/static/css/ux_features.css")
        assert response.status_code == 200
        assert "@media" in response.text

    @pytest.mark.asyncio
    async def test_ux_features_css_contains_accessibility(self, client):
        """Test that ux_features.css contains accessibility features."""
        response = await client.get("/static/css/ux_features.css")
        
        assert response.status_code == 200
        content = response.text
        
        # Check for accessibility features
        assert ".sr-only" in content  # Screen reader only
        assert "prefers-contrast" in content  # High contrast mode
        assert ".keyboard-focus" in content  # Keyboard navigation

    @pytest.mark.asyncio
    async def test_nonexistent_css_returns_404(self, client):
        """Test that requesting a nonexistent CSS file returns 404."""
        response = await client.get("/static/css/nonexistent.css")
        # Static files might return HTML or 404, just ensure CSS exists
        assert response.status_code in [200, 404]


class TestJavaScriptFileServing:
    """Test JavaScript file serving functionality."""

    @pytest.mark.asyncio
    async def test_app_js_accessible(self, client):
        """Test that app.js is accessible."""
        response = await client.get("/static/js/app.js")
        
        # File might not exist yet, but if it does, it should be served correctly
        if response.status_code == 200:
            assert "javascript" in response.headers.get("content-type", "").lower()

    @pytest.mark.asyncio
    async def test_websocket_client_js_accessible(self, client):
        """Test that websocket_client.js is accessible."""
        response = await client.get("/static/js/websocket_client.js")
        
        # File might not exist yet, but if it does, it should be served correctly
        if response.status_code == 200:
            assert "javascript" in response.headers.get("content-type", "").lower()


class TestHTMLTemplatesCSS:
    """Test that HTML templates correctly reference CSS files."""

    @pytest.mark.asyncio
    async def test_index_page_references_css(self, client):
        """Test that index.html correctly references CSS files."""
        response = await client.get("/")
        
        assert response.status_code == 200
        content = response.text
        
        # Check for CSS references
        assert '/static/css/styles.css' in content
        assert '/static/css/ux_features.css' in content

    @pytest.mark.asyncio
    async def test_login_page_references_css(self, client):
        """Test that login.html correctly references CSS files."""
        response = await client.get("/login")
        
        assert response.status_code == 200
        content = response.text
        
        # Check for CSS reference
        assert '/static/css/styles.css' in content

    @pytest.mark.asyncio
    async def test_setup_page_references_css(self, client):
        """Test that setup.html correctly references CSS files."""
        response = await client.get("/setup")
        
        assert response.status_code == 200
        content = response.text
        
        # Check for CSS reference
        assert '/static/css/styles.css' in content

    @pytest.mark.asyncio
    async def test_queue_page_references_css(self, client):
        """Test that queue.html correctly references CSS files."""
        response = await client.get("/queue")
        
        assert response.status_code == 200
        content = response.text
        
        # Check for CSS reference
        assert '/static/css/styles.css' in content

    @pytest.mark.asyncio
    async def test_css_paths_are_absolute(self, client):
        """Test that CSS paths in templates are absolute paths."""
        pages = ["/", "/login", "/setup", "/queue"]
        
        for page in pages:
            response = await client.get(page)
            assert response.status_code == 200
            content = response.text
            
            # Ensure CSS links start with /static (absolute paths)
            if 'href="/static/css/' in content:
                # Good - using absolute paths
                assert 'href="static/css/' not in content
            elif 'href="static/css/' in content:
                msg = f"Page {page} uses relative CSS paths"
                pytest.fail(msg)


class TestCSSContentIntegrity:
    """Test CSS content integrity and structure."""

    @pytest.mark.asyncio
    async def test_styles_css_structure(self, client):
        """Test that styles.css is a modular entry point with @import statements."""
        response = await client.get("/static/css/styles.css")
        assert response.status_code == 200
        
        content = response.text
        
        # styles.css is now an entry point with @import statements
        assert "@import" in content
        
        # Check for imports of base, components, pages, and utilities
        assert 'base/' in content or "base" in content.lower()

    @pytest.mark.asyncio
    async def test_css_variables_file_structure(self, client):
        """Test that base/variables.css has proper structure."""
        response = await client.get("/static/css/base/variables.css")
        assert response.status_code == 200
        
        content = response.text
        
        # Should have CSS variable definitions
        assert ":root" in content
        
        # Should not have syntax errors (basic check)
        # Count braces - should be balanced
        open_braces = content.count("{")
        close_braces = content.count("}")
        assert open_braces == close_braces, "CSS has unbalanced braces"

    @pytest.mark.asyncio
    async def test_ux_features_css_structure(self, client):
        """Test that ux_features.css has proper structure."""
        response = await client.get("/static/css/ux_features.css")
        assert response.status_code == 200
        
        content = response.text
        
        # Should not have syntax errors (basic check)
        open_braces = content.count("{")
        close_braces = content.count("}")
        assert open_braces == close_braces, "CSS has unbalanced braces"

    @pytest.mark.asyncio
    async def test_css_file_sizes_reasonable(self, client):
        """Test that CSS files are not empty and have reasonable sizes."""
        # Test styles.css (now just @imports, so smaller)
        response = await client.get("/static/css/styles.css")
        assert response.status_code == 200
        assert len(response.text) > 100, "styles.css seems too small"
        assert len(response.text) < 500000, "styles.css seems unusually large"

        # Test variables.css (has actual content)
        response = await client.get("/static/css/base/variables.css")
        assert response.status_code == 200
        assert len(response.text) > 500, "variables.css seems too small"

        # Test ux_features.css
        response = await client.get("/static/css/ux_features.css")
        assert response.status_code == 200
        assert len(response.text) > 100, "ux_features.css seems too small"
        msg = "ux_features.css seems unusually large"
        assert len(response.text) < 100000, msg
