"""
Pytest configuration and fixtures for pyPhotoAlbum tests
"""

import pytest
import tempfile
import os
from pathlib import Path
from PIL import Image
from pyPhotoAlbum.models import ImageData, PlaceholderData, TextBoxData
from pyPhotoAlbum.page_layout import PageLayout, GridLayout
from pyPhotoAlbum.project import Project, Page


@pytest.fixture
def temp_image_file():
    """Create a temporary test image file"""
    with tempfile.NamedTemporaryFile(suffix=".png", delete=False) as f:
        # Create a simple test image
        img = Image.new("RGB", (100, 100), color="red")
        img.save(f.name)
        yield f.name
    # Cleanup
    try:
        os.unlink(f.name)
    except:
        pass


@pytest.fixture
def temp_dir():
    """Create a temporary directory for tests"""
    with tempfile.TemporaryDirectory() as tmpdir:
        yield tmpdir


@pytest.fixture
def sample_image_data(temp_image_file):
    """Create a sample ImageData instance"""
    return ImageData(image_path=temp_image_file, x=10.0, y=20.0, width=100.0, height=150.0)


@pytest.fixture
def sample_placeholder_data():
    """Create a sample PlaceholderData instance"""
    return PlaceholderData(placeholder_type="image", x=50.0, y=60.0, width=200.0, height=150.0)


@pytest.fixture
def sample_textbox_data():
    """Create a sample TextBoxData instance"""
    return TextBoxData(text_content="Sample Text", x=30.0, y=40.0, width=150.0, height=50.0)


@pytest.fixture
def sample_page_layout():
    """Create a sample PageLayout instance"""
    layout = PageLayout()
    return layout


@pytest.fixture
def sample_grid_layout():
    """Create a sample GridLayout instance"""
    return GridLayout(rows=2, columns=2, spacing=10.0)


@pytest.fixture
def sample_page(sample_page_layout):
    """Create a sample Page instance"""
    return Page(layout=sample_page_layout, page_number=1)


@pytest.fixture
def sample_project():
    """Create a sample Project instance"""
    return Project(name="Test Project")


@pytest.fixture
def populated_page_layout(sample_image_data, sample_placeholder_data, sample_textbox_data):
    """Create a page layout populated with various elements"""
    layout = PageLayout()
    layout.add_element(sample_image_data)
    layout.add_element(sample_placeholder_data)
    layout.add_element(sample_textbox_data)
    return layout


# GL Widget fixtures (moved from test_gl_widget_fixtures.py)

from unittest.mock import Mock, MagicMock
from PyQt6.QtCore import Qt, QPointF, QPoint
from PyQt6.QtGui import QMouseEvent, QWheelEvent


@pytest.fixture
def mock_main_window():
    """Create a mock main window with a basic project"""
    window = Mock()
    window.project = Project(name="Test Project")

    # Add a test page
    page = Page(layout=PageLayout(width=210, height=297), page_number=1)  # A4 size in mm
    window.project.pages.append(page)
    window.project.working_dpi = 96
    window.project.page_size_mm = (210, 297)
    window.project.page_spacing_mm = 10

    # Mock status bar
    window.status_bar = Mock()
    window.status_bar.showMessage = Mock()
    window.show_status = Mock()

    return window


@pytest.fixture
def sample_image_element():
    """Create a sample ImageData element for testing"""
    return ImageData(image_path="test.jpg", x=100, y=100, width=200, height=150, z_index=1)


@pytest.fixture
def sample_placeholder_element():
    """Create a sample PlaceholderData element for testing"""
    return PlaceholderData(x=50, y=50, width=100, height=100, z_index=0)


@pytest.fixture
def sample_textbox_element():
    """Create a sample TextBoxData element for testing"""
    return TextBoxData(x=10, y=10, width=180, height=50, text_content="Test Text", z_index=2)


@pytest.fixture
def mock_page_renderer():
    """Create a mock PageRenderer

    NOTE: This fixture contains simplified coordinate conversion logic for testing.
    It is NOT a replacement for testing with the real PageRenderer in integration tests.
    """
    renderer = Mock()
    renderer.screen_x = 50
    renderer.screen_y = 50
    renderer.zoom = 1.0
    renderer.dpi = 96

    # Mock coordinate conversion methods
    def page_to_screen(x, y):
        return (renderer.screen_x + x * renderer.zoom, renderer.screen_y + y * renderer.zoom)

    def screen_to_page(x, y):
        return ((x - renderer.screen_x) / renderer.zoom, (y - renderer.screen_y) / renderer.zoom)

    def is_point_in_page(x, y):
        # Simple bounds check (assume 210mm x 297mm page at 96 DPI)
        page_width_px = 210 * 96 / 25.4
        page_height_px = 297 * 96 / 25.4
        return (
            renderer.screen_x <= x <= renderer.screen_x + page_width_px * renderer.zoom
            and renderer.screen_y <= y <= renderer.screen_y + page_height_px * renderer.zoom
        )

    renderer.page_to_screen = page_to_screen
    renderer.screen_to_page = screen_to_page
    renderer.is_point_in_page = is_point_in_page

    return renderer


@pytest.fixture
def create_mouse_event():
    """Factory fixture for creating QMouseEvent objects"""

    def _create_event(event_type, x, y, button=Qt.MouseButton.LeftButton, modifiers=Qt.KeyboardModifier.NoModifier):
        """Create a QMouseEvent for testing

        Args:
            event_type: QEvent.Type (MouseButtonPress, MouseButtonRelease, MouseMove)
            x, y: Position coordinates
            button: Mouse button
            modifiers: Keyboard modifiers
        """
        pos = QPointF(x, y)
        return QMouseEvent(event_type, pos, button, button, modifiers)

    return _create_event


@pytest.fixture
def create_wheel_event():
    """Factory fixture for creating QWheelEvent objects"""

    def _create_event(x, y, delta_y=120, modifiers=Qt.KeyboardModifier.NoModifier):
        """Create a QWheelEvent for testing

        Args:
            x, y: Position coordinates
            delta_y: Wheel delta (positive = scroll up, negative = scroll down)
            modifiers: Keyboard modifiers (e.g., ControlModifier for zoom)
        """
        pos = QPointF(x, y)
        global_pos = QPoint(int(x), int(y))
        angle_delta = QPoint(0, delta_y)

        return QWheelEvent(
            pos,
            global_pos,
            QPoint(0, 0),
            angle_delta,
            Qt.MouseButton.NoButton,
            modifiers,
            Qt.ScrollPhase.NoScrollPhase,
            False,
        )

    return _create_event


@pytest.fixture
def populated_page():
    """Create a page with multiple elements for testing"""
    page = Page(layout=PageLayout(width=210, height=297), page_number=1)

    # Add various elements
    page.layout.add_element(ImageData(image_path="img1.jpg", x=10, y=10, width=100, height=75, z_index=0))

    page.layout.add_element(PlaceholderData(x=120, y=10, width=80, height=60, z_index=1))

    page.layout.add_element(TextBoxData(x=10, y=100, width=190, height=40, text_content="Sample Text", z_index=2))

    return page
