"""Pre-built page layouts for authenticated app experiences (login, dashboard, admin)."""

# AUTOGENERATED! DO NOT EDIT! File to edit: ../nbs/03_app_pages.ipynb.

# %% auto #0
__all__ = ['LoginScreen', 'TopContent', 'TopLayout']

# %% ../nbs/03_app_pages.ipynb #99dc363f
from fastcore.utils import *
from fasthtml.common import *
from fasthtml.jupyter import *
from fastlite import *
import fasthtml.components as fc
from fasthtml.common import A, Button as FhButton, I, Span
from .foundations import normalize_tokens, stringify, VEnum
from .core import *
from .components import *



# %% ../nbs/03_app_pages.ipynb #47b3b49d
# Default inspirational quotes for login screen (fully customizable via parameter)
_DEFAULT_LOGIN_QUOTES = [
    "The only way to do great work is to love what you do. — Steve Jobs",
    "Innovation distinguishes between a leader and a follower. — Steve Jobs",
    "Stay hungry, stay foolish. — Steve Jobs",
    "The best time to plant a tree was 20 years ago. The second best time is now. — Chinese Proverb",
    "Success is not final, failure is not fatal: it is the courage to continue that counts. — Winston Churchill",
    "The future belongs to those who believe in the beauty of their dreams. — Eleanor Roosevelt",
    "It does not matter how slowly you go as long as you do not stop. — Confucius",
    "Everything you've ever wanted is on the other side of fear. — George Addair",
    "The only limit to our realization of tomorrow is our doubts of today. — Franklin D. Roosevelt",
    "Believe you can and you're halfway there. — Theodore Roosevelt",
]

# CSS for login screen: gradient background and quote rotation
_LOGIN_SCREEN_CSS = """
/* Hero gradient background - uses current theme colors */
.login-brand-panel {
    position: relative;
    background: linear-gradient(135deg, 
        var(--primary-container) 0%, 
        var(--surface-container) 50%,
        var(--secondary-container) 100%);
    overflow: hidden;
    transition: background 1s ease-in-out;
}
.login-brand-panel::before {
    content: '';
    position: absolute;
    inset: 0;
    background: radial-gradient(circle at 20% 80%, var(--primary) 0%, transparent 50%),
                radial-gradient(circle at 80% 20%, var(--secondary) 0%, transparent 50%);
    opacity: 0.15;
    pointer-events: none;
}
.login-brand-content {
    position: relative;
    z-index: 1;
    display: flex;
    flex-direction: column;
    height: 100%;
    min-height: 100vh;
    padding: 2rem;
}

/* Branding anchored at top-left */
.login-branding {
    flex-shrink: 0;
    display: flex;
    align-items: center;
    gap: 0.75rem;
    justify-content: flex-start;
}
.login-branding img {
    max-height: 3rem;
}

/* Quote in center - larger and prominent */
.login-quotes-wrapper {
    flex: 1;
    display: flex;
    align-items: center;
    justify-content: center;
}
.login-quotes {
    position: relative;
    min-height: 6rem;
    max-width: 500px;
    width: 100%;
}
.login-quote {
    position: absolute;
    width: 100%;
    opacity: 0;
    animation: quote-fade 100s infinite;
    text-align: center;
    font-style: italic;
    font-size: 1.25rem;
    line-height: 1.6;
}
/* Stagger each quote: 10 quotes × 10s each = 100s total cycle */
.login-quote:nth-child(1) { animation-delay: 0s; }
.login-quote:nth-child(2) { animation-delay: 10s; }
.login-quote:nth-child(3) { animation-delay: 20s; }
.login-quote:nth-child(4) { animation-delay: 30s; }
.login-quote:nth-child(5) { animation-delay: 40s; }
.login-quote:nth-child(6) { animation-delay: 50s; }
.login-quote:nth-child(7) { animation-delay: 60s; }
.login-quote:nth-child(8) { animation-delay: 70s; }
.login-quote:nth-child(9) { animation-delay: 80s; }
.login-quote:nth-child(10) { animation-delay: 90s; }

@keyframes quote-fade {
    0%, 8% { opacity: 0; transform: translateY(10px); }
    10%, 18% { opacity: 1; transform: translateY(0); }
    20%, 100% { opacity: 0; transform: translateY(-10px); }
}

/* Mobile: hide quotes, simplify layout */
@media (max-width: 992px) {
    .login-quotes-wrapper { display: none; }
    .login-brand-content { 
        min-height: auto; 
        padding: 1.5rem;
    }
    .login-branding {
        justify-content: center;
    }
}
"""

# Minimal JS for cycling BeerCSS theme colors
_LOGIN_COLOR_CYCLE_JS = """
(function() {
    const colors = ['primary', 'secondary', 'tertiary'];
    let idx = 0;
    const panel = document.querySelector('.login-brand-panel');
    if (!panel) return;
    
    setInterval(function() {
        idx = (idx + 1) % colors.length;
        panel.style.background = 'linear-gradient(135deg, var(--' + colors[idx] + '-container) 0%, var(--surface-container) 50%, var(--' + colors[(idx+1) % colors.length] + '-container) 100%)';
    }, 30000);
})();
"""

def LoginScreen(
    title='Sign In',
    subtitle='Choose your preferred sign-in method',
    providers=None,      
    left_slot=None,      
    logo_src=None,
    brand_name=None,         # Brand name displayed at top-left of left panel
    quotes=None,             # List of quotes to rotate (uses defaults if None, pass [] to disable)
    color_cycle=True,        # Enable color cycling animation
    testimonial_text=None,   # Legacy: single testimonial (use quotes instead)
    brand_bg_cls='primary',  # Legacy: fallback if gradient fails
    left_cols=9,             # Number of columns for left side (out of 12)
    cls='',
    **kwargs
):
    """
    A configurable Split Login Screen with dynamic branding.
    
    Features:
    - Hero-style gradient background (same as landing page)
    - Brand name + logo at top-left corner
    - Rotating inspirational quotes in center (pure CSS, hidden on mobile)
    - Optional color cycling through BeerCSS theme colors (minimal JS)
    
    Args:
        title: Sign-in form title
        subtitle: Sign-in form subtitle
        providers: List of OAuth provider dicts [{label, icon, href, cls}, ...]
        left_slot: Custom content for left panel (overrides default branding)
        logo_src: URL/path to logo image
        brand_name: Brand name displayed at top-left corner
        quotes: List of quote strings to rotate. Defaults to inspirational quotes.
                Pass empty list [] to disable quotes entirely.
        color_cycle: Enable gradient color cycling (default True)
        left_cols: Grid columns for left panel (out of 12). Default 9 = 75%
    
    Example:
        LoginScreen(
            brand_name="MyApp",
            logo_src="/static/logo.svg",
            quotes=[
                "Your custom quote here — Author",
                "Another inspiring message — Source",
            ],
        )
    """
    
    # 1. Defaults
    if providers is None:
        providers = [
            {'label': 'Continue with Google', 'icon': 'https://authjs.dev/img/providers/google.svg', 'href': '/auth/google', 'cls': 'border responsive surface'},
            {'label': 'Continue with GitHub', 'icon': 'https://authjs.dev/img/providers/github.svg', 'icon_cls': 'invert', 'href': '/auth/github', 'cls': 'fill responsive inverse-surface'}
        ]
    
    # Use default quotes if None, allow empty list to disable
    if quotes is None:
        quotes = _DEFAULT_LOGIN_QUOTES

    # 2. Build Left Column - Branded layout
    if left_slot:
        left_content = left_slot
    else:
        # Top-left: Logo + Brand name (anchored at top-left via CSS)
        top_section = []
        if logo_src:
            top_section.append(Img(src=logo_src, cls="responsive"))
        if brand_name:
            top_section.append(H3(brand_name, cls="bold no-margin"))
        elif not logo_src:
            top_section.append(H3("Welcome", cls="bold no-margin"))
        
        top_branding = Div(*top_section, cls="login-branding")
        
        # Center section: Rotating quotes (larger, centered)
        center_quotes = Div(cls="login-quotes-wrapper")
        if quotes:
            quote_elements = [
                P(f'"{q}"', cls="login-quote")
                for q in quotes[:10]  # Max 10 for CSS animation
            ]
            center_quotes = Div(
                Div(*quote_elements, cls="login-quotes"),
                cls="login-quotes-wrapper"
            )
        
        # Legacy support
        if testimonial_text and not quotes:
            center_quotes = Div(
                Blockquote(P(f'"{testimonial_text}"', cls="italic center-align large-text")),
                cls="login-quotes-wrapper"
            )
        
        left_content = Div(
            top_branding,
            center_quotes,
            cls="login-brand-content"
        )

    # 3. Build Right Column Buttons
    button_list = []
    for p in providers:
        icon = Img(src=p['icon'], cls=f"circle tiny spacing-right {p.get('icon_cls', '')}") if p.get('icon') else ""
        button_list.append(
            Div(
                A(
                    Button(icon, Span(p['label']), cls=p.get('cls')), 
                    href=p.get('href', '#')
                ),
                cls="s12"
            )
        )

    auth_buttons = Div(*button_list, cls="grid small-space")

    right_content = Div(
        H4(title, cls="center-align bold margin-bottom"),
        P(subtitle, cls="center-align medium-text margin-bottom no-wrap"),
        auth_buttons,
        cls="medium-width"
    )

    # 4. Build page
    right_cols = 12 - left_cols
    left_panel_cls = f"s12 m12 l{left_cols} login-brand-panel"
    
    # Include CSS, and optionally JS for color cycling
    head_elements = [Style(_LOGIN_SCREEN_CSS)]
    if color_cycle:
        head_elements.append(Script(_LOGIN_COLOR_CYCLE_JS))
    
    return Div(
        *head_elements,
        # Left (Brand) - gradient background with branding
        Div(left_content, cls=left_panel_cls),
        # Right (Auth) - clean form area
        Div(
            DivCentered(right_content),
            cls=f"s12 m12 l{right_cols} padding middle-align center-align"
        ),
        cls=f"grid no-space {cls}".strip(),
        style="min-height: 100vh;",
        **kwargs
    )


# %% ../nbs/03_app_pages.ipynb #20e88764
# Navbar height offset: 4.5rem (BeerCSS nav height) + 1rem (padding class)
# This fixes overlap when using sticky/blur navbars
_NAV_OFFSET = "calc(env(safe-area-inset-top, 0px) + 4.5rem + 1rem)"

def TopContent(*content, main_id='main-content', main_bg='surface'):
    """Wrap content for HTMX partial responses inside a TopLayout.
    
    Returns a full-width ``<main>`` element with padding-top offset for
    sticky navbars. Use with ``hx-swap="outerHTML"`` on the NavBar.
    
    If content is already a ``<main>`` element, returns it directly to
    prevent double-wrapping.
    
    Args:
        content: Page content (children)
        main_id: Must match the ``main_id`` used in TopLayout (default ``'main-content'``)
        main_bg: Background class (default ``'surface'``)
    
    Example::
    
        @rt("/dashboard")
        def get(req):
            page = dashboard_content()
            if 'HX-Request' in req.headers:
                return TopContent(page)
            return TopLayout(page, nav_bar=my_navbar())
    """
    # Prevent double-wrapping: if content is already a Main, return it directly
    if len(content) == 1 and hasattr(content[0], 'tag') and content[0].tag == 'main':
        return content[0]
    
    return Main(
        Div(*content), 
        id=main_id,
        cls=f"padding {main_bg}".strip(),
        style=f"padding-top: {_NAV_OFFSET};"
    )


def TopLayout(*content, nav_bar=None, main_id='main-content',
              main_bg='surface', **kwargs):
    """Top-navigation-only app shell — full-width content below a sticky NavBar.
    
    Returns ``(nav, main)`` as a tuple so they render as **sibling elements**
    directly under ``<body>``. This is required for BeerCSS's native layout
    engine.
    
    Configure the NavBar with ``sticky=True``, ``blur='small-blur'``, and 
    ``hx_swap='outerHTML'`` for the recommended glass-effect navigation.
    
    The ``<main>`` element has ``padding-top: 4.5rem`` (navbar height) to
    prevent content from being hidden under the sticky navbar, with iOS
    safe-area support.
    
    Use ``TopContent`` to wrap HTMX partial responses.
    
    Args:
        content: Page content (children)
        nav_bar: A ``NavBar(...)`` instance. Configure sticky/blur/hx_swap on NavBar directly.
        main_id: ID for the ``<main>`` content area (default ``'main-content'``)
        main_bg: Background class for the main area (default ``'surface'``)
    
    Example::

        TopLayout(
            H1("Dashboard"), DashboardGrid(),
            nav_bar=NavBar(
                A("Home", href="/"),
                brand=H5("MyApp"),
                sticky=True,
                blur='small-blur',
                hx_swap='outerHTML'
            ),
        )
        
    Route pattern (use TopContent for HTMX partials)::
    
        @rt("/dashboard")
        def dashboard(req):
            page = DashboardGrid()
            if 'HX-Request' in req.headers:
                return TopContent(page)
            return TopLayout(page, nav_bar=my_navbar())
    """
    result = []
    
    # Append NavBar as-is (configure sticky/blur/hx_swap on NavBar directly)
    if nav_bar:
        result.append(nav_bar)
    
    # Build full-width <main> with padding-top offset for sticky navbar
    if content:
        result.append(TopContent(*content, main_id=main_id, main_bg=main_bg))
    
    # Return as tuple — nav + main become siblings under <body>
    return tuple(result)
