"""
Unit tests for example scripts.

This test suite validates that all example scripts:
1. Can be imported without errors (syntax checks, import validation)
2. Have valid import statements
3. Can run their main functions without crashing (when applicable)

This helps catch issues like:
- Incorrect import paths
- Missing dependencies
- API breakages that affect examples
"""

import unittest
import importlib.util
import sys
import os
from pathlib import Path


class TestExampleImports(unittest.TestCase):
    """Test that all example scripts can be imported successfully"""

    def setUp(self):
        """Set up test fixtures"""
        # Get the project root directory
        self.project_root = Path(__file__).parent.parent
        self.examples_dir = self.project_root / "examples"

        # Add project root to Python path if not already there
        if str(self.project_root) not in sys.path:
            sys.path.insert(0, str(self.project_root))

    def _import_module_from_file(self, file_path: Path):
        """
        Import a Python module from a file path.

        Args:
            file_path: Path to the Python file

        Returns:
            The imported module

        Raises:
            Any import errors that occur
        """
        spec = importlib.util.spec_from_file_location(file_path.stem, file_path)
        if spec is None or spec.loader is None:
            raise ImportError(f"Could not load spec for {file_path}")

        module = importlib.util.module_from_spec(spec)
        sys.modules[file_path.stem] = module
        spec.loader.exec_module(module)
        return module

    def test_word_selection_highlighting_imports(self):
        """Test word_selection_highlighting.py can be imported"""
        example_file = self.examples_dir / "word_selection_highlighting.py"
        self.assertTrue(example_file.exists(), f"Example file not found: {example_file}")

        try:
            module = self._import_module_from_file(example_file)

            # Verify key components are available
            self.assertTrue(hasattr(module, 'draw_highlight'))
            self.assertTrue(hasattr(module, 'example_1_single_word_selection'))
            self.assertTrue(hasattr(module, 'example_2_range_selection'))
            self.assertTrue(hasattr(module, 'example_3_interactive_word_lookup'))
            self.assertTrue(hasattr(module, 'example_4_multi_word_annotation'))
            self.assertTrue(hasattr(module, 'example_5_link_highlighting'))

        except ImportError as e:
            self.fail(f"Failed to import word_selection_highlighting.py: {e}")

    def test_demo_pagination_imports(self):
        """Test demo_pagination.py can be imported"""
        example_file = self.examples_dir / "demo_pagination.py"
        self.assertTrue(example_file.exists(), f"Example file not found: {example_file}")

        try:
            module = self._import_module_from_file(example_file)
            self.assertTrue(hasattr(module, 'main'))
        except ImportError as e:
            self.fail(f"Failed to import demo_pagination.py: {e}")

    def test_demo_toc_overlay_imports(self):
        """Test demo_toc_overlay.py can be imported"""
        example_file = self.examples_dir / "demo_toc_overlay.py"
        self.assertTrue(example_file.exists(), f"Example file not found: {example_file}")

        try:
            module = self._import_module_from_file(example_file)
            self.assertTrue(hasattr(module, 'main'))
        except ImportError as e:
            self.fail(f"Failed to import demo_toc_overlay.py: {e}")

    def test_demo_settings_overlay_imports(self):
        """Test demo_settings_overlay.py can be imported"""
        example_file = self.examples_dir / "demo_settings_overlay.py"
        self.assertTrue(example_file.exists(), f"Example file not found: {example_file}")

        try:
            module = self._import_module_from_file(example_file)
            self.assertTrue(hasattr(module, 'main'))
        except ImportError as e:
            self.fail(f"Failed to import demo_settings_overlay.py: {e}")

    def test_library_reading_integration_imports(self):
        """Test library_reading_integration.py can be imported"""
        example_file = self.examples_dir / "library_reading_integration.py"
        self.assertTrue(example_file.exists(), f"Example file not found: {example_file}")

        try:
            module = self._import_module_from_file(example_file)
            self.assertTrue(hasattr(module, 'main'))
            self.assertTrue(hasattr(module, 'simulate_mode_transition_workflow'))
        except ImportError as e:
            self.fail(f"Failed to import library_reading_integration.py: {e}")

    def test_all_examples_have_correct_dreader_imports(self):
        """
        Verify all example scripts use correct import paths for dreader classes.

        This test specifically checks that examples don't use outdated import paths
        like 'from dreader.application import' when they should use 'from dreader import'.
        """
        # Get all Python files in examples directory
        example_files = list(self.examples_dir.glob("*.py"))

        problematic_imports = []

        for example_file in example_files:
            # Skip __init__.py and other special files
            if example_file.name.startswith('_'):
                continue

            with open(example_file, 'r') as f:
                content = f.read()

            # Check for problematic import patterns
            if 'from pyWebLayout.io.gesture import' in content:
                problematic_imports.append(
                    f"{example_file.name}: Uses 'from pyWebLayout.io.gesture import' "
                    f"(should be 'from dreader import')"
                )

            if 'from dreader.application import EbookReader' in content:
                # This is acceptable, but check if TouchEvent/GestureType are also imported correctly
                if 'from pyWebLayout.io.gesture import TouchEvent' in content:
                    problematic_imports.append(
                        f"{example_file.name}: Mixes dreader.application and pyWebLayout.io.gesture imports"
                    )

        if problematic_imports:
            self.fail(
                "Found problematic imports in example files:\n" +
                "\n".join(f"  - {issue}" for issue in problematic_imports)
            )


class TestExampleFunctions(unittest.TestCase):
    """Test key functionality in example scripts"""

    def test_draw_highlight_function(self):
        """Test the draw_highlight function from word_selection_highlighting"""
        from PIL import Image

        # Import the module
        project_root = Path(__file__).parent.parent
        example_file = project_root / "examples" / "word_selection_highlighting.py"

        spec = importlib.util.spec_from_file_location("word_selection_highlighting", example_file)
        module = importlib.util.module_from_spec(spec)
        spec.loader.exec_module(module)

        # Create a test image
        test_image = Image.new('RGBA', (100, 100), (255, 255, 255, 255))

        # Test the draw_highlight function
        bounds = (10, 10, 50, 20)
        result = module.draw_highlight(test_image, bounds)

        # Verify the result is an image
        self.assertIsInstance(result, Image.Image)
        self.assertEqual(result.size, (100, 100))
        self.assertEqual(result.mode, 'RGBA')


class TestExampleDocumentation(unittest.TestCase):
    """Test that examples have proper documentation"""

    def test_all_examples_have_docstrings(self):
        """Verify all example scripts have module docstrings"""
        project_root = Path(__file__).parent.parent
        examples_dir = project_root / "examples"

        example_files = [
            f for f in examples_dir.glob("*.py")
            if not f.name.startswith('_') and f.name not in ['__init__.py']
        ]

        missing_docstrings = []

        for example_file in example_files:
            spec = importlib.util.spec_from_file_location(example_file.stem, example_file)
            if spec is None or spec.loader is None:
                continue

            module = importlib.util.module_from_spec(spec)
            try:
                spec.loader.exec_module(module)

                if not module.__doc__ or len(module.__doc__.strip()) < 10:
                    missing_docstrings.append(example_file.name)
            except:
                # If module can't be loaded, skip docstring check
                # (import test will catch the error)
                pass

        if missing_docstrings:
            self.fail(
                f"Examples missing proper docstrings: {', '.join(missing_docstrings)}"
            )


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