<!DOCTYPE html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}" data-theme="@themeId">

<head>
    <meta charset="utf-8">
    <meta content="width=device-width, initial-scale=1" name="viewport">
    <meta content="{{ csrf_token() }}" name="csrf-token">
    <meta content="{{config('app.name')}}" name="title">
    @unless(timebank_config('seo.allow_indexing_auth'))
        <meta name="robots" content="noindex, nofollow, noarchive, nosnippet">
    @endunless

    @auth
        <meta name="user-id" content="{{ auth()->id() }}">
        <meta name="user-guard" content="{{ config('auth.defaults.guard') }}">
    @endauth

    @php
        // Determine page title: explicit title > header content > fallback
        $pageTitle = null;

        // Check if header slot is set and extract text from it
        if (isset($header) && $header) {
            $headerContent = (string) $header;
            $pageTitle = trim(strip_tags($headerContent));
        }

        // Fall back to StringHelper if no valid header content
        if (empty($pageTitle)) {
            $pageTitle = \App\Helpers\StringHelper::getPageTitle();
        }
    @endphp

    <title>@yield('title', $pageTitle) - {{ config('app.name') }}</title>
    <link rel="icon" type="image/x-icon" href="{{ asset('favicon.ico') }}">
    <link rel="icon" type="image/png" sizes="32x32" href="{{ asset('favicon-32x32.png') }}">
    <link rel="icon" type="image/png" sizes="16x16" href="{{ asset('favicon-16x16.png') }}">
    <link rel="apple-touch-icon" sizes="180x180" href="{{ asset('apple-touch-icon.png') }}">

    <!-- Scripts head -->
    <script src="{{ route('lang.js') }}"></script>
    <!-- Fonts -->
    {{-- <link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Nunito:wght@400;600;700&display=swap"> --}}

    <!-- Styles -->
    <link href="{{ asset('css/tagify.css') }}" rel="stylesheet">

    <!-- Dynamic Theme CSS Custom Properties -->
    <style>
        :root {
            {!! theme_css_vars() !!}
        }
    </style>

    @vite(['resources/css/app.css', 'resources/css/fonts.css', 'resources/sass/custom_timebank.css'])
    <link href="{{ asset('css/custom_tagify.css') }}" rel="stylesheet">
    @livewireStyles
    @wirechatStyles

    <!-- Flatpickr Styles -->
    <x-flatpickr::style />


    <style>
/* Theme-aware typography */
body {
    font-family: var(--font-family-body, 'Poppins', sans-serif) !important;
}

/* Theme-aware heading styles */
h1, h2, h3, h4, h5, h6 {
    font-family: var(--font-family-heading, 'Oswald', sans-serif) !important;
    text-transform: var(--heading-transform, uppercase) !important;
}

/* Apply theme-specific CSS custom properties */
:root {
    @themeCssVars
}
    </style>

    <!-- Quill editor (loaded locally via Vite) -->
    @vite('resources/js/quill.js')
    <style>
        .ql-editor {
            height: 500px;
        }
    </style>

    <!-- Scripts (wireui moved to body to fix Firefox Alpine init order) -->


{{-- TODO: Move styles below to separate css file, that can be compiled --}}
    <style>
        input[type=file]::file-selector-button {
            border-style: none;
            padding: 0;
            color: #fff !important;
            padding-left: 1.0rem;
            padding-top: 0.25rem;
            padding-right: 1.0rem;
            padding-bottom: 0.25rem;
            border-radius: 0.25rem;
            -webkit-appearance: button;
            font-weight: 700;
            --tw-bg-opacity: 1;
            background-color: rgb(107 114 128 / var(--tw-bg-opacity));
            text-transform: none;
        }

        input[type=file]::file-selector-button:hover {
            cursor: pointer;
            --tw-text-opacity: 1;
            --tw-bg-opacity: 1;
            background-color: rgb(107 114 128 / var(--tw-bg-opacity));
        }

        progress {
            width: 100%;
            height: 20px;
            border: none;
            background-color: #f1f1f1;
        }

        progress::-webkit-progress-bar {
            background-color: #f1f1f1;
        }

        progress::-webkit-progress-value {
            background-color: #9ae6b4;
        }

        progress::-moz-progress-bar {
            background-color: #9ae6b4;
        }
    </style>

</head>

<body class="font-sans antialiased flex flex-col min-h-screen">

    <x-jetstream.banner />
    <x-jetstream.toaster />

        <div class="flex-grow md:bg-theme-surface">
            @livewire('navigation-menu')
        <x-notifications position="bottom-end" />


            <header class="bg-theme-brand text-xl font-semibold text-theme-background shadow sm:mt-16">
                <!-- System Anounnucement -->
                @livewire('system-announcement', ['type' => 'SiteContents\SystemAnnouncement' ?? null, 'limit' => 1])
                <!-- Maintenance Banner -->
                @livewire('admin.maintenance-banner')
                <!-- Header --->
                @if (isset($header))
                    <div class="max-w-7xl mx-auto py-2 px-4 sm:px-6 lg:px-8">
                        {{ $header }}
                    </div>
                @endif
            </header>

        <!-- Page Content -->
        <main>
            {{ $slot }}
        </main>
    </div>

    <!-- Footer -->
    <div class="mt-auto w-full">
        <x-footer />
    </div>

    <!-- Forced Logout Modal -->
    @auth
        @livewire('forced-logout-modal')
        @livewire('account-info-modal')
    @endauth

    <!-- Scripts body-->
    <!-- Be careful with changing the loading order! -->
    <wireui:scripts />
    @livewireScripts
    @vite('resources/js/app.js')
    @wirechatAssets

    <!-- Session Expiration Detection -->
    <script>
        // Detect session expiration and auto-reload
        document.addEventListener('DOMContentLoaded', function() {
            let sessionExpired = false;
            let isLoggingOut = false;

            // Mark when logout is initiated
            document.addEventListener('click', function(e) {
                const logoutButton = e.target.closest('form[action*="logout"]') ||
                                   e.target.closest('button[wire\\:click*="logout"]') ||
                                   e.target.closest('a[href*="logout"]');
                if (logoutButton) {
                    isLoggingOut = true;
                }
            });

            // Detect Livewire 401/419 errors (session expired)
            window.addEventListener('livewire:request', ({ detail }) => {
                detail.fail(({ status, content, preventDefault }) => {
                    if (status === 401 || status === 419) {
                        preventDefault(); // Always prevent default to avoid "Page expired" dialog

                        if (!sessionExpired) {
                            sessionExpired = true;

                            // Small delay to let other pending requests complete
                            setTimeout(() => {
                                // If logging out, redirect to home instead of reloading
                                if (isLoggingOut) {
                                    window.location.href = '{{ LaravelLocalization::localizeUrl('/') }}';
                                } else {
                                    window.location.reload();
                                }
                            }, 100);
                        }
                    }
                });
            });

            // Detect Echo connection errors (session expired)
            if (window.Echo && window.Echo.connector && window.Echo.connector.pusher) {
                window.Echo.connector.pusher.connection.bind('error', function(err) {
                    // Check if it's an authentication error
                    if (err && (err.type === 'AuthError' || err.error?.data?.code === 4009)) {
                        if (!sessionExpired) {
                            sessionExpired = true;
                            // Delay reload slightly to avoid rapid reloads
                            setTimeout(() => window.location.reload(), 1000);
                        }
                    }
                });

            }

            // Catch "Handler does not exist" errors globally
            window.addEventListener('error', function(event) {
                const message = event.message || '';
                if (message.includes('Handler for event') && message.includes('does not exist')) {
                    // This means session expired and component is stale
                    if (!sessionExpired) {
                        sessionExpired = true;
                        window.location.reload();
                    }
                    event.preventDefault();
                    return false;
                }
            }, true);

            // Suppress the specific Echo error message in console
            const originalConsoleError = console.error;
            console.error = function(...args) {
                const message = args[0]?.toString() || '';
                // Don't log Echo handler errors if we're already reloading
                if (sessionExpired && message.includes('Handler for event')) {
                    return;
                }
                // Suppress handler errors and trigger reload
                if (message.includes('Handler for event') && message.includes('does not exist')) {
                    if (!sessionExpired) {
                        sessionExpired = true;
                        setTimeout(() => window.location.reload(), 500);
                    }
                    return;
                }
                originalConsoleError.apply(console, args);
            };
        });
    </script>

    <!-- Flatpickr Scripts -->
    <x-flatpickr::script />

    <!-- Flatpickr Error Handling Override -->
    <script>
    // Wrap the original Flatpickr initialization with error handling
    if (window.LaravelFlatpickr) {
        const originalInit = window.LaravelFlatpickr.initializeFlatpickr;
        window.LaravelFlatpickr.initializeFlatpickr = function(e) {
            try {
                // Check if element and required methods exist
                if (!e || !e.getAttribute) return;

                const targetId = e.getAttribute("data-selector-id");
                if (!targetId) return;

                const target = document.getElementById(targetId);
                if (!target) return;

                // Call original initialization
                originalInit.call(this, e);
            } catch (error) {
                // Silently fail to prevent console spam
                // console.warn('Flatpickr initialization skipped:', error);
            }
        };
    }
    </script>

    <!-- Suppress non-critical Alpine.js errors during Livewire morphing -->
    <script>
    // Suppress WireUI select component errors during Livewire morphing
    // These errors occur when Alpine tries to evaluate expressions before the component data is initialized
    // They don't affect functionality as the components initialize correctly after morphing completes

    // Store original console methods
    const originalError = console.error;
    const originalWarn = console.warn;

    // List of error patterns to suppress
    const suppressedPatterns = [
        /positionable is not defined/,
        /getSelectedValue is not defined/,
        /isEmpty is not defined/,
        /getPlaceholder is not defined/,
        /config is not defined/,
        /getSelectedDisplayText is not defined/,
        /asyncData is not defined/,
        /displayOptions is not defined/,
        /isNotEmpty is not defined/,
        /selectedOptions is not defined/,
        /wireui_select/,
        /Alpine Expression Error/,
        /ReferenceError.*is not defined/
    ];

    function shouldSuppressMessage(args) {
        const message = args.map(arg => {
            if (typeof arg === 'string') return arg;
            if (arg instanceof Error) return arg.message;
            return String(arg);
        }).join(' ');

        return suppressedPatterns.some(pattern => pattern.test(message));
    }

    // Override console.error
    console.error = function(...args) {
        if (!shouldSuppressMessage(args)) {
            originalError.apply(console, args);
        }
    };

    // Override console.warn (some frameworks log errors as warnings)
    console.warn = function(...args) {
        if (!shouldSuppressMessage(args)) {
            originalWarn.apply(console, args);
        }
    };

    // Catch uncaught errors in promises and event handlers
    window.addEventListener('error', function(event) {
        if (shouldSuppressMessage([event.message || event.error?.message || ''])) {
            event.preventDefault();
            event.stopPropagation();
            return false;
        }
    }, true);

    window.addEventListener('unhandledrejection', function(event) {
        if (shouldSuppressMessage([event.reason?.message || event.reason || ''])) {
            event.preventDefault();
            return false;
        }
    }, true);
    </script>

    @stack('scripts')
    @yield('scripts_body')
    @yield('js')
    @stack('modals')

    <!-- Listen for forced logout event -->
    @auth
    <script>
        document.addEventListener('DOMContentLoaded', function() {
            if (window.Echo) {
                window.Echo.private('user.logout.{{ auth()->id() }}')
                    .listen('.forced-logout', (e) => {
                        // Get current locale from HTML lang attribute
                        const locale = document.documentElement.lang || 'en';

                        // Translate message in user's locale using window.i18n
                        const messageKey = e.message_key || 'For security and maintenance, a system administrator has logged you out of your account. Sorry for this inconvenience and thanks for your patience.';
                        let message = messageKey;
                        if (window.i18n && window.i18n[locale] && window.i18n[locale][messageKey]) {
                            message = window.i18n[locale][messageKey];
                        }

                        // Show alert and immediately redirect to login page
                        // This avoids CSRF errors from deleted sessions
                        alert(message);

                        // Redirect to login page with a maintenance mode flag
                        window.location.href = '{{ route("login") }}?logged_out=maintenance';
                    });
            }
        });
    </script>
    @endauth


</body>

</html>
