"""UI components for media browser views (grid, list, preview modal)"""

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

# %% auto 0
__all__ = ['get_media_icon', 'grid_view_content', 'list_view_content', 'media_preview_modal', 'empty_media_content',
           'media_browser_controls']

# %% ../../nbs/media/components.ipynb 3
from typing import List, Optional
from fasthtml.common import *
from fasthtml.svg import Svg, Path as SvgPath, Circle, Rect

from cjm_fasthtml_daisyui.components.actions.button import btn, btn_colors, btn_sizes, btn_styles
from cjm_fasthtml_daisyui.components.data_display.card import card, card_body, card_actions
from cjm_fasthtml_daisyui.components.data_display.table import table, table_modifiers
from cjm_fasthtml_daisyui.components.data_display.badge import badge, badge_colors, badge_sizes
from cjm_fasthtml_daisyui.components.navigation.pagination import join
from cjm_fasthtml_daisyui.utilities.semantic_colors import bg_dui, text_dui, border_dui
from cjm_fasthtml_daisyui.utilities.border_radius import border_radius
from cjm_fasthtml_tailwind.utilities.spacing import p, m
from cjm_fasthtml_tailwind.utilities.sizing import w, h, max_w
from cjm_fasthtml_tailwind.utilities.typography import font_size, font_weight, text_align
from cjm_fasthtml_tailwind.utilities.flexbox_and_grid import (
    flex_display, gap, items, justify, grid_display, grid_cols
)
from cjm_fasthtml_tailwind.utilities.layout import overflow
from cjm_fasthtml_tailwind.utilities.borders import border
from cjm_fasthtml_tailwind.core.base import combine_classes

from cjm_fasthtml_interactions.patterns.modal_dialog import ModalDialog, ModalSize

from .models import MediaFile

from .mounter import MediaMounter

# %% ../../nbs/media/components.ipynb 6
def get_media_icon(
    media_type: str  # "video" or "audio"
) -> FT:  # SVG element with appropriate icon
    """Get an SVG icon for the media type."""
    if media_type == "video":
        return Svg(
            SvgPath(d="M4 12V4a2 2 0 0 1 2-2h8a2.4 2.4 0 0 1 1.706.706l3.588 3.588A2.4 2.4 0 0 1 20 8v12a2 2 0 0 1-2 2"),
            SvgPath(d="M14 2v5a1 1 0 0 0 1 1h5"),
            SvgPath(d="m10 17.843 3.033-1.755a.64.64 0 0 1 .967.56v4.704a.65.65 0 0 1-.967.56L10 20.157"),
            Rect(width="7", height="6", x="3", y="16", rx="1"),
            xmlns="http://www.w3.org/2000/svg",
            width="24",
            height="24",
            viewBox="0 0 24 24",
            fill="none",
            stroke="currentColor",
            stroke_width="2",
            stroke_linecap="round",
            stroke_linejoin="round",
            cls=combine_classes(w(16), h(16), m.x.auto, stroke_dui.base_content)
        )
    else:  # audio
        return Svg(
            SvgPath(d="M11.65 22H18a2 2 0 0 0 2-2V8a2.4 2.4 0 0 0-.706-1.706l-3.588-3.588A2.4 2.4 0 0 0 14 2H6a2 2 0 0 0-2 2v10.35"),
            SvgPath(d="M14 2v5a1 1 0 0 0 1 1h5"),
            SvgPath(d="M8 20v-7l3 1.474"),
            Circle(cx="6", cy="20", r="2"),
            xmlns="http://www.w3.org/2000/svg",
            width="24",
            height="24",
            viewBox="0 0 24 24",
            fill="none",
            stroke="currentColor",
            stroke_width="2",
            stroke_linecap="round",
            stroke_linejoin="round",
            cls=combine_classes(w(16), h(16), m.x.auto, stroke_dui.base_content)
        )

# %% ../../nbs/media/components.ipynb 9
def grid_view_content(
    media_files: List[MediaFile],  # List of media files to display
    mounter: MediaMounter,  # MediaMounter instance for URL generation
    start_idx: int = 0,  # Starting index for item numbering
    media_type: Optional[str] = None,  # Current filter type for maintaining state
    preview_route_func = None,  # Function to generate preview route URL
    modal_id: str = "sf-media-preview"  # ID for the preview modal
) -> FT:  # Grid container with media cards
    """Render media files as cards in a responsive grid layout."""
    return Div(
        *[
            Div(
                Div(
                    # Media type badge
                    Div(
                        Span(
                            file.media_type.upper(),
                            cls=combine_classes(
                                badge,
                                badge_colors.primary if file.media_type == "video" else badge_colors.secondary,
                                badge_sizes.xs
                            )
                        ),
                        cls=combine_classes(flex_display, justify.end, m.b(2))
                    ),

                    # File icon based on type
                    Div(
                        get_media_icon(file.media_type),
                        cls=combine_classes(
                            text_align.center,
                            p(8),
                            bg_dui.base_200,
                            border_radius.box,
                            m.b(4)
                        )
                    ),

                    # File info
                    H3(
                        file.name[:30] + "..." if len(file.name) > 30 else file.name,
                        title=file.name,
                        cls=combine_classes(font_weight.bold, m.b(2))
                    ),
                    P(file.size_str, cls=combine_classes(text_dui.base_content.opacity(70), font_size.sm)),
                    P(file.modified_str, cls=combine_classes(text_dui.base_content.opacity(70), font_size.sm)),

                    # Actions
                    Div(
                        Button(
                            "Preview",
                            hx_get=preview_route_func(idx=start_idx + idx, media_type=media_type) if preview_route_func else "#",
                            hx_target="body",
                            hx_swap="beforeend",
                            cls=combine_classes(btn, btn_colors.primary, btn_sizes.sm, w.full)
                        ) if preview_route_func else None,
                        cls=combine_classes(card_actions, m.t(4))
                    ),
                    cls=str(card_body)
                ),
                cls=combine_classes(
                    card,
                    bg_dui.base_100,
                    border(),
                    border_dui.base_300
                )
            )
            for idx, file in enumerate(media_files)
        ],
        cls=combine_classes(
            grid_display,
            grid_cols(1),
            grid_cols(2).md,
            grid_cols(3).lg,
            grid_cols(4).xl,
            gap(4)
        )
    )

# %% ../../nbs/media/components.ipynb 11
def list_view_content(
    media_files: List[MediaFile],  # List of media files to display
    mounter: MediaMounter,  # MediaMounter instance for URL generation
    start_idx: int = 0,  # Starting index for item numbering
    media_type: Optional[str] = None,  # Current filter type for maintaining state
    preview_route_func = None,  # Function to generate preview route URL
    modal_id: str = "sf-media-preview"  # ID for the preview modal
) -> FT:  # Table with media file rows
    """Render media files as rows in a table."""
    return Div(
        Table(
            Thead(
                Tr(
                    Th("#"),
                    Th("Name"),
                    Th("Type"),
                    Th("Extension"),
                    Th("Size"),
                    Th("Modified"),
                    Th("Actions") if preview_route_func else None
                )
            ),
            Tbody(
                *[
                    Tr(
                        Td(str(start_idx + idx + 1)),
                        Td(
                            file.name[:40] + "..." if len(file.name) > 40 else file.name,
                            title=file.name
                        ),
                        Td(
                            Span(
                                file.media_type,
                                cls=combine_classes(
                                    badge,
                                    badge_colors.primary if file.media_type == "video" else badge_colors.secondary,
                                    badge_sizes.sm
                                )
                            )
                        ),
                        Td(file.extension.upper()),
                        Td(file.size_str),
                        Td(file.modified_str),
                        Td(
                            Button(
                                "Preview",
                                hx_get=preview_route_func(idx=start_idx + idx, media_type=media_type) if preview_route_func else "#",
                                hx_target="body",
                                hx_swap="beforeend",
                                cls=combine_classes(btn, btn_styles.ghost, btn_sizes.xs)
                            )
                        ) if preview_route_func else None,
                        cls=str(bg_dui.base_300.hover)
                    )
                    for idx, file in enumerate(media_files)
                ]
            ),
            cls=combine_classes(
                table,
                table_modifiers.zebra,
                w.full
            )
        ),
        cls=combine_classes(
            overflow.x.auto,
            bg_dui.base_100,
            border_radius.box
        )
    )

# %% ../../nbs/media/components.ipynb 13
def media_preview_modal(
    media_file: MediaFile,  # MediaFile to preview
    media_url: Optional[str],  # URL to the media file for playback
    modal_id: str = "sf-media-preview"  # ID for the modal element
) -> FT:  # Modal dialog with media preview
    """Create a modal dialog for previewing media files with video/audio player."""
    # Build modal content
    modal_content = Div(
        # Modal header
        H3(media_file.name,
           cls=combine_classes(font_size.lg, font_weight.bold, m.b(4))),

        # File details
        Div(
            Div(
                Strong("Type: "),
                Span(
                    media_file.media_type.capitalize(),
                    cls=combine_classes(
                        badge,
                        badge_colors.primary if media_file.media_type == "video" else badge_colors.secondary
                    )
                ),
                cls=str(m.b(2))
            ),
            Div(Strong("Extension: "), media_file.extension.upper(), cls=str(m.b(2))),
            Div(Strong("Size: "), media_file.size_str, cls=str(m.b(2))),
            Div(Strong("Modified: "), media_file.modified_str, cls=str(m.b(2))),
            Div(
                Strong("Path: "),
                Code(media_file.path, cls=combine_classes(font_size.xs, text_dui.base_content.opacity(80))),
                cls=str(m.b(4))
            ),
            cls=str(m.b(4))
        ),

        # Media preview (if URL available)
        Div(
            # Video preview
            Video(
                Source(src=media_url, type=f"video/{media_file.extension}"),
                controls=True,
                cls=combine_classes(w.full, max_w._2xl, m.x.auto)
            ) if media_url and media_file.media_type == "video" else

            # Audio preview
            Audio(
                Source(src=media_url, type=f"audio/{media_file.extension}"),
                controls=True,
                cls=str(w.full)
            ) if media_url and media_file.media_type == "audio" else

            # No preview available
            P("Preview not available", cls=combine_classes(text_align.center, text_dui.base_content.opacity(60))),

            cls=combine_classes(
                p(4),
                bg_dui.base_200,
                border_radius.box,
                m.b(4)
            )
        ) if media_url else None,
    )

    # Use ModalDialog pattern with large size
    # Note: We don't use OOB swap here because the modal is appended to body
    # via hx-swap="beforeend" and doesn't need to replace an existing element
    return ModalDialog(
        modal_id=modal_id,
        content=modal_content,
        size=ModalSize.LARGE,
        auto_show=True,
        show_close_button=True,
        close_on_backdrop=True
    )

# %% ../../nbs/media/components.ipynb 15
def empty_media_content(
    message: str = "No media files found.",  # Message to display
    action_url: Optional[str] = None,  # Optional URL for action button
    action_text: str = "Configure Settings"  # Text for action button
) -> FT:  # Empty state container
    """Render empty state display when no media files are found."""
    content = [
        P(message, cls=combine_classes(text_align.center, p(8), text_dui.base_content.opacity(60)))
    ]

    if action_url:
        content.append(
            Div(
                A(
                    action_text,
                    href=action_url,
                    cls=combine_classes(btn, btn_colors.primary)
                ),
                cls=str(text_align.center)
            )
        )

    return Div(*content)

# %% ../../nbs/media/components.ipynb 17
def media_browser_controls(
    view_mode: str,  # Current view mode ("grid" or "list")
    media_type_filter: Optional[str],  # Current media type filter
    change_view_url_func,  # Function to generate URL for view change
    change_filter_url_func,  # Function to generate URL for filter change
    content_target_id: str  # ID of content container to target
) -> FT:  # Controls bar element
    """Render control bar for media browser with view mode toggle and media type filter."""
    return Div(
        # View mode selector
        Div(
            Label("View:", cls=str(m.r(2))),
            Div(
                A(
                    "Grid",
                    hx_get=change_view_url_func(view="grid"),
                    hx_target=f"#{content_target_id}",
                    hx_swap="outerHTML",
                    cls=combine_classes(
                        btn,
                        btn_sizes.sm,
                        btn_colors.primary if view_mode == "grid" else btn_styles.ghost
                    )
                ),
                A(
                    "List",
                    hx_get=change_view_url_func(view="list"),
                    hx_target=f"#{content_target_id}",
                    hx_swap="outerHTML",
                    cls=combine_classes(
                        btn,
                        btn_sizes.sm,
                        btn_colors.primary if view_mode == "list" else btn_styles.ghost
                    )
                ),
                cls=str(join)
            ),
            cls=combine_classes(flex_display, items.center)
        ),

        # Media type filter
        Div(
            Label("Filter:", cls=str(m.r(2))),
            Div(
                A(
                    "All",
                    hx_get=change_filter_url_func(media_type="all"),
                    hx_target=f"#{content_target_id}",
                    hx_swap="outerHTML",
                    cls=combine_classes(
                        btn,
                        btn_sizes.sm,
                        btn_colors.primary if (not media_type_filter or media_type_filter == "all") else btn_styles.ghost
                    )
                ),
                A(
                    "Videos",
                    hx_get=change_filter_url_func(media_type="video"),
                    hx_target=f"#{content_target_id}",
                    hx_swap="outerHTML",
                    cls=combine_classes(
                        btn,
                        btn_sizes.sm,
                        btn_colors.primary if media_type_filter == "video" else btn_styles.ghost
                    )
                ),
                A(
                    "Audio",
                    hx_get=change_filter_url_func(media_type="audio"),
                    hx_target=f"#{content_target_id}",
                    hx_swap="outerHTML",
                    cls=combine_classes(
                        btn,
                        btn_sizes.sm,
                        btn_colors.primary if media_type_filter == "audio" else btn_styles.ghost
                    )
                ),
                cls=str(join)
            ),
            cls=combine_classes(flex_display, items.center)
        ),

        cls=combine_classes(
            flex_display,
            justify.between,
            items.center,
            m.b(4),
            p(3),
            bg_dui.base_200,
            border_radius.box
        )
    )
