#!/usr/bin/env python3
"""
Demo script for Settings overlay feature.

This script demonstrates the complete settings overlay workflow:
1. Display reading page
2. Swipe down from top to open settings overlay
3. Display settings overlay with controls
4. Tap on font size increase button
5. Show live preview update (background page changes)
6. Tap on line spacing increase button
7. Show another live preview update
8. Close overlay and show final page with new settings

Generates a GIF showing all these interactions.
"""

from pathlib import Path
from dreader import EbookReader, TouchEvent, GestureType
from PIL import Image, ImageDraw, ImageFont


def add_gesture_annotation(image: Image.Image, text: str, position: str = "top") -> Image.Image:
    """
    Add a text annotation to an image showing what gesture is being performed.

    Args:
        image: Base image
        text: Annotation text
        position: "top" or "bottom"

    Returns:
        Image with annotation
    """
    # Create a copy
    annotated = image.copy()
    draw = ImageDraw.Draw(annotated)

    # Try to use a nice font, fall back to default
    try:
        font = ImageFont.truetype("/usr/share/fonts/truetype/dejavu/DejaVuSans-Bold.ttf", 24)
    except:
        font = ImageFont.load_default()

    # Calculate text position
    bbox = draw.textbbox((0, 0), text, font=font)
    text_width = bbox[2] - bbox[0]
    text_height = bbox[3] - bbox[1]

    x = (image.width - text_width) // 2
    if position == "top":
        y = 20
    else:
        y = image.height - text_height - 20

    # Draw background rectangle
    padding = 10
    draw.rectangle(
        [x - padding, y - padding, x + text_width + padding, y + text_height + padding],
        fill=(0, 0, 0, 200)
    )

    # Draw text
    draw.text((x, y), text, fill=(255, 255, 255), font=font)

    return annotated


def add_swipe_arrow(image: Image.Image, start_y: int, end_y: int) -> Image.Image:
    """
    Add a visual swipe arrow to show gesture direction.

    Args:
        image: Base image
        start_y: Starting Y position
        end_y: Ending Y position

    Returns:
        Image with arrow overlay
    """
    annotated = image.copy()
    draw = ImageDraw.Draw(annotated)

    # Draw arrow in center of screen
    x = image.width // 2

    # Draw line
    draw.line([(x, start_y), (x, end_y)], fill=(255, 100, 100), width=5)

    # Draw arrowhead
    arrow_size = 20
    if end_y < start_y:  # Upward arrow
        draw.polygon([
            (x, end_y),
            (x - arrow_size, end_y + arrow_size),
            (x + arrow_size, end_y + arrow_size)
        ], fill=(255, 100, 100))
    else:  # Downward arrow
        draw.polygon([
            (x, end_y),
            (x - arrow_size, end_y - arrow_size),
            (x + arrow_size, end_y - arrow_size)
        ], fill=(255, 100, 100))

    return annotated


def add_tap_indicator(image: Image.Image, x: int, y: int, label: str = "") -> Image.Image:
    """
    Add a visual tap indicator to show where user tapped.

    Args:
        image: Base image
        x, y: Tap coordinates
        label: Optional label for the tap

    Returns:
        Image with tap indicator
    """
    annotated = image.copy()
    draw = ImageDraw.Draw(annotated)

    # Draw circle at tap location
    radius = 30
    draw.ellipse(
        [x - radius, y - radius, x + radius, y + radius],
        outline=(255, 100, 100),
        width=5
    )

    # Draw crosshair
    draw.line([(x - radius - 10, y), (x + radius + 10, y)], fill=(255, 100, 100), width=3)
    draw.line([(x, y - radius - 10), (x, y + radius + 10)], fill=(255, 100, 100), width=3)

    # Add label if provided
    if label:
        try:
            font = ImageFont.truetype("/usr/share/fonts/truetype/dejavu/DejaVuSans-Bold.ttf", 18)
        except:
            font = ImageFont.load_default()

        bbox = draw.textbbox((0, 0), label, font=font)
        text_width = bbox[2] - bbox[0]

        # Position label above tap point
        label_x = x - text_width // 2
        label_y = y - radius - 40

        draw.text((label_x, label_y), label, fill=(255, 100, 100), font=font)

    return annotated


def main():
    """Generate Settings overlay demo GIF"""
    print("=== Settings Overlay Demo ===")
    print()

    # Use Alice in Wonderland test book (has actual content)
    epub_path = Path(__file__).parent.parent / 'tests' / 'data' / 'test.epub'

    if not epub_path.exists():
        print("Error: test.epub not found!")
        print(f"Looked in: {epub_path}")
        return

    print(f"Using book: {epub_path.name}")

    # Create reader
    reader = EbookReader(page_size=(800, 1200))

    # Load book
    print("Loading book...")
    success = reader.load_epub(str(epub_path))

    if not success:
        print("Error: Failed to load EPUB!")
        return

    print(f"Loaded: {reader.book_title} by {reader.book_author}")
    print()

    # Skip to a page with actual content (past cover/title pages)
    for _ in range(3):
        reader.next_page()

    # Prepare frames for GIF
    frames = []
    frame_duration = []  # Duration in milliseconds for each frame

    # Frame 1: Initial reading page
    print("Frame 1: Initial reading page...")
    page1 = reader.get_current_page()
    annotated1 = add_gesture_annotation(page1, f"Reading: {reader.book_title}", "top")
    frames.append(annotated1)
    frame_duration.append(2000)  # 2 seconds

    # Frame 2: Show swipe down gesture
    print("Frame 2: Swipe down gesture...")
    swipe_visual = add_swipe_arrow(page1, 100, 300)
    annotated2 = add_gesture_annotation(swipe_visual, "Swipe down from top", "top")
    frames.append(annotated2)
    frame_duration.append(1000)  # 1 second

    # Frame 3: Settings overlay appears
    print("Frame 3: Settings overlay opens...")
    event_swipe_down = TouchEvent(gesture=GestureType.SWIPE_DOWN, x=400, y=100)
    response = reader.handle_touch(event_swipe_down)
    print(f"  Response: {response.action}")

    # Get the overlay image by calling open_settings_overlay again
    overlay_image = reader.open_settings_overlay()
    annotated3 = add_gesture_annotation(overlay_image, "Settings", "top")
    frames.append(annotated3)
    frame_duration.append(3000)  # 3 seconds to read

    # Find actual button coordinates by querying the overlay
    print("Querying overlay for button positions...")
    link_positions = {}
    if reader._active_overlay and reader._active_overlay._overlay_reader:
        page = reader._active_overlay._overlay_reader.manager.get_current_page()

        # Scan for all links with very fine granularity to catch all buttons
        for y in range(0, 840, 3):
            for x in range(0, 480, 3):
                result = page.query_point((x, y))
                if result and result.link_target:
                    if result.link_target not in link_positions:
                        # Translate to screen coordinates
                        panel_x_offset = int((800 - 480) / 2)
                        panel_y_offset = int((1200 - 840) / 2)
                        screen_x = x + panel_x_offset
                        screen_y = y + panel_y_offset
                        link_positions[result.link_target] = (screen_x, screen_y)

        for link, (x, y) in sorted(link_positions.items()):
            print(f"  Found: {link} at ({x}, {y})")

    # Frame 4: Tap on font size increase button
    print("Frame 4: Tap on font size increase...")
    if 'setting:font_increase' in link_positions:
        tap_x, tap_y = link_positions['setting:font_increase']
        print(f"  Using coordinates: ({tap_x}, {tap_y})")

        tap_visual = add_tap_indicator(overlay_image, tap_x, tap_y, "Increase")
        annotated4 = add_gesture_annotation(tap_visual, "Tap to increase font size", "bottom")
        frames.append(annotated4)
        frame_duration.append(1500)  # 1.5 seconds

        # Frames 5-9: Font size increased (live preview) - show each tap individually
        print("Frames 5-9: Font size increased with live preview (5 taps, showing each)...")
        for i in range(5):
            event_tap_font = TouchEvent(gesture=GestureType.TAP, x=tap_x, y=tap_y)
            response = reader.handle_touch(event_tap_font)
            print(f"  Tap {i+1}: {response.action} - Font scale: {response.data.get('font_scale', 'N/A')}")

            # Get updated overlay image after each tap
            updated_overlay = reader.get_current_page()  # This gets the composited overlay
            annotated = add_gesture_annotation(
                updated_overlay,
                f"Font: {int(reader.base_font_scale * 100)}% (tap {i+1}/5)",
                "top"
            )
            frames.append(annotated)
            frame_duration.append(800)  # 0.8 seconds per tap

        # Hold on final font size for a bit longer
        final_font_overlay = reader.get_current_page()
        annotated_final = add_gesture_annotation(
            final_font_overlay,
            f"Font: {int(reader.base_font_scale * 100)}% (complete)",
            "top"
        )
        frames.append(annotated_final)
        frame_duration.append(1500)  # 1.5 seconds to see the final result
    else:
        print("  Skipping - button not found")
        updated_overlay = overlay_image

    # Get current overlay state for line spacing section
    current_overlay = reader.get_current_page()

    # Frame N: Tap on line spacing increase button
    print("Frame N: Tap on line spacing increase...")
    if 'setting:line_spacing_increase' in link_positions:
        tap_x2, tap_y2 = link_positions['setting:line_spacing_increase']
        print(f"  Using coordinates: ({tap_x2}, {tap_y2})")

        tap_visual2 = add_tap_indicator(current_overlay, tap_x2, tap_y2, "Increase")
        annotated_ls_tap = add_gesture_annotation(tap_visual2, "Tap to increase line spacing", "bottom")
        frames.append(annotated_ls_tap)
        frame_duration.append(1500)  # 1.5 seconds

        # Frames N+1 to N+5: Line spacing increased (live preview) - show each tap individually
        print("Frames N+1 to N+5: Line spacing increased with live preview (5 taps, showing each)...")
        for i in range(5):
            event_tap_spacing = TouchEvent(gesture=GestureType.TAP, x=tap_x2, y=tap_y2)
            response = reader.handle_touch(event_tap_spacing)
            print(f"  Tap {i+1}: {response.action} - Line spacing: {response.data.get('line_spacing', 'N/A')}")

            # Get updated overlay image after each tap
            updated_overlay2 = reader.get_current_page()
            annotated = add_gesture_annotation(
                updated_overlay2,
                f"Line Spacing: {reader.page_style.line_spacing}px (tap {i+1}/5)",
                "top"
            )
            frames.append(annotated)
            frame_duration.append(800)  # 0.8 seconds per tap

        # Hold on final line spacing for a bit longer
        final_spacing_overlay = reader.get_current_page()
        annotated_final_ls = add_gesture_annotation(
            final_spacing_overlay,
            f"Line Spacing: {reader.page_style.line_spacing}px (complete)",
            "top"
        )
        frames.append(annotated_final_ls)
        frame_duration.append(1500)  # 1.5 seconds to see the final result
    else:
        print("  Skipping - button not found")

    # Get current overlay state for paragraph spacing section
    current_overlay2 = reader.get_current_page()

    # Frame M: Tap on paragraph spacing increase button
    print("Frame M: Tap on paragraph spacing increase...")
    if 'setting:block_spacing_increase' in link_positions:
        tap_x3, tap_y3 = link_positions['setting:block_spacing_increase']
        print(f"  Using coordinates: ({tap_x3}, {tap_y3})")

        tap_visual3 = add_tap_indicator(current_overlay2, tap_x3, tap_y3, "Increase")
        annotated_ps_tap = add_gesture_annotation(tap_visual3, "Tap to increase paragraph spacing", "bottom")
        frames.append(annotated_ps_tap)
        frame_duration.append(1500)  # 1.5 seconds

        # Frames M+1 to M+5: Paragraph spacing increased (live preview) - show each tap individually
        print("Frames M+1 to M+5: Paragraph spacing increased with live preview (5 taps, showing each)...")
        for i in range(5):
            event_tap_para = TouchEvent(gesture=GestureType.TAP, x=tap_x3, y=tap_y3)
            response = reader.handle_touch(event_tap_para)
            print(f"  Tap {i+1}: {response.action} - Paragraph spacing: {response.data.get('inter_block_spacing', 'N/A')}")

            # Get updated overlay image after each tap
            updated_overlay3 = reader.get_current_page()
            annotated = add_gesture_annotation(
                updated_overlay3,
                f"Paragraph Spacing: {reader.page_style.inter_block_spacing}px (tap {i+1}/5)",
                "top"
            )
            frames.append(annotated)
            frame_duration.append(800)  # 0.8 seconds per tap

        # Hold on final paragraph spacing for a bit longer
        final_para_overlay = reader.get_current_page()
        annotated_final_ps = add_gesture_annotation(
            final_para_overlay,
            f"Paragraph Spacing: {reader.page_style.inter_block_spacing}px (complete)",
            "top"
        )
        frames.append(annotated_final_ps)
        frame_duration.append(1500)  # 1.5 seconds to see the final result
    else:
        print("  Skipping - button not found")

    # Get current overlay state for word spacing section
    current_overlay3 = reader.get_current_page()

    # Frame W: Tap on word spacing increase button
    print("Frame W: Tap on word spacing increase...")
    if 'setting:word_spacing_increase' in link_positions:
        tap_x4, tap_y4 = link_positions['setting:word_spacing_increase']
        print(f"  Using coordinates: ({tap_x4}, {tap_y4})")

        tap_visual4 = add_tap_indicator(current_overlay3, tap_x4, tap_y4, "Increase")
        annotated_ws_tap = add_gesture_annotation(tap_visual4, "Tap to increase word spacing", "bottom")
        frames.append(annotated_ws_tap)
        frame_duration.append(1500)  # 1.5 seconds

        # Frames W+1 to W+5: Word spacing increased (live preview) - show each tap individually
        print("Frames W+1 to W+5: Word spacing increased with live preview (5 taps, showing each)...")
        for i in range(5):
            event_tap_word = TouchEvent(gesture=GestureType.TAP, x=tap_x4, y=tap_y4)
            response = reader.handle_touch(event_tap_word)
            print(f"  Tap {i+1}: {response.action} - Word spacing: {response.data.get('word_spacing', 'N/A')}")

            # Get updated overlay image after each tap
            updated_overlay4 = reader.get_current_page()
            annotated = add_gesture_annotation(
                updated_overlay4,
                f"Word Spacing: {reader.page_style.word_spacing}px (tap {i+1}/5)",
                "top"
            )
            frames.append(annotated)
            frame_duration.append(800)  # 0.8 seconds per tap

        # Hold on final word spacing for a bit longer
        final_word_overlay = reader.get_current_page()
        annotated_final_ws = add_gesture_annotation(
            final_word_overlay,
            f"Word Spacing: {reader.page_style.word_spacing}px (complete)",
            "top"
        )
        frames.append(annotated_final_ws)
        frame_duration.append(1500)  # 1.5 seconds to see the final result
    else:
        print("  Skipping - button not found")

    # Frame Z: Tap outside to close
    print("Frame Z: Close overlay...")
    final_overlay_state = reader.get_current_page()
    tap_visual_close = add_tap_indicator(final_overlay_state, 100, 600, "Close")
    annotated_close = add_gesture_annotation(tap_visual_close, "Tap outside to close", "bottom")
    frames.append(annotated_close)
    frame_duration.append(1500)  # 1.5 seconds

    # Final Frame: Back to reading with new settings applied
    print("Final Frame: Back to reading with new settings...")
    event_close = TouchEvent(gesture=GestureType.TAP, x=100, y=600)
    response = reader.handle_touch(event_close)
    print(f"  Response: {response.action}")

    final_page = reader.get_current_page()
    annotated_final = add_gesture_annotation(
        final_page,
        f"Settings Applied: {int(reader.base_font_scale * 100)}% font, {reader.page_style.line_spacing}px line, {reader.page_style.inter_block_spacing}px para, {reader.page_style.word_spacing}px word",
        "top"
    )
    frames.append(annotated_final)
    frame_duration.append(3000)  # 3 seconds

    # Save as GIF
    output_path = Path(__file__).parent.parent / 'docs' / 'images' / 'settings_overlay_demo.gif'
    output_path.parent.mkdir(parents=True, exist_ok=True)

    print()
    print(f"Saving GIF with {len(frames)} frames...")
    frames[0].save(
        output_path,
        save_all=True,
        append_images=frames[1:],
        duration=frame_duration,
        loop=0,
        optimize=False
    )

    print(f"✓ GIF saved to: {output_path}")
    print(f"  Size: {output_path.stat().st_size / 1024:.1f} KB")
    print(f"  Frames: {len(frames)}")
    print(f"  Total duration: {sum(frame_duration) / 1000:.1f}s")

    # Also save individual frames for documentation
    frames_dir = output_path.parent / 'settings_overlay_frames'
    frames_dir.mkdir(exist_ok=True)

    for i, frame in enumerate(frames):
        frame_path = frames_dir / f'frame_{i+1:02d}.png'
        frame.save(frame_path)

    print(f"✓ Individual frames saved to: {frames_dir}")

    # Cleanup
    reader.close()

    print()
    print("=== Demo Complete ===")


if __name__ == '__main__':
    main()
