#!/usr/bin/env python3
"""
Quick integration test for the main application controller.

This test verifies that all components integrate correctly without
requiring a GUI. It uses a mock HAL to simulate display/input.
"""

import sys
import asyncio
from pathlib import Path
from PIL import Image

# Add parent directory to path
sys.path.insert(0, str(Path(__file__).parent))

from dreader.main import DReaderApplication, AppConfig
from dreader.hal import DisplayHAL
from dreader.gesture import TouchEvent, GestureType


class MockDisplayHAL(DisplayHAL):
    """Mock HAL for headless testing."""

    def __init__(self):
        self.images_displayed = []
        self.events = []

    async def show_image(self, image: Image.Image):
        """Record displayed images."""
        self.images_displayed.append(image)
        print(f"  [HAL] Displayed image: {image.size}")

    async def get_touch_event(self):
        """Return queued events."""
        if self.events:
            return self.events.pop(0)
        return None

    async def set_brightness(self, level: int):
        """Mock brightness control."""
        print(f"  [HAL] Brightness set to {level}")

    def queue_event(self, event: TouchEvent):
        """Add event to queue for testing."""
        self.events.append(event)


async def test_integration():
    """Test the complete integration."""
    print("=" * 70)
    print("DReader Main Application Integration Test")
    print("=" * 70)

    # Find test library
    library_path = Path(__file__).parent / "tests" / "data" / "library-epub"

    if not library_path.exists():
        print(f"\nError: Test library not found at {library_path}")
        print("Please ensure test EPUB files exist in tests/data/library-epub/")
        return False

    print(f"\nLibrary path: {library_path}")

    # Create mock HAL
    hal = MockDisplayHAL()

    # Create config
    config = AppConfig(
        display_hal=hal,
        library_path=str(library_path),
        page_size=(800, 1200),
        auto_save_interval=999  # Don't auto-save during test
    )

    # Create application
    app = DReaderApplication(config)

    try:
        # Test 1: Start application (should show library)
        print("\n" + "-" * 70)
        print("Test 1: Starting application")
        print("-" * 70)
        await app.start()
        print(f"✓ Application started")
        print(f"  Current mode: {app.get_current_mode()}")
        print(f"  Images displayed: {len(hal.images_displayed)}")

        assert len(hal.images_displayed) > 0, "No image displayed after start"
        assert app.get_current_mode().value == "library", "Should start in library mode"
        print("✓ Test 1 passed")

        # Test 2: Simulate tap on first book
        print("\n" + "-" * 70)
        print("Test 2: Selecting a book from library")
        print("-" * 70)

        # Tap in approximate location of first book
        tap_event = TouchEvent(GestureType.TAP, 400, 150)
        print(f"  Simulating tap at (400, 150)")

        images_before = len(hal.images_displayed)
        await app.handle_touch(tap_event)

        print(f"  Current mode: {app.get_current_mode()}")
        print(f"  New images displayed: {len(hal.images_displayed) - images_before}")

        # Should have transitioned to reading mode
        if app.get_current_mode().value == "reading":
            print("✓ Successfully entered reading mode")
            print("✓ Test 2 passed")
        else:
            print("⚠ Tap may not have hit a book (this is OK for the test)")
            print("  Manually entering reading mode for further tests...")

            # Get first book from library and enter reading mode manually
            if app.library:
                books = app.library.scan_library()
                if books:
                    await app._enter_reading_mode(books[0]['path'])
                    print(f"✓ Loaded book: {books[0]['title']}")

        # Test 3: Page navigation
        print("\n" + "-" * 70)
        print("Test 3: Page navigation")
        print("-" * 70)

        if app.get_current_mode().value == "reading":
            images_before = len(hal.images_displayed)

            # Next page (swipe left)
            swipe_event = TouchEvent(GestureType.SWIPE_LEFT, 600, 600)
            print("  Simulating swipe left (next page)")
            await app.handle_touch(swipe_event)

            print(f"  New images displayed: {len(hal.images_displayed) - images_before}")
            print("✓ Test 3 passed")
        else:
            print("⊘ Skipping (not in reading mode)")

        # Test 4: Font size change (pinch gesture)
        print("\n" + "-" * 70)
        print("Test 4: Font size adjustment")
        print("-" * 70)

        if app.get_current_mode().value == "reading":
            images_before = len(hal.images_displayed)

            # Increase font size
            pinch_event = TouchEvent(GestureType.PINCH_OUT, 400, 600)
            print("  Simulating pinch out (increase font)")
            await app.handle_touch(pinch_event)

            print(f"  New images displayed: {len(hal.images_displayed) - images_before}")
            print("✓ Test 4 passed")
        else:
            print("⊘ Skipping (not in reading mode)")

        # Test 5: State persistence check
        print("\n" + "-" * 70)
        print("Test 5: State persistence")
        print("-" * 70)

        state = app.state
        print(f"  Current mode: {state.mode}")
        print(f"  Current book: {state.current_book}")
        print(f"  Font scale: {state.settings.font_scale}")

        # Save state
        success = app.state_manager.save_state(force=True)
        if success:
            print("✓ State saved successfully")
            print("✓ Test 5 passed")
        else:
            print("✗ State save failed")
            return False

        # Test 6: Graceful shutdown
        print("\n" + "-" * 70)
        print("Test 6: Graceful shutdown")
        print("-" * 70)

        await app.shutdown()
        print("✓ Application shut down cleanly")
        print("✓ Test 6 passed")

        # Summary
        print("\n" + "=" * 70)
        print("✓ ALL TESTS PASSED")
        print("=" * 70)
        print(f"\nTotal images displayed: {len(hal.images_displayed)}")
        print(f"Final mode: {app.get_current_mode()}")
        print("\nIntegration test successful!")

        return True

    except Exception as e:
        print(f"\n✗ TEST FAILED: {e}")
        import traceback
        traceback.print_exc()
        return False


def main():
    """Main entry point."""
    success = asyncio.run(test_integration())
    sys.exit(0 if success else 1)


if __name__ == "__main__":
    main()
