#!/usr/bin/env python3
"""
Link Navigation Example

This example demonstrates:
- Creating clickable links with LinkedWord
- Different link types (INTERNAL, EXTERNAL, API, FUNCTION)
- Link styling with underlines and colors
- Link callbacks and event handling
- Interactive link states (hover, pressed)
- Organizing linked content in paragraphs

This shows how to create interactive documents with hyperlinks.
"""

import sys
from pathlib import Path
from typing import List

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

from pyWebLayout.concrete.page import Page
from pyWebLayout.style.page_style import PageStyle
from pyWebLayout.style.fonts import Font
from pyWebLayout.abstract.inline import Word, LinkedWord
from pyWebLayout.abstract.functional import LinkType
from pyWebLayout.abstract.block import Paragraph
from pyWebLayout.layout.document_layouter import DocumentLayouter


# Track link clicks for demonstration
link_clicks = []


def link_callback(link_id: str):
    """Callback for link clicks"""
    def callback():
        link_clicks.append(link_id)
        print(f"  Link clicked: {link_id}")
    return callback


def create_paragraph_with_links(
        text_parts: List[tuple],
        font_size: int = 14) -> Paragraph:
    """
    Create a paragraph with mixed text and links.

    Args:
        text_parts: List of tuples where each is either:
                   ('text', "word1 word2") for normal text
                   ('link', "word", location, link_type, callback_id)
        font_size: Base font size

    Returns:
        Paragraph with words and links
    """
    font = Font(font_size=font_size, colour=(50, 50, 50))
    paragraph = Paragraph(style=font)

    for part in text_parts:
        if part[0] == 'text':
            # Add normal words
            for word_text in part[1].split():
                paragraph.add_word(Word(word_text, font))
        elif part[0] == 'link':
            # Add linked word
            word_text, location, link_type, callback_id = part[1:]
            callback = link_callback(callback_id)
            linked_word = LinkedWord(
                text=word_text,
                style=font,
                location=location,
                link_type=link_type,
                callback=callback,
                title=f"Click to: {location}"
            )
            paragraph.add_word(linked_word)

    return paragraph


def create_example_1_internal_links():
    """Example 1: Internal navigation links within a document."""
    print("\n  Creating Example 1: Internal links...")

    page_style = PageStyle(
        border_width=2,
        border_color=(150, 150, 200),
        padding=(20, 30, 20, 30),
        background_color=(255, 255, 255),
        line_spacing=6
    )

    page = Page(size=(500, 600), style=page_style)
    layouter = DocumentLayouter(page)

    # Title
    title_font = Font(font_size=20, colour=(0, 0, 100), weight='bold')
    title = Paragraph(style=title_font)
    for word in "Internal Navigation Links".split():
        title.add_word(Word(word, title_font))

    # Content with internal links
    intro = create_paragraph_with_links([
        ('text', "This document demonstrates"),
        ('link', "internal", "#section1", LinkType.INTERNAL, "goto_section1"),
        ('text', "navigation links that jump to different parts of the document."),
    ])

    section1 = create_paragraph_with_links([
        ('text', "Jump to"),
        ('link', "Section 2", "#section2", LinkType.INTERNAL, "goto_section2"),
        ('text', "or"),
        ('link', "Section 3", "#section3", LinkType.INTERNAL, "goto_section3"),
        ('text', "within this document."),
    ])

    section2 = create_paragraph_with_links([
        ('text', "You are in Section 2. Return to"),
        ('link', "top", "#top", LinkType.INTERNAL, "goto_top"),
        ('text', "or go to"),
        ('link', "Section 3", "#section3", LinkType.INTERNAL, "goto_section3_from2"),
    ])

    section3 = create_paragraph_with_links([
        ('text', "This is Section 3. Go back to"),
        ('link', "Section 1", "#section1", LinkType.INTERNAL, "goto_section1_from3"),
        ('text', "or"),
        ('link', "top", "#top", LinkType.INTERNAL, "goto_top_from3"),
    ])

    # Layout content
    layouter.layout_paragraph(title)
    layouter.layout_paragraph(intro)
    layouter.layout_paragraph(section1)
    layouter.layout_paragraph(section2)
    layouter.layout_paragraph(section3)

    return page


def create_example_2_external_links():
    """Example 2: External links to websites."""
    print("  Creating Example 2: External links...")

    page_style = PageStyle(
        border_width=2,
        border_color=(150, 200, 150),
        padding=(20, 30, 20, 30),
        background_color=(255, 255, 255),
        line_spacing=6
    )

    page = Page(size=(500, 600), style=page_style)
    layouter = DocumentLayouter(page)

    # Title
    title_font = Font(font_size=20, colour=(0, 100, 0), weight='bold')
    title = Paragraph(style=title_font)
    for word in "External Web Links".split():
        title.add_word(Word(word, title_font))

    # Content with external links
    intro = create_paragraph_with_links([
        ('text', "Click"),
        ('link', "here", "https://example.com", LinkType.EXTERNAL, "visit_example"),
        ('text', "to visit an external website."),
    ])

    resources = create_paragraph_with_links([
        ('text', "Useful resources:"),
        ('link', "Documentation", "https://docs.example.com", LinkType.EXTERNAL, "visit_docs"),
        ('text', "and"),
        ('link', "GitHub", "https://github.com/example", LinkType.EXTERNAL, "visit_github"),
    ])

    more_links = create_paragraph_with_links([
        ('text', "Learn more at"),
        ('link', "Wikipedia", "https://wikipedia.org", LinkType.EXTERNAL, "visit_wiki"),
        ('text', "or check out"),
        ('link', "Python.org", "https://python.org", LinkType.EXTERNAL, "visit_python"),
    ])

    # Layout content
    layouter.layout_paragraph(title)
    layouter.layout_paragraph(intro)
    layouter.layout_paragraph(resources)
    layouter.layout_paragraph(more_links)

    return page


def create_example_3_api_links():
    """Example 3: API links that trigger actions."""
    print("  Creating Example 3: API links...")

    page_style = PageStyle(
        border_width=2,
        border_color=(200, 150, 150),
        padding=(20, 30, 20, 30),
        background_color=(255, 255, 255),
        line_spacing=6
    )

    page = Page(size=(500, 600), style=page_style)
    layouter = DocumentLayouter(page)

    # Title
    title_font = Font(font_size=20, colour=(150, 0, 0), weight='bold')
    title = Paragraph(style=title_font)
    for word in "API Action Links".split():
        title.add_word(Word(word, title_font))

    # Content with API links
    settings = create_paragraph_with_links([
        ('text', "Click"),
        ('link', "Settings", "/api/settings", LinkType.API, "open_settings"),
        ('text', "to configure the application."),
    ])

    actions = create_paragraph_with_links([
        ('text', "Actions:"),
        ('link', "Save", "/api/save", LinkType.API, "save_action"),
        ('text', "or"),
        ('link', "Export", "/api/export", LinkType.API, "export_action"),
        ('text', "your data."),
    ])

    management = create_paragraph_with_links([
        ('text', "Manage:"),
        ('link', "Users", "/api/users", LinkType.API, "manage_users"),
        ('text', "or"),
        ('link', "Permissions", "/api/permissions", LinkType.API, "manage_perms"),
    ])

    # Layout content
    layouter.layout_paragraph(title)
    layouter.layout_paragraph(settings)
    layouter.layout_paragraph(actions)
    layouter.layout_paragraph(management)

    return page


def create_example_4_function_links():
    """Example 4: Function links that execute code."""
    print("  Creating Example 4: Function links...")

    page_style = PageStyle(
        border_width=2,
        border_color=(150, 200, 200),
        padding=(20, 30, 20, 30),
        background_color=(255, 255, 255),
        line_spacing=6
    )

    page = Page(size=(500, 600), style=page_style)
    layouter = DocumentLayouter(page)

    # Title
    title_font = Font(font_size=20, colour=(0, 120, 120), weight='bold')
    title = Paragraph(style=title_font)
    for word in "Function Execution Links".split():
        title.add_word(Word(word, title_font))

    # Content with function links
    intro = create_paragraph_with_links([
        ('text', "These links execute"),
        ('link', "functions", "calculate()", LinkType.FUNCTION, "exec_calculate"),
        ('text', "directly in the application."),
    ])

    calculations = create_paragraph_with_links([
        ('text', "Run:"),
        ('link', "analyze()", "analyze()", LinkType.FUNCTION, "exec_analyze"),
        ('text', "or"),
        ('link', "process()", "process()", LinkType.FUNCTION, "exec_process"),
    ])

    utilities = create_paragraph_with_links([
        ('text', "Utilities:"),
        ('link', "validate()", "validate()", LinkType.FUNCTION, "exec_validate"),
        ('text', "and"),
        ('link', "cleanup()", "cleanup()", LinkType.FUNCTION, "exec_cleanup"),
    ])

    # Layout content
    layouter.layout_paragraph(title)
    layouter.layout_paragraph(intro)
    layouter.layout_paragraph(calculations)
    layouter.layout_paragraph(utilities)

    return page


def combine_pages_into_grid(pages, title):
    """Combine multiple pages into a 2x2 grid."""
    from PIL import Image, ImageDraw, ImageFont

    print("\n  Combining pages into grid...")

    # Render all pages
    images = [page.render() for page in pages]

    # Grid layout
    padding = 20
    title_height = 40
    cols = 2
    rows = 2

    # Calculate dimensions
    img_width = images[0].size[0]
    img_height = images[0].size[1]

    total_width = cols * img_width + (cols + 1) * padding
    total_height = rows * img_height + (rows + 1) * padding + title_height

    # Create combined image
    combined = Image.new('RGB', (total_width, total_height), (240, 240, 240))
    draw = ImageDraw.Draw(combined)

    # Draw title
    try:
        title_font = ImageFont.truetype(
            "/usr/share/fonts/truetype/dejavu/DejaVuSans-Bold.ttf", 18
        )
    except:
        title_font = ImageFont.load_default()

    # Center the title
    bbox = draw.textbbox((0, 0), title, font=title_font)
    text_width = bbox[2] - bbox[0]
    title_x = (total_width - text_width) // 2
    draw.text((title_x, 10), title, fill=(50, 50, 50), font=title_font)

    # Place pages in grid
    y_offset = title_height + padding
    for row in range(rows):
        x_offset = padding
        for col in range(cols):
            idx = row * cols + col
            if idx < len(images):
                combined.paste(images[idx], (x_offset, y_offset))
            x_offset += img_width + padding
        y_offset += img_height + padding

    return combined


def main():
    """Demonstrate link navigation across different link types."""
    global link_clicks
    link_clicks = []

    print("Link Navigation Example")
    print("=" * 50)

    # Create examples for each link type
    pages = [
        create_example_1_internal_links(),
        create_example_2_external_links(),
        create_example_3_api_links(),
        create_example_4_function_links()
    ]

    # Combine into demonstration image
    combined_image = combine_pages_into_grid(
        pages,
        "Link Types: Internal | External | API | Function"
    )

    # Save output
    output_dir = Path("docs/images")
    output_dir.mkdir(parents=True, exist_ok=True)
    output_path = output_dir / "example_09_link_navigation.png"
    combined_image.save(output_path)

    print("\n✓ Example completed!")
    print(f"  Output saved to: {output_path}")
    print(f"  Image size: {combined_image.size[0]}x{combined_image.size[1]} pixels")
    print(f"  Created {len(pages)} link type examples")
    print(f"  Total links created: {len(link_clicks)} callbacks registered")

    return combined_image, link_clicks


if __name__ == "__main__":
    main()
