#!/usr/bin/env python3
"""
Generate animated GIFs demonstrating EbookReader functionality.

This script creates animated GIFs showcasing:
1. Page navigation (next/previous)
2. Font size adjustment
3. Chapter navigation
4. Bookmark/position management
5. Word highlighting

The GIFs are saved to the examples/ directory and can be included in documentation.

Usage:
    python generate_ereader_gifs.py path/to/book.epub [output_dir]

Example:
    python generate_ereader_gifs.py ../tests/data/test.epub ../docs/images
"""

import sys
import os
from pathlib import Path
from typing import List

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

from dreader.application import EbookReader
from pyWebLayout.core.highlight import HighlightColor
from PIL import Image


def create_gif(images: List[Image.Image], output_path: str, duration: int = 800, loop: int = 0):
    """
    Create an animated GIF from a list of PIL Images.

    Args:
        images: List of PIL Images to animate
        output_path: Path where to save the GIF
        duration: Duration of each frame in milliseconds
        loop: Number of loops (0 = infinite)
    """
    if not images:
        print(f"Warning: No images provided for {output_path}")
        return False

    try:
        # Save as animated GIF
        images[0].save(
            output_path,
            save_all=True,
            append_images=images[1:],
            duration=duration,
            loop=loop,
            optimize=False
        )
        print(f"✓ Created: {output_path} ({len(images)} frames)")
        return True
    except Exception as e:
        print(f"✗ Error creating {output_path}: {e}")
        return False


def generate_page_navigation_gif(reader: EbookReader, output_path: str):
    """Generate GIF showing page navigation (forward and backward)."""
    print("\n[1/4] Generating page navigation GIF...")

    frames = []

    # Go to beginning
    reader.set_font_size(1.0)

    # Capture 5 pages going forward
    for i in range(5):
        page = reader.get_current_page()
        if page:
            frames.append(page.copy())
        reader.next_page()

    # Go back to start
    for _ in range(4):
        reader.previous_page()

    # Capture 5 pages going forward again (smoother loop)
    for i in range(5):
        page = reader.get_current_page()
        if page:
            frames.append(page.copy())
        reader.next_page()

    create_gif(frames, output_path, duration=600)


def generate_font_size_gif(reader: EbookReader, output_path: str):
    """Generate GIF showing font size adjustment."""
    print("\n[2/4] Generating font size adjustment GIF...")

    frames = []

    # Reset to beginning and normal font
    for _ in range(10):
        reader.previous_page()
    reader.set_font_size(1.0)

    # Font sizes to demonstrate
    font_scales = [0.8, 0.9, 1.0, 1.1, 1.2, 1.3, 1.4, 1.3, 1.2, 1.1, 1.0, 0.9, 0.8]

    for scale in font_scales:
        page = reader.set_font_size(scale)
        if page:
            frames.append(page.copy())

    # Reset to normal
    reader.set_font_size(1.0)

    create_gif(frames, output_path, duration=500)


def generate_chapter_navigation_gif(reader: EbookReader, output_path: str):
    """Generate GIF showing chapter navigation."""
    print("\n[3/4] Generating chapter navigation GIF...")

    frames = []

    # Reset font
    reader.set_font_size(1.0)

    # Get chapters
    chapters = reader.get_chapters()

    if len(chapters) == 0:
        print("  Warning: No chapters found, skipping chapter navigation GIF")
        return

    # Visit first few chapters (or loop through available chapters)
    chapter_indices = list(range(min(5, len(chapters))))

    # Add some chapters twice for smoother animation
    for idx in chapter_indices:
        page = reader.jump_to_chapter(idx)
        if page:
            frames.append(page.copy())
            # Add a second frame at each chapter for pause effect
            frames.append(page.copy())

    # Go back to first chapter
    page = reader.jump_to_chapter(0)
    if page:
        frames.append(page.copy())

    if frames:
        create_gif(frames, output_path, duration=1000)
    else:
        print("  Warning: No frames captured for chapter navigation")


def generate_bookmark_gif(reader: EbookReader, output_path: str):
    """Generate GIF showing bookmark save/load functionality."""
    print("\n[4/5] Generating bookmark/position GIF...")

    frames = []

    # Reset font
    reader.set_font_size(1.0)

    # Go to beginning
    for _ in range(20):
        reader.previous_page()

    # Capture initial position
    page = reader.get_current_page()
    if page:
        frames.append(page.copy())
        frames.append(page.copy())  # Hold frame

    # Navigate forward a bit
    for i in range(3):
        reader.next_page()
        page = reader.get_current_page()
        if page:
            frames.append(page.copy())

    # Save this position
    reader.save_position("demo_bookmark")
    page = reader.get_current_page()
    if page:
        frames.append(page.copy())
        frames.append(page.copy())  # Hold frame to show saved position

    # Navigate away
    for i in range(5):
        reader.next_page()
        page = reader.get_current_page()
        if page:
            frames.append(page.copy())

    # Hold at distant position
    page = reader.get_current_page()
    if page:
        frames.append(page.copy())
        frames.append(page.copy())

    # Jump back to bookmark
    page = reader.load_position("demo_bookmark")
    if page:
        frames.append(page.copy())
        frames.append(page.copy())
        frames.append(page.copy())  # Hold longer to show we're back

    create_gif(frames, output_path, duration=600)


def generate_highlighting_gif(reader: EbookReader, output_path: str):
    """Generate GIF showing word highlighting functionality."""
    print("\n[5/5] Generating word highlighting GIF...")

    frames = []

    # Reset font
    reader.set_font_size(1.0)

    # Find a page with actual text content (skip title/cover pages)
    for _ in range(5):
        reader.next_page()

    # Collect text objects from the page with their actual positions
    from pyWebLayout.concrete.text import Line
    text_positions = []

    # Try to find a page with text
    max_attempts = 10
    for attempt in range(max_attempts):
        page = reader.manager.get_current_page()
        text_positions = []

        for child in page._children:
            if isinstance(child, Line):
                for text_obj in child._text_objects:
                    # Skip empty text
                    if not hasattr(text_obj, '_text') or not text_obj._text or not text_obj._text.strip():
                        continue

                    # Calculate center of text object, but clamp Y to Line bounds
                    origin = text_obj._origin
                    size = text_obj.size
                    center_x = int(origin[0] + size[0] / 2)
                    center_y = int(origin[1] + size[1] / 2)

                    # Clamp Y to be within Line bounds (avoids the baseline extension issue)
                    line_y_min = int(child._origin[1])
                    line_y_max = int(child._origin[1] + child._size[1])
                    clamped_y = max(line_y_min, min(line_y_max - 1, center_y))

                    text_positions.append((center_x, clamped_y, text_obj._text))

        # If we found enough text, use this page
        if len(text_positions) > 10:
            print(f"  Found page with {len(text_positions)} words")
            break

        # Otherwise try next page
        reader.next_page()

    if len(text_positions) == 0:
        print("  Warning: Could not find a page with text after searching")

    # Capture initial page without highlights
    page_img = reader.get_current_page(include_highlights=False)
    if page_img:
        frames.append(page_img.copy())
        frames.append(page_img.copy())  # Hold frame

    # Use different colors for highlighting
    colors = [
        HighlightColor.YELLOW.value,
        HighlightColor.GREEN.value,
        HighlightColor.BLUE.value,
        HighlightColor.PINK.value,
        HighlightColor.ORANGE.value,
    ]

    # Select a subset of words to highlight (spread across the page)
    # Take every Nth word to get a good distribution
    if len(text_positions) > 10:
        step = len(text_positions) // 5
        selected_positions = [text_positions[i * step] for i in range(5) if i * step < len(text_positions)]
    else:
        selected_positions = text_positions[:5]

    highlighted_words = 0
    color_names = ['YELLOW', 'GREEN', 'BLUE', 'PINK', 'ORANGE']

    print(f"\n  Highlighting words:")
    for i, (x, y, text) in enumerate(selected_positions):
        color = colors[i % len(colors)]
        color_name = color_names[i % len(color_names)]

        # Highlight the word at this position
        highlight_id = reader.highlight_word(x, y, color=color)

        if highlight_id:
            highlighted_words += 1
            print(f"    [{color_name:6s}] {text}")
            # Capture page with new highlight
            page_img = reader.get_current_page(include_highlights=True)
            if page_img:
                frames.append(page_img.copy())
                # Hold frame briefly to show the new highlight
                frames.append(page_img.copy())

    # If we managed to highlight any words, show the final result
    if highlighted_words > 0:
        page_img = reader.get_current_page(include_highlights=True)
        if page_img:
            # Hold final frame longer
            for _ in range(3):
                frames.append(page_img.copy())

        # Clear highlights one by one
        for highlight in reader.list_highlights():
            reader.remove_highlight(highlight.id)
            page_img = reader.get_current_page(include_highlights=True)
            if page_img:
                frames.append(page_img.copy())

        # Show final cleared page
        page_img = reader.get_current_page(include_highlights=False)
        if page_img:
            frames.append(page_img.copy())
            frames.append(page_img.copy())

        print(f"  Successfully highlighted {highlighted_words} words")
    else:
        print("  Warning: No words found to highlight on current page")

    if frames:
        create_gif(frames, output_path, duration=700)
    else:
        print("  Warning: No frames captured for highlighting")


def main():
    """Main function to generate all GIFs."""
    if len(sys.argv) < 2:
        print("Usage: python generate_ereader_gifs.py path/to/book.epub [output_dir]")
        print("\nExample:")
        print("  python generate_ereader_gifs.py ../tests/data/test.epub ../docs/images")
        sys.exit(1)

    epub_path = sys.argv[1]
    output_dir = sys.argv[2] if len(sys.argv) > 2 else "."

    # Validate EPUB path
    if not os.path.exists(epub_path):
        print(f"Error: EPUB file not found: {epub_path}")
        sys.exit(1)

    # Create output directory
    os.makedirs(output_dir, exist_ok=True)

    print("="*70)
    print(" EbookReader Animated GIF Generator")
    print("="*70)
    print(f"\nInput EPUB: {epub_path}")
    print(f"Output directory: {output_dir}")

    # Create paths for output GIFs
    nav_gif = os.path.join(output_dir, "ereader_page_navigation.gif")
    font_gif = os.path.join(output_dir, "ereader_font_size.gif")
    chapter_gif = os.path.join(output_dir, "ereader_chapter_navigation.gif")
    bookmark_gif = os.path.join(output_dir, "ereader_bookmarks.gif")
    highlight_gif = os.path.join(output_dir, "ereader_highlighting.gif")

    try:
        # Create reader
        with EbookReader(page_size=(600, 800), margin=30) as reader:
            # Load EPUB
            print("\nLoading EPUB...")
            if not reader.load_epub(epub_path):
                print("Error: Failed to load EPUB file")
                sys.exit(1)

            print("✓ EPUB loaded successfully")

            # Get book info
            book_info = reader.get_book_info()
            print(f"\nBook: {book_info['title']}")
            print(f"Author: {book_info['author']}")
            print(f"Chapters: {book_info['total_chapters']}")
            print(f"Blocks: {book_info['total_blocks']}")

            print("\nGenerating GIFs...")
            print("-" * 70)

            # Generate all GIFs
            generate_page_navigation_gif(reader, nav_gif)
            generate_font_size_gif(reader, font_gif)
            generate_chapter_navigation_gif(reader, chapter_gif)
            generate_bookmark_gif(reader, bookmark_gif)
            generate_highlighting_gif(reader, highlight_gif)

            print("\n" + "="*70)
            print(" Generation Complete!")
            print("="*70)
            print("\nGenerated files:")
            for gif_path in [nav_gif, font_gif, chapter_gif, bookmark_gif, highlight_gif]:
                if os.path.exists(gif_path):
                    size = os.path.getsize(gif_path)
                    print(f"  ✓ {gif_path} ({size/1024:.1f} KB)")

            print("\nYou can now add these GIFs to your README.md!")

    except Exception as e:
        print(f"\nError: {e}")
        import traceback
        traceback.print_exc()
        sys.exit(1)


if __name__ == "__main__":
    main()
