"""Preview modal component for viewing media files."""

# AUTOGENERATED! DO NOT EDIT! File to edit: ../../nbs/components/preview.ipynb.

# %% auto #0
__all__ = ['render_preview_content', 'render_preview_modal']

# %% ../../nbs/components/preview.ipynb #c3d4e5f6
from typing import Any, Optional

from fasthtml.common import (
    Div, Span, Button, Dialog, Form, H3, A, Script
)

# Tailwind utilities
from cjm_fasthtml_tailwind.utilities.sizing import w, h, max_w, max_h, min_w, min_h
from cjm_fasthtml_tailwind.utilities.spacing import p, m
from cjm_fasthtml_tailwind.utilities.typography import (
    font_size, font_weight, truncate, whitespace, break_all
)
from cjm_fasthtml_tailwind.utilities.flexbox_and_grid import (
    flex_display, flex_direction, items, justify, grow, gap, shrink
)
from cjm_fasthtml_tailwind.utilities.layout import position, overflow, display_tw
from cjm_fasthtml_tailwind.utilities.borders import border, divide
from cjm_fasthtml_tailwind.core.base import combine_classes

# DaisyUI utilities
from cjm_fasthtml_daisyui.utilities.semantic_colors import (
    bg_dui, text_dui, border_dui, divide_dui
)
from cjm_fasthtml_daisyui.components.actions.button import (
    btn, btn_colors, btn_sizes, btn_modifiers, btn_styles
)
from cjm_fasthtml_daisyui.components.actions.modal import (
    modal, modal_box, modal_action, modal_backdrop
)

# Local imports
from cjm_file_discovery.core.models import FileInfo, FileType
from ..core.config import GalleryConfig, PreviewConfig
from ..core.html_ids import GalleryHtmlIds
from cjm_fasthtml_media_gallery.core.icons import (
    get_gallery_icon, get_media_type_icon, MEDIA_TYPE_BADGE_COLORS
)
from .players import render_media_player

# %% ../../nbs/components/preview.ipynb #e5f6a7b8
def _render_preview_header(
    file_info: FileInfo,              # File being previewed
    config: PreviewConfig,            # Preview configuration
) -> Any:  # Header component
    """Render the preview modal header."""
    return Div(
        # File info
        Div(
            get_media_type_icon(file_info.file_type, size=5),
            H3(
                file_info.name,
                cls=combine_classes(font_size.lg, font_weight.bold, truncate, m.l(3)),
                title=file_info.name
            ),
            cls=combine_classes(flex_display, items.center, grow(), min_w._0)
        ),
        # Close button
        Form(
            Button(
                get_gallery_icon("close", size=5),
                cls=combine_classes(
                    btn, btn_sizes.sm, btn_modifiers.circle, btn_styles.ghost
                ),
                type="submit"
            ),
            method="dialog"
        ),
        cls=combine_classes(
            flex_display, items.center, justify.between,
            p(4), bg_dui.base_100, border.b(), border_dui.base_300
        )
    )

# %% ../../nbs/components/preview.ipynb #g7b8c9d0
def _render_info_panel(
    file_info: FileInfo,              # File being previewed
) -> Any:  # Info panel component
    """Render the file info panel."""
    info_items = [
        ("Type", file_info.file_type.value.title()),
        ("Extension", file_info.extension.upper() if file_info.extension else "—"),
        ("Size", file_info.size_str or "—"),
        ("Modified", file_info.modified_str or "—"),
    ]
    
    panel_items = []
    for label, value in info_items:
        panel_items.append(
            Div(
                Span(label, cls=combine_classes(font_size.sm, text_dui.base_content.opacity(60))),
                Span(value, cls=combine_classes(font_size.sm, font_weight.medium, whitespace.nowrap)),
                cls=combine_classes(flex_display, justify.between, gap(2), p.y(2))
            )
        )
    
    # Path (full width, can wrap)
    panel_items.append(
        Div(
            Span("Path", cls=combine_classes(font_size.sm, text_dui.base_content.opacity(60))),
            Span(
                file_info.path,
                cls=combine_classes(font_size.xs, break_all, text_dui.base_content.opacity(70)),
                title=file_info.path
            ),
            cls=combine_classes(flex_display, flex_direction.col, gap(1), p.y(2))
        )
    )
    
    return Div(
        Div(
            Span("File Info", cls=combine_classes(font_size.sm, font_weight.bold)),
            cls=str(m.b(2))
        ),
        Div(
            *panel_items,
            cls=combine_classes(divide.y(), divide_dui.base_300)
        ),
        id=GalleryHtmlIds.PREVIEW_INFO,
        cls=combine_classes(
            min_w(56), w(64), shrink(0), p(4),
            bg_dui.base_200,
            border.l(), border_dui.base_300,
            overflow.y.auto
        )
    )

# %% ../../nbs/components/preview.ipynb #i9d0e1f2
def _render_preview_footer(
    file_info: FileInfo,              # File being previewed
    file_url: str,                    # URL to the file
    config: PreviewConfig,            # Preview configuration
    modal_id: str,                    # Modal ID for HTMX targeting
    prev_url: Optional[str] = None,   # URL for previous file
    next_url: Optional[str] = None,   # URL for next file
    has_prev: bool = False,           # Whether there's a previous file
    has_next: bool = False,           # Whether there's a next file
) -> Any:  # Footer component
    """Render the preview modal footer."""
    buttons = []
    
    # Build hx_vals JSON with the current file path for navigation
    path_vals = f'{{"path": "{file_info.path}"}}'
    
    # Navigation buttons
    if config.show_navigation:
        # Previous button
        prev_attrs = {
            "cls": combine_classes(btn, btn_sizes.sm, btn_styles.ghost),
            "disabled": not has_prev,
        }
        if has_prev and prev_url:
            prev_attrs["hx_post"] = prev_url
            prev_attrs["hx_vals"] = path_vals
            prev_attrs["hx_target"] = f"#{modal_id}"
            prev_attrs["hx_swap"] = "innerHTML"
        
        buttons.append(
            Button(
                get_gallery_icon("prev", size=4),
                Span("Previous", cls=str(m.l(1))),
                **prev_attrs
            )
        )
        
        # Next button
        next_attrs = {
            "cls": combine_classes(btn, btn_sizes.sm, btn_styles.ghost),
            "disabled": not has_next,
        }
        if has_next and next_url:
            next_attrs["hx_post"] = next_url
            next_attrs["hx_vals"] = path_vals
            next_attrs["hx_target"] = f"#{modal_id}"
            next_attrs["hx_swap"] = "innerHTML"
        
        buttons.append(
            Button(
                Span("Next", cls=str(m.r(1))),
                get_gallery_icon("next", size=4),
                **next_attrs
            )
        )
    
    # Spacer
    buttons.append(Div(cls=str(grow())))
    
    # Download button
    if config.show_download_button:
        buttons.append(
            A(
                get_gallery_icon("download", size=4),
                Span("Download", cls=str(m.l(2))),
                href=file_url,
                download=file_info.name,
                cls=combine_classes(btn, btn_sizes.sm, btn_colors.primary)
            )
        )
    
    return Div(
        *buttons,
        cls=combine_classes(
            flex_display, items.center, gap(2),
            p(4), bg_dui.base_100, border.t(), border_dui.base_300
        )
    )

# %% ../../nbs/components/preview.ipynb #k1f2g3h4
def render_preview_content(
    file_info: FileInfo,  # File to preview
    file_url: str,  # URL to the file
    config: GalleryConfig,  # Gallery configuration
    prev_url: Optional[str] = None,  # URL for previous file handler
    next_url: Optional[str] = None,  # URL for next file handler
    has_prev: bool = False,  # Whether there's a previous file
    has_next: bool = False,  # Whether there's a next file
    modal_id: Optional[str] = None,  # Modal ID to show (for auto-show script)
    text_content: Optional[str] = None,  # Pre-read text content for text files
    text_error: Optional[str] = None,  # Error message if text reading failed
) -> Any:  # Preview modal content with auto-show script
    """Render the preview modal content with script to show the modal."""
    preview_config = config.preview
    modal_id = modal_id or config.preview_modal_id
    
    # Determine autoplay based on config and file type
    autoplay = False
    if file_info.file_type == FileType.VIDEO:
        autoplay = preview_config.autoplay_video
    elif file_info.file_type == FileType.AUDIO:
        autoplay = preview_config.autoplay_audio
    
    # Build content
    content = []
    
    # Header
    content.append(_render_preview_header(file_info, preview_config))
    
    # Main content area (player + info panel)
    main_content = [
        # Media player
        Div(
            render_media_player(
                file_url, file_info,
                autoplay=autoplay,
                text_content=text_content,
                text_error=text_error
            ),
            id=GalleryHtmlIds.PREVIEW_PLAYER,
            cls=combine_classes(
                flex_display, items.center, justify.center,
                grow(), min_h(0),  # min_h(0) allows flex child to shrink
                p(4),
                bg_dui.base_300,
                overflow.auto  # Enable scrolling for text content with long lines
            )
        ),
    ]
    
    # Info panel (optional)
    if preview_config.show_info_panel:
        main_content.append(_render_info_panel(file_info))
    
    content.append(
        Div(
            *main_content,
            cls=combine_classes(
                flex_display, grow(), min_h(0),  # min_h(0) allows flex child to shrink
                overflow.hidden
            )
        )
    )
    
    # Footer
    content.append(
        _render_preview_footer(
            file_info, file_url, preview_config, modal_id,
            prev_url, next_url, has_prev, has_next
        )
    )
    
    # Main content div - fills the modal which has fixed dimensions
    content_div = Div(
        *content,
        id=GalleryHtmlIds.PREVIEW_CONTENT,
        cls=combine_classes(
            flex_display, flex_direction.col,
            h.screen, w.screen  # Fill available screen space
        )
    )
    
    # Script to show the modal after content loads
    show_script = Script(f"""
        (function() {{
            const modal = document.getElementById('{modal_id}');
            if (modal && typeof modal.showModal === 'function' && !modal.open) {{
                requestAnimationFrame(() => modal.showModal());
            }}
        }})();
    """)
    
    return Div(content_div, show_script)

# %% ../../nbs/components/preview.ipynb #n4i5j6k7
def render_preview_modal(
    modal_id: str = GalleryHtmlIds.PREVIEW_MODAL,  # Modal ID
) -> Dialog:  # Preview modal container
    """Render the preview modal container (empty, content loaded via HTMX)."""
    return Dialog(
        Div(
            # Content will be loaded here via HTMX
            cls=combine_classes(
                modal_box,
                flex_display, flex_direction.col,  # Flex column for header/content/footer
                overflow.hidden,  # Prevent content from overflowing modal
                p._0
            )
        ),
        # Backdrop for clicking outside to close
        Form(
            Button("close", cls=display_tw.hidden),
            method="dialog",
            cls=str(modal_backdrop)
        ),
        id=modal_id,
        cls=str(modal)
    )
