{{--
|--------------------------------------------------------------------------
| Plik Widoku: Panel Główny (Vendor Dashboard)
|--------------------------------------------------------------------------
|
| Lokalizacja: resources/views/home.blade.php
| Autor: Tomasz Kaplanski
| Wersja: 1.0
| Ostatnia modyfikacja: 14 lipca 2025
|
|--------------------------------------------------------------------------
| Opis Przeznaczenia
|--------------------------------------------------------------------------
|
| Ten plik Blade renderuje główny panel informacyjny (dashboard) dla
| zalogowanego użytkownika z rolą "vendor" (sprzedawca/restauracja).
| Pełni on rolę centrum dowodzenia, agregując i wizualizując kluczowe
| dane biznesowe w czasie rzeczywistym. Widok umożliwia szybką ocenę
| bieżącej kondycji finansowej, statusu zamówień oraz przegląd
| najnowszej aktywności w systemie.
|
|--------------------------------------------------------------------------
| Kluczowe Funkcjonalności
|--------------------------------------------------------------------------
|
| - Wyświetlanie dynamicznych kafelków z kluczowymi metrykami (KPIs).
| - Interaktywny wykres słupkowy (Chart.js) prezentujący przegląd sprzedaży.
| - Tabela z listą 5 ostatnich, aktywnych zamówień (z zamaskowanym e-mailem klienta).
| - Warunkowe renderowanie całej sekcji dla sprzedawcy w oparciu o rolę użytkownika.
| - Pełnoekranowy loader informujący o procesie pobierania danych z bazy.
| - Pełna responsywność interfejsu.
|
|--------------------------------------------------------------------------
| Stos Technologiczny i Zależności
|--------------------------------------------------------------------------
|
| - Backend: Laravel (Blade, Auth, i18n)
| - Frontend: JavaScript (ES6+), Chart.js, Moment.js, Tailwind CSS, Font Awesome
| - Baza Danych (Client-Side): Google Firestore
| - Wymagane pole w Firestore: `restaurant_orders` musi zawierać `customerEmail`.
|
--}}

{{-- Pobranie roli zalogowanego użytkownika i usunięcie ewentualnych białych znaków --}}
<?php $role = trim(Auth::user()->getUserRole()); ?>

@extends('layouts.app')

@section('content')
{{-- Główny kontener (`wrapper`) całej zawartości strony, stylizowany za pomocą Tailwind CSS. --}}
<div id="main-wrapper" class="p-10">
    {{-- Kontener Flexbox dla głównych sekcji pulpitu, z odstępami (gap) --}}
    <div class="flex flex-col gap-6">

        {{-- Pełnoekranowa nakładka z loaderem (spinner), wyświetlana podczas ładowania danych z Firestore. --}}
        <div id="homeLoaderOverlay" class="hidden fixed inset-0 bg-black bg-opacity-80 z-50 flex items-center justify-center">
            <div class="text-white text-lg flex flex-col items-center gap-2">
                <i class="fa-solid fa-spinner fa-spin text-4xl"></i>
                <span class="text-base">{{ trans('lang.processing') }}</span>
            </div>
        </div>

        {{-- ====================================================================== --}}
        {{-- SEKCJA DANYCH SPRZEDAWCY (WIDOCZNA TYLKO DLA ROLI 'vendor')          --}}
        {{-- ====================================================================== --}}
        @if ($role == 'vendor')

        {{-- Nagłówek sekcji "Zarobki" z sumą całkowitą i linkiem do centrum eksportu --}}
        <div class="rounded-lg shadow-[1px_1px_4px_0px_#e2e8f0] p-4 bg-gradient-to-r from-slate-900 via-blue-800 to-blue-500 flex items-center justify-between">
            <div>
                <h3 class="text-2xl font-bold text-slate-50">{!! trans('lang.earning_plural') !!}</h3>
                <p class="text-sm text-slate-200 mt-1 m-0">{!! trans('lang.earning_desc') !!}</p>
                {{-- Całkowite zarobki wszech czasów (wypełniane przez JavaScript) --}}
                <h1 class="text-2xl font-bold mt-2 text-white" id="earnings_count"></h1>
            </div>
            <a href="{{ route('user.payment_details') }}" class="px-4 py-2 rounded-md bg-white text-slate-700 text-sm transition focus:outline-none flex items-center justify-center gap-2 whitespace-nowrap hover:no-underline hover:text-slate-700">
                <span class="flex items-center gap-2">
                    <i class="fa-solid fa-download"></i>
                    <span>{{ trans('lang.export_center_title') }}</span>
                </span>
            </a>
        </div>

        {{-- Kafelki (KPI tiles) z podsumowaniem zarobków w podziale na okresy (roczny, miesięczny, tygodniowy) --}}
        <div class="flex flex-col md:flex-row w-full gap-4">
            <div class="flex-1 min-w-0 border !border-gray-300 rounded-lg shadow-[1px_1px_4px_0px_#e2e8f0] p-4 bg-white">
                <p class="text-sm font-medium m-0">{!! trans('lang.yearly_earnings') !!}</p>
                <h3 id="yearly_earnings" class="text-xl font-bold mt-2 text-blue-500"></h3>
            </div>
            <div class="flex-1 min-w-0 border !border-gray-300 rounded-lg shadow-[1px_1px_4px_0px_#e2e8f0] p-4 bg-white">
                <p class="text-sm font-medium m-0">{!! trans('lang.monthly_earnings') !!}</p>
                <h3 id="monthly_earnings" class="text-xl font-bold mt-2 text-blue-500"></h3>
            </div>
            <div class="flex-1 min-w-0 border !border-gray-300 rounded-lg shadow-[1px_1px_4px_0px_#e2e8f0] p-4 bg-white">
                <p class="text-sm font-medium m-0">{!! trans('lang.weekly_earnings') !!}</p>
                <h3 id="weekly_earnings" class="text-xl font-bold mt-2 text-blue-500"></h3>
            </div>
        </div>

        {{-- Kontener na wykres sprzedaży z filtrami i nawigacją --}}
        <div class="border border-gray-300 rounded-lg shadow-[1px_1px_4px_0px_#e2e8f0] p-4 bg-white">
            <div class="flex flex-col md:flex-row md:justify-between md:items-center gap-4 mb-6">
                {{-- Nagłówek wykresu i suma dla wybranego zakresu --}}
                <div class="flex flex-col">
                    <h3 class="text-xl text-slate-800 font-bold m-0">{{ trans('lang.sales_overview') }}</h3>
                    <p class="text-sm text-stlate-600 m-0" id="salesTotalTitle"></p>
                    <h1 class="text-2xl font-extrabold mt-2 text-blue-500" id="rangeSalesSum"></h1>
                </div>

                {{-- Przyciski do filtrowania i nawigacji po wykresie --}}
                <div class="flex flex-col md:items-end gap-3">
                    <div class="flex gap-3 justify-end">
                        <button id="yearBtn" class="px-4 py-2 rounded-md border !border-slate-300 bg-white text-slate-700 text-sm hover:bg-slate-100 transition focus:outline-none focus:ring-0">{{ trans('lang.year') }}</button>
                        <button id="monthBtn" class="px-4 py-2 rounded-md border !border-slate-300 bg-white text-slate-700 text-sm hover:bg-slate-100 transition focus:outline-none focus:ring-0">{{ trans('lang.month') }}</button>
                        <button id="weekBtn" class="px-4 py-2 rounded-md border !border-slate-300 bg-white text-slate-700 text-sm hover:bg-slate-100 transition focus:outline-none focus:ring-0">{{ trans('lang.week') }}</button>
                    </div>
                    <div class="flex items-center gap-3 justify-end border !border-slate-300 rounded-full p-1">
                        <button id="prevRangeBtn" class="w-8 h-8 flex items-center justify-center rounded-full bg-white text-gray-700 hover:bg-slate-100 transition focus:outline-none focus:ring-0" title="{{ trans('lang.previous_range') }}"><i class="fa-solid fa-chevron-left"></i></button>
                        <span id="chartDateTitle" class="text-sm font-medium text-slate-700 min-w-[120px] text-center"></span>
                        <button id="nextRangeBtn" class="w-8 h-8 flex items-center justify-center rounded-full bg-white text-gray-700 hover:bg-slate-100 transition focus:outline-none focus:ring-0" title="{{ trans('lang.next_range') }}"><i class="fa-solid fa-chevron-right"></i></button>
                    </div>
                </div>
            </div>

            {{-- Element <canvas> renderowany przez bibliotekę Chart.js --}}
            <div class="border border-gray-300 rounded-lg overflow-hidden bg-blue-50 bg-opacity-25 p-4">
                <canvas id="sales-chart" height="400"></canvas>
            </div>
        </div>
        @endif {{-- Koniec warunku @if ($role == 'vendor') --}}

        {{-- Nagłówek sekcji "Zamówienia" z sumą wszystkich zamówień --}}
        <div class="rounded-lg shadow-[1px_1px_4px_0px_#e2e8f0] p-4 mt-4 bg-gradient-to-r from-slate-900 via-blue-800 to-blue-500 flex items-center justify-between">
            <div>
                <h3 class="text-2xl font-bold text-slate-50">{!! trans('lang.orders') !!}</h3>
                <p class="text-sm text-slate-200 mt-1 m-0">{!! trans('lang.orders_desc') !!}</p>
                <h1 class="text-2xl font-bold mt-2 text-white" id="order_count"></h1>
            </div>
        </div>

        {{-- Kafelki z podsumowaniem liczby zamówień dla kluczowych statusów --}}
        <div class="flex flex-col md:flex-row w-full gap-4">
            <div class="flex-1 min-w-0 border !border-gray-300 rounded-lg shadow-[1px_1px_4px_0px_#e2e8f0] p-4 bg-white">
                <p class="text-sm text-slate-800 font-medium m-0">{!! trans('lang.dashboard_order_placed') !!}</p>
                <h4 id="placed_count" class="text-xl font-bold mt-2 text-blue-500"></h4>
            </div>
            <div class="flex-1 min-w-0 border !border-gray-300 rounded-lg shadow-[1px_1px_4px_0px_#e2e8f0] p-4 bg-white">
                <p class="text-sm text-slate-800 font-medium m-0">{!! trans('lang.dashboard_order_accepted') !!}</p>
                <h4 id="confirmed_count" class="text-xl font-bold mt-2 text-blue-500"></h4>
            </div>
            <div class="flex-1 min-w-0 border !border-gray-300 rounded-lg shadow-[1px_1px_4px_0px_#e2e8f0] p-4 bg-white">
                <p class="text-sm text-slate-800 font-medium m-0">{!! trans('lang.dashboard_order_completed') !!}</p>
                <h4 id="completed_count" class="text-xl font-bold mt-2 text-blue-500"></h4>
            </div>
            <div class="flex-1 min-w-0 border !border-gray-300 rounded-lg shadow-[1px_1px_4px_0px_#e2e8f0] p-4 bg-white">
                <p class="text-sm text-slate-800 font-medium m-0">{!! trans('lang.dashboard_payment_failed') !!}</p>
                <h4 id="failed_payment_count" class="text-xl font-bold mt-2 text-red-500"></h4>
            </div>
        </div>

        {{-- Kontener tabeli z 5 ostatnimi aktywnymi zamówieniami --}}
        <div class="bg-white border !border-slate-300 rounded-lg shadow-[1px_1px_4px_0px_#e2e8f0] relative">
            <div class="p-4">
                <h3 class="text-xl text-slate-800 font-bold m-0">{!! trans('lang.last_orders') !!}</h3>
                <p class="text-sm text-slate-600 m-0">{!! trans('lang.last_orders_desc') !!}</p>
            </div>
            <table class="w-full text-sm text-slate-700" id="homeOrderTable">
                <thead class="bg-gradient-to-r from-slate-900 via-slate-800 to-slate-900 text-slate-50">
                    <tr>
                        {{-- ID zamówienia --}}
                        <th class="px-4 py-3 uppercase font-semibold text-center align-middle relative before:absolute before:right-0 before:top-[20%] before:h-[60%] before:border-r before:border-slate-600">
                            {{ trans('lang.order_id') }}
                        </th>
                        {{-- Email klienta --}}
                        <th class="px-4 py-3 uppercase font-semibold text-center align-middle relative before:absolute before:right-0 before:top-[20%] before:h-[60%] before:border-r before:border-slate-600">
                            {{ trans('lang.customer') }}
                        </th>
                        {{-- Status zamówienia --}}
                        <th class="px-4 py-3 uppercase font-semibold text-center align-middle relative before:absolute before:right-0 before:top-[20%] before:h-[60%] before:border-r before:border-slate-600">
                            {{ trans('lang.order_order_status_id') }}
                        </th>
                        {{-- Typ zamówienia --}}
                        <th class="px-4 py-3 uppercase font-semibold text-center align-middle relative before:absolute before:right-0 before:top-[20%] before:h-[60%] before:border-r before:border-slate-600">
                            {{ trans('lang.order_type') }}
                        </th>
                        {{-- Cena zamówienia --}}
                        <th class="px-4 py-3 uppercase font-semibold text-center align-middle relative before:absolute before:right-0 before:top-[20%] before:h-[60%] before:border-r before:border-slate-600">
                            {{ trans('lang.total_amount') }}
                        </th>
                        {{-- Ilość produktów --}}
                        <th class="px-4 py-3 uppercase font-semibold text-center align-middle relative before:absolute before:right-0 before:top-[20%] before:h-[60%] before:border-r before:border-slate-600">
                            {{ trans('lang.quantity') }}
                        </th>
                        {{-- Data zamówienia --}}
                        <th class="px-4 py-3 uppercase font-semibold text-center align-middle relative before:absolute before:right-0 before:top-[20%] before:h-[60%] before:border-r before:border-slate-600">
                            {{ trans('lang.date') }}
                        </th>
                        {{-- Akcje --}}
                        <th class="px-4 py-3 uppercase font-semibold text-center align-middle relative">
                            {{ trans('lang.actions') }}
                        </th>
                    </tr>
                </thead>
                {{-- Korpus tabeli, wypełniany dynamicznie przez funkcję loadLastOrders() --}}
                <tbody id="append_list_recent_order" class="divide-y divide-slate-200">
                    {{-- Wiersze zostaną wstawione tutaj przez JavaScript --}}
                </tbody>
            </table>
        </div>

    </div>
</div>
@endsection

@section('scripts')
{{-- Dołączenie skryptów specyficznych dla tej strony --}}
<script src="{{ asset('js/chart.js') }}"></script>

{{-- Obiekt globalny do przekazywania tłumaczeń z Laravela (PHP) do JavaScript --}}
<script>
    window.langTranslations = {
        sales_total_for: "{!! trans('lang.sales_total_for') !!}",
        sales_total_for_week: "{!! trans('lang.sales_total_for_week') !!}",
        week: "{!! trans('lang.week') !!}",
        month: "{!! trans('lang.month') !!}",
        year: "{!! trans('lang.year') !!}",
        months_long: {!! json_encode(trans('lang.months_long')) !!},
        months_short: {!! json_encode(trans('lang.months_short')) !!}
    };
</script>

{{-- Główny blok skryptów dla pulpitu --}}
<script>
    document.addEventListener('DOMContentLoaded', function() {
/**
         * ====================================================================
         * INICJALIZACJA I DEKLARACJA ZMIENNYCH
         * ====================================================================
         */

        // Ustawienie aktywnego elementu w menu nawigacyjnym.
        const menuHome = document.getElementById("menu_home");
        if (menuHome) {
            menuHome.classList.add("active");
        }
        // Zmienne globalne przechowujące stan i dane aplikacji.
        const loaderOverlay = document.getElementById("homeLoaderOverlay");
        let currentCurrency = '';
        let currencyAtRight = false;
        let decimal_degits = 0;
        const vendorUserId = "<?php echo $id; ?>";
        let vendorId = '';
        let allCompletedOrders = [];
        const salesTotalTitleEl = document.getElementById('salesTotalTitle');
        const rangeSalesSumEl = document.getElementById('rangeSalesSum');
        const chartDateTitleEl = document.getElementById('chartDateTitle');
        let currentViewMode = 'year';
        let referenceDate = new Date();
        let earliestDate = null;
        const now = new Date();
        // Wyświetlenie nakładki ładowania na czas operacji asynchronicznych.
        if (loaderOverlay) {
            loaderOverlay.classList.remove("hidden");
        }

        /**
         * ====================================================================
         * GŁÓWNA LOGIKA APLIKACJI (Pobieranie i przetwarzanie danych)
         * ====================================================================
         */
        // Pobranie aktywnych ustawień waluty z Firestore.
        const refCurrency = database.collection('currencies').where('isActive', '==', true);
        refCurrency.get().then(async function(snapshots) {
            const currencyData = snapshots.docs[0].data();
            currentCurrency = currencyData.symbol;
            currencyAtRight = currencyData.symbolAtRight;
            if (currencyData.decimal_degits) {
                decimal_degits = currencyData.decimal_degits;
            }
        });

        // Główna sekwencja operacji po uzyskaniu ID sprzedawcy.
        getVendorId(vendorUserId).then(async (data) => {
            vendorId = data;
            loadOrderCount(vendorId);
            loadProductCount(vendorId);
            loadOrderStatusCounts(vendorId);
            loadLastOrders(vendorId);
            allCompletedOrders = await fetchAllCompletedOrders(vendorId);
            loadTotalEarnings(allCompletedOrders);
            calculateAndDisplayPeriodicEarnings(allCompletedOrders);
            earliestDate = findEarliestDate(allCompletedOrders);

            // Ustawienie globalnych zmiennych z zakresem dat dla nawigacji na wykresie.
            window.earliestWeek = getMondayOfWeek(earliestDate);
            window.earliestMonth = getStartOfMonth(earliestDate);
            window.earliestYear = getStartOfYear(earliestDate);
            window.latestWeek = getMondayOfWeek(now);
            window.latestMonth = getStartOfMonth(now);
            window.latestYear = getStartOfYear(now);

            // Inicjalizacja wykresu z widokiem rocznym.
            currentViewMode = 'year';
            referenceDate = new Date();
            loadYearlyEarnings(referenceDate);

            // Ukrycie nakładki ładowania po zakończeniu operacji.
            if (loaderOverlay) {
                loaderOverlay.classList.add("hidden");
            }

            // Przypisanie event listenerów do przycisków zmiany zakresu wykresu.
            const weekBtn = document.getElementById('weekBtn');
            const monthBtn = document.getElementById('monthBtn');
            const yearBtn = document.getElementById('yearBtn');

            if (weekBtn) {
                weekBtn.addEventListener('click', () => {
                    currentViewMode = 'week';
                    referenceDate = new Date();
                    loadWeeklyEarnings(referenceDate);
                });
            }
            if (monthBtn) {
                monthBtn.addEventListener('click', () => {
                    currentViewMode = 'month';
                    referenceDate = new Date();
                    loadMonthlyEarnings(referenceDate);
                });
            }
            if (yearBtn) {
                yearBtn.addEventListener('click', () => {
                    currentViewMode = 'year';
                    referenceDate = new Date();
                    loadYearlyEarnings(referenceDate);
                });
            }

            // Przypisanie event listenerów do przycisków nawigacji (poprzedni/następny).
            const prevBtn = document.getElementById('prevRangeBtn');
            const nextBtn = document.getElementById('nextRangeBtn');
            if (prevBtn) {
                prevBtn.addEventListener('click', goPrevRange);
            }
            if (nextBtn) {
                nextBtn.addEventListener('click', goNextRange);
            }
        });

        /**
         * ====================================================================
         * NOWA FUNKCJA: Maskuje adres e-mail, pokazując pierwsze 3 znaki nazwy.
         * ====================================================================
         */
        function obfuscatedEmail(email) {
            if (!email) return '-';
            const atIndex = email.indexOf('@');
            if (atIndex === -1) return email;

            const name = email.slice(0, atIndex);
            const domain = email.slice(atIndex);

            return name.length > 3 ?
                name.slice(0, 3) + '...' + domain :
                email;
        }

        /**
         * Oblicza i zwraca datę poniedziałku dla tygodnia, w którym znajduje się podana data.
         * Ustawia godzinę na 00:00:00.
         */
        function getMondayOfWeek(date) {
            const result = new Date(date);
            let day = result.getDay();
            if (day === 0) day = 7;
            result.setDate(result.getDate() - (day - 1));
            result.setHours(0, 0, 0, 0);
            return result;
        }

        /**
         * Zwraca pierwszy dzień miesiąca dla podanej daty.
         */
        function getStartOfMonth(date) {
            return new Date(date.getFullYear(), date.getMonth(), 1, 0, 0, 0, 0);
        }

        /**
         * Zwraca pierwszy dzień roku dla podanej daty.
         */
        function getStartOfYear(date) {
            return new Date(date.getFullYear(), 0, 1, 0, 0, 0, 0);
        }

        /**
         * Tworzy klucz daty w formacie 'YYYY-MM-DD' do grupowania danych.
         */
        function getLocalDateKey(date) {
            const year = date.getFullYear();
            const month = (date.getMonth() + 1).toString().padStart(2, '0');
            const day = date.getDate().toString().padStart(2, '0');
            return `${year}-${month}-${day}`;
        }

        /**
         * Asynchronicznie pobiera ID sprzedawcy (vendorID) na podstawie ID użytkownika.
         */
        async function getVendorId(vendorUser) {
            let vId = '';
            if (vendorUser) {
                await database.collection('users').where('id', "==", vendorUser).get()
                    .then(function(snap) {
                        if (snap.docs[0]) {
                            const vendorData = snap.docs[0].data();
                            vId = vendorData.vendorID;
                        }
                    });
            }
            return vId;
        }

        /**
         * Asynchronicznie pobiera wszystkie zamówienia ze statusem 'Order Completed'
         * dla danego sprzedawcy.
         */
        async function fetchAllCompletedOrders(vid) {
            const orderSnapshots = await database.collection('restaurant_orders').where('vendorID', "==", vid).where('status', '==', "Order Completed").get();
            let orders = [];
            orderSnapshots.forEach(doc => {
                orders.push(doc.data());
            });
            return orders;
        }

         /**
         * Oblicza i wyświetla całkowite zarobki wszech czasów.
         */
        function loadTotalEarnings(orders) {
            let total = 0;
            orders.forEach(orderData => {
                const priceInfo = calculateOrderPrice(orderData);
                const val = priceInfo.total < 0 ? 0 : priceInfo.total;
                total += val;
            });

            const earningsCount = document.getElementById('earnings_count');
            if (earningsCount) {
                earningsCount.textContent = formatCurrency(total, currentCurrency, currencyAtRight, decimal_degits);
            }
        }

        /**
         * Oblicza i wyświetla zarobki dla bieżącego roku, miesiąca i tygodnia
         * w odpowiednich kafelkach KPI.
         */
        function calculateAndDisplayPeriodicEarnings(orders) {
            const now = new Date();
            const currentYear = now.getFullYear();
            const currentMonth = now.getMonth();
            const monday = getMondayOfWeek(now);
            const sunday = new Date(monday);
            sunday.setDate(sunday.getDate() + 6);
            sunday.setHours(23, 59, 59, 999);

            let yearlyTotal = 0, monthlyTotal = 0, weeklyTotal = 0;

            orders.forEach(order => {
                if (!order.createdAt) return;
                const orderDate = order.createdAt.toDate();
                const priceInfo = calculateOrderPrice(order);
                const val = priceInfo.total < 0 ? 0 : priceInfo.total;

                if (orderDate.getFullYear() === currentYear) yearlyTotal += val;
                if (orderDate.getFullYear() === currentYear && orderDate.getMonth() === currentMonth) monthlyTotal += val;
                if (orderDate >= monday && orderDate <= sunday) weeklyTotal += val;
            });

            const yearlyEl = document.getElementById('yearly_earnings');
            if(yearlyEl) yearlyEl.textContent = formatCurrency(yearlyTotal, currentCurrency, currencyAtRight, decimal_degits);
            
            const monthlyEl = document.getElementById('monthly_earnings');
            if(monthlyEl) monthlyEl.textContent = formatCurrency(monthlyTotal, currentCurrency, currencyAtRight, decimal_degits);

            const weeklyEl = document.getElementById('weekly_earnings');
            if(weeklyEl) weeklyEl.textContent = formatCurrency(weeklyTotal, currentCurrency, currencyAtRight, decimal_degits);
        }

        /**
         * Znajduje najwcześniejszą datę utworzenia zamówienia w dostarczonym zbiorze.
         */
        function findEarliestDate(orders) {
            if (!orders || !orders.length) return new Date();
            let minDate = new Date();
            orders.forEach(o => {
                if (o.createdAt) {
                    let d = o.createdAt.toDate();
                    if (d < minDate) minDate = d;
                }
            });
            return minDate;
        }

        /**
         * Obsługuje nawigację do poprzedniego zakresu dat na wykresie (tydzień/miesiąc/rok)
         * i odświeża dane.
         */
        function goPrevRange() {
            let newDate = new Date(referenceDate);
            if (currentViewMode === 'week') {
                newDate.setDate(newDate.getDate() - 7);
                if (newDate < window.earliestWeek) newDate = new Date(window.earliestWeek);
                referenceDate = newDate;
                loadWeeklyEarnings(referenceDate);
            } else if (currentViewMode === 'month') {
                newDate.setMonth(newDate.getMonth() - 1);
                if (newDate < window.earliestMonth) newDate = new Date(window.earliestMonth);
                referenceDate = newDate;
                loadMonthlyEarnings(referenceDate);
            } else if (currentViewMode === 'year') {
                newDate.setFullYear(newDate.getFullYear() - 1);
                if (newDate < window.earliestYear) newDate = new Date(window.earliestYear);
                referenceDate = newDate;
                loadYearlyEarnings(referenceDate);
            }
        }

        /**
         * Obsługuje nawigację do następnego zakresu dat na wykresie (tydzień/miesiąc/rok)
         * i odświeża dane.
         */
        function goNextRange() {
            let newDate = new Date(referenceDate);
            if (currentViewMode === 'week') {
                newDate.setDate(newDate.getDate() + 7);
                if (newDate > window.latestWeek) newDate = new Date(window.latestWeek);
                referenceDate = newDate;
                loadWeeklyEarnings(referenceDate);
            } else if (currentViewMode === 'month') {
                newDate.setMonth(newDate.getMonth() + 1);
                if (newDate > window.latestMonth) newDate = new Date(window.latestMonth);
                referenceDate = newDate;
                loadMonthlyEarnings(referenceDate);
            } else if (currentViewMode === 'year') {
                newDate.setFullYear(newDate.getFullYear() + 1);
                if (newDate > window.latestYear) newDate = new Date(window.latestYear);
                referenceDate = newDate;
                loadYearlyEarnings(referenceDate);
            }
        }

        /**
         * Pobiera i wyświetla całkowitą liczbę zamówień (z wyłączeniem statusów płatności).
         */
        function loadOrderCount(vid) {
            database.collection('restaurant_orders').where('vendorID', "==", vid).get()
                .then((snapshot) => {
                    const docsArray = snapshot.docs.map(doc => doc.data());
                    const ordersArray = docsArray.filter(o => !["Payment Pending", "Payment Failed"].includes(o.status));
                    const orderCount = document.getElementById("order_count");
                    if (orderCount) orderCount.textContent = ordersArray.length;
                });
        }

        /**
         * Pobiera i wyświetla całkowitą liczbę produktów w menu.
         */
        function loadProductCount(vid) {
            database.collection('vendor_products').where('vendorID', "==", vid).get()
                .then((snapshot) => {
                    const productCount = document.getElementById("product_count");
                    if (productCount) productCount.textContent = snapshot.docs.length;
                });
        }

        /**
         * Ładuje i renderuje dane o sprzedaży dla wybranego tygodnia.
         * Agreguje dane dzienne i aktualizuje wykres oraz podsumowania.
         */
        function loadWeeklyEarnings(refDate) {
            setActiveChartButton('weekBtn');
            currentViewMode = 'week';
            let refDay = refDate.getDay();
            if (refDay === 0) refDay = 7;
            const monday = new Date(refDate);
            monday.setHours(0, 0, 0, 0);
            monday.setDate(monday.getDate() - (refDay - 1));
            const sunday = new Date(monday);
            sunday.setDate(sunday.getDate() + 6);
            sunday.setHours(23, 59, 59, 999);
            const weekNumber = moment(monday).isoWeek();
            const yearNumber = monday.getFullYear();
            if (salesTotalTitleEl) salesTotalTitleEl.textContent = `${window.langTranslations.sales_total_for_week} ${weekNumber} (${yearNumber})`;
            if (chartDateTitleEl) chartDateTitleEl.textContent = `${window.langTranslations.week} ${weekNumber} (${yearNumber})`;
            let dailyTotals = {}, totalEarning = 0;
            allCompletedOrders.forEach(orderData => {
                if (!orderData.createdAt) return;
                let createdTS = orderData.createdAt.toDate();
                if (createdTS >= monday && createdTS <= sunday) {
                    let priceInfo = calculateOrderPrice(orderData);
                    let totalVal = priceInfo.total < 0 ? 0 : priceInfo.total;
                    totalEarning += totalVal;
                    let key = getLocalDateKey(createdTS);
                    dailyTotals[key] = (dailyTotals[key] || 0) + totalVal;
                }
            });
            let labels = [], data = [];
            let loopDate = new Date(monday);
            while (loopDate <= sunday) {
                let key = getLocalDateKey(loopDate);
                let dd = loopDate.getDate().toString().padStart(2, '0');
                let mm = (loopDate.getMonth() + 1).toString().padStart(2, '0');
                labels.push(`${dd}/${mm}`);
                data.push(dailyTotals[key] || 0);
                loopDate.setDate(loopDate.getDate() + 1);
            }
            if (rangeSalesSumEl) rangeSalesSumEl.textContent = formatCurrency(totalEarning, currentCurrency, currencyAtRight, decimal_degits);
            const salesChartNode = document.getElementById('sales-chart');
            if (salesChartNode) renderChart(salesChartNode, data, labels, currentCurrency, currencyAtRight, decimal_degits);
        }

        /**
         * Ładuje i renderuje dane o sprzedaży dla wybranego miesiąca.
         * Agreguje dane dzienne i aktualizuje wykres oraz podsumowania.
         */
        function loadMonthlyEarnings(refDate) {
            setActiveChartButton('monthBtn');
            currentViewMode = 'month';
            const firstDay = new Date(refDate.getFullYear(), refDate.getMonth(), 1, 0, 0, 0, 0);
            const lastDay = new Date(refDate.getFullYear(), refDate.getMonth() + 1, 0, 23, 59, 59, 999);
            const monthIndex = refDate.getMonth();
            const monthName = window.langTranslations.months_long[monthIndex];
            const yearNumber = refDate.getFullYear();
            if (salesTotalTitleEl) salesTotalTitleEl.textContent = `${window.langTranslations.sales_total_for} ${monthName} ${yearNumber}`;
            if (chartDateTitleEl) chartDateTitleEl.textContent = `${monthName} ${yearNumber}`;
            let dailyTotals = {}, totalEarning = 0;
            allCompletedOrders.forEach(orderData => {
                if (!orderData.createdAt) return;
                let createdTS = orderData.createdAt.toDate();
                if (createdTS >= firstDay && createdTS <= lastDay) {
                    let priceInfo = calculateOrderPrice(orderData);
                    let totalVal = priceInfo.total < 0 ? 0 : priceInfo.total;
                    totalEarning += totalVal;
                    let key = getLocalDateKey(createdTS);
                    dailyTotals[key] = (dailyTotals[key] || 0) + totalVal;
                }
            });
            let labels = [], data = [];
            let loopDate = new Date(firstDay);
            while (loopDate <= lastDay) {
                let key = getLocalDateKey(loopDate);
                let dd = loopDate.getDate().toString().padStart(2, '0');
                let mm = (loopDate.getMonth() + 1).toString().padStart(2, '0');
                labels.push(`${dd}/${mm}`);
                data.push(dailyTotals[key] || 0);
                loopDate.setDate(loopDate.getDate() + 1);
            }
            if (rangeSalesSumEl) rangeSalesSumEl.textContent = formatCurrency(totalEarning, currentCurrency, currencyAtRight, decimal_degits);
            const salesChartNode = document.getElementById('sales-chart');
            if (salesChartNode) renderChart(salesChartNode, data, labels, currentCurrency, currencyAtRight, decimal_degits);
        }

        /**
         * Ładuje i renderuje dane o sprzedaży dla wybranego roku.
         * Agreguje dane miesięczne i aktualizuje wykres oraz podsumowania.
         */
        function loadYearlyEarnings(refDate) {
            setActiveChartButton('yearBtn');
            currentViewMode = 'year';
            const targetYear = refDate.getFullYear();
            if (salesTotalTitleEl) salesTotalTitleEl.textContent = `${window.langTranslations.sales_total_for} ${targetYear}`;
            if (chartDateTitleEl) chartDateTitleEl.textContent = targetYear;
            let monthlyTotals = Array(12).fill(0), totalEarning = 0;
            allCompletedOrders.forEach(orderData => {
                if (!orderData.createdAt) return;
                let createdTS = orderData.createdAt.toDate();
                if (createdTS.getFullYear() === targetYear) {
                    let priceInfo = calculateOrderPrice(orderData);
                    let totalVal = priceInfo.total < 0 ? 0 : priceInfo.total;
                    totalEarning += totalVal;
                    const orderMonth = createdTS.getMonth();
                    monthlyTotals[orderMonth] += totalVal;
                }
            });
            if (rangeSalesSumEl) rangeSalesSumEl.textContent = formatCurrency(totalEarning, currentCurrency, currencyAtRight, decimal_degits);
            let labels = [];
            for (let m = 0; m < 12; m++) {
                labels.push(window.langTranslations.months_short[m]);
            }
            const salesChartNode = document.getElementById('sales-chart');
            if (salesChartNode) renderChart(salesChartNode, monthlyTotals, labels, currentCurrency, currencyAtRight, decimal_degits);
        }

        /**
         * Oblicza całkowitą wartość zamówienia na podstawie jego produktów, dodatków,
         * zniżek, podatków i kosztów dostawy.
         */
        function calculateOrderPrice(orderData) {
            let price = 0, basePrice = 0;
            if (orderData.order) {
                orderData.order.forEach((product) => {
                    if (product.totalPrice && product.quantity) {
                        const extrasP = product.extras_price ? parseFloat(product.extras_price) * parseInt(product.quantity) : 0;
                        const productTotal = (parseFloat(product.totalPrice) * parseInt(product.quantity)) + extrasP;
                        price += productTotal;
                        basePrice += productTotal;
                    }
                });
            }
            if (orderData.discount) {
                const discountVal = parseFloat(orderData.discount) || 0;
                price -= discountVal;
                basePrice -= discountVal;
            }
            if (orderData.hasOwnProperty('taxSetting') && orderData.taxSetting.type && orderData.taxSetting.tax) {
                if (orderData.taxSetting.type === 'percent') {
                    const t = (parseFloat(orderData.taxSetting.tax) * basePrice) / 100;
                    price += t;
                } else {
                    price += parseFloat(orderData.taxSetting.tax);
                }
            }
            if (orderData.deliveryCharge) {
                price += parseFloat(orderData.deliveryCharge);
            }
            return { total: price };
        }

        /**
         * Pobiera i wyświetla liczbę zamówień dla każdego z kluczowych statusów.
         */
        function loadOrderStatusCounts(vid) {
            const statusMap = {
                placed_count: ['Order Placed'],
                confirmed_count: ['Order Accepted', 'Driver Accepted'],
                completed_count: ['Order Completed'],
                failed_payment_count: ['Payment Failed'],
                shipped_count: ['Order Shipped', 'In Transit'],
                canceled_count: ['Order Rejected'],
                failed_count: ['Driver Rejected'],
                pending_count: ['Driver Pending']
            };
            for (const [id, statuses] of Object.entries(statusMap)) {
                database.collection('restaurant_orders').where('vendorID', '==', vid).where('status', 'in', statuses).get()
                    .then((snapshot) => {
                        const el = document.getElementById(id);
                        if (el) el.textContent = snapshot.docs.length;
                    });
            }
        }

        /**
         * Pobiera i wyświetla 5 ostatnich aktywnych zamówień w tabeli.
         */
        function loadLastOrders(vid) {
            const appendListEl = document.getElementById('append_list_recent_order');
            if (!appendListEl) return;
            appendListEl.innerHTML = '';
            database.collection('restaurant_orders').where('vendorID', '==', vid).orderBy('createdAt', 'desc').limit(10).get()
                .then(async (snapshots) => {
                    let html = await buildOrderHTML(snapshots);
                    if (html !== '') {
                        appendListEl.innerHTML = html;
                        attachTooltipListeners();
                    }
                });
        }

        /**
         * Buduje kod HTML dla wierszy tabeli z ostatnimi zamówieniami.
         */
        async function buildOrderHTML(snapshots) {
            let rows = [];
            for (const doc of snapshots.docs) {
                if (rows.length >= 5) break;
                const rowHtml = await getListData(doc.data());
                if (rowHtml) rows.push(rowHtml);
            }
            return rows.join('');
        }

        function attachTooltipListeners() {
            const tooltipContainers = document.querySelectorAll('.js-tooltip-container');
            tooltipContainers.forEach(container => {
                const tooltip = container.querySelector('.js-tooltip-content');
                if (tooltip) {
                    container.addEventListener('mouseenter', () => {
                        tooltip.classList.remove('opacity-0', 'translate-y-2', 'pointer-events-none');
                        tooltip.classList.add('opacity-100', 'translate-y-0');
                    });
                    container.addEventListener('mouseleave', () => {
                        tooltip.classList.add('opacity-0', 'translate-y-2', 'pointer-events-none');
                        tooltip.classList.remove('opacity-100', 'translate-y-0');
                    });
                }
            });
        }

        /**
         * Generuje kod HTML dla pojedynczego wiersza w tabeli ostatnich zamówień.
         */
        async function getListData(val) {
            if (['Payment Pending'].includes(val.status)) return '';

            // KLUCZOWA ZMIANA: Wywołanie funkcji maskującej e-mail klienta.
            const customerIdentifier = obfuscatedEmail(val.customerEmail);

            let editUrl = `<?php echo route('orders.edit', ':id'); ?>`.replace(':id', val.id);
            const createdAtObj = val.createdAt ? moment(val.createdAt.toDate()) : null;
            const datePart = createdAtObj ? createdAtObj.format('DD.MM.YYYY') : '-';
            const timePart = createdAtObj ? createdAtObj.format('HH:mm') : '';
            const statusLabel = transStatus(val.status);
            const badgeClass = statusBadgeClass(val.status);
            const iconClass = statusIconClass(val.status);
            const typeLabel = (val.tableNumber === null) ? `{!! trans('lang.counter_pickup') !!}` : `{!! trans('lang.table_service') !!}`;
            const priceHtml = `${currentCurrency} ${parseFloat(val.checkOutPrice || 0).toFixed(decimal_degits)}`;
            const itemsCount = Array.isArray(val.order) ? val.order.length : 0;

            return `
            <tr class="hover:bg-gradient-to-r from-blue-50 via-blue-100 to-blue-50 transition-colors delay-50 duration-300 ease-in-out">
                <td class="px-4 py-3 text-center align-middle text-sm text-slate-700">${val.id}</td>
                <td class="px-4 py-3 text-center align-middle text-sm text-slate-700">${customerIdentifier}</td>
                <td class="px-4 py-3 text-center align-middle">
                    <span class="inline-flex items-center px-3 py-2 rounded-md text-xs font-medium ${badgeClass}">
                        <i class="mr-2 text-base ${iconClass}"></i>
                        ${statusLabel}
                    </span>
                </td>
                <td class="px-4 py-3 text-center align-middle text-sm text-slate-700">${typeLabel}</td>
                <td class="px-4 py-3 text-center align-middle text-sm font-bold text-blue-500">${priceHtml}</td>
                <td class="px-4 py-3 text-center align-middle text-sm text-slate-700">
                    <div class="flex justify-center items-center gap-1">
                        <i class="fa fa-shopping-cart text-sm"></i>
                        ${itemsCount}
                    </div>
                </td>
                <td class="px-4 py-3 text-center align-middle text-sm leading-tight">
                    <div class="flex flex-col items-center">
                        <span class="text-slate-700">${datePart}</span>
                        <span class="inline-flex items-center gap-1 text-slate-500">
                            <i class="fa-regular fa-clock text-xs"></i>
                            <span>${timePart}</span>
                        </span>
                    </div>
                </td>
                <td class="px-4 py-3 text-center align-middle text-sm whitespace-nowrap">
                    <div class="js-tooltip-container relative flex justify-center">
                        <a href="${editUrl}" class="flex h-10 w-10 items-center justify-center rounded-lg text-slate-400 hover:bg-blue-100 hover:text-blue-500 transition hover:no-underline">
                            <i class="fa-solid fa-ellipsis text-xl"></i>
                        </a>
                        <div class="js-tooltip-content absolute top-full left-1/2 mt-2 w-max max-w-xs bg-slate-800 text-white text-center text-xs rounded py-2 px-3 z-10 transition-all duration-300 ease-out opacity-0 translate-y-2 pointer-events-none" style="transform: translateX(-50%);">
                            {!! trans('lang.edit') !!}
                            <div class="absolute left-1/2 -translate-x-1/2 bottom-full w-0 h-0 border-x-8 border-x-transparent border-b-8 border-b-slate-800"></div>
                        </div>
                    </div>
                </td>
            </tr>`;
        }

        /**
         * Tłumaczy status zamówienia na język zdefiniowany w plikach `lang` Laravela.
         */
        function transStatus(status) {
            switch (status) {
                case 'Order Placed': return '{!! trans("lang.dashboard_order_placed") !!}';
                case 'Order Accepted': return '{!! trans("lang.dashboard_order_accepted") !!}';
                case 'Order Rejected': return '{!! trans("lang.dashboard_order_canceled") !!}';
                case 'Driver Pending': return '{!! trans("lang.dashboard_order_pending") !!}';
                case 'Order Completed': return '{!! trans("lang.dashboard_order_completed") !!}';
                case 'Payment Failed': return '{!! trans("lang.dashboard_payment_failed") !!}';
                default: return status;
            }
        }

        /**
         * Zwraca klasy CSS dla "badge'a" statusu na podstawie jego wartości.
         */
        function statusBadgeClass(s) {
            switch (s) {
                case 'Order Placed': return 'bg-blue-50 border !border-blue-500 text-blue-500';
                case 'Order Accepted': case 'Order Completed': return 'bg-green-50 border !border-green-600 text-green-600';
                case 'Order Rejected': return 'bg-red-50 border !border-red-600 text-red-600';
                case 'Payment Pending': return 'bg-yellow-50 border !border-yellow-600 text-yellow-600';
                case 'Payment Failed': return 'bg-slate-100 border !border-slate-600 text-slate-600';
                default: return 'bg-slate-100 border !border-slate-600 text-slate-600';
            }
        }

        /**
         * Zwraca klasy CSS dla ikony Font Awesome na podstawie statusu zamówienia.
         */
        function statusIconClass(s) {
            switch (s) {
                case 'Order Placed': return 'fa fa-shopping-bag';
                case 'Order Accepted': case 'Order Completed': return 'fa fa-check-circle';
                case 'Order Rejected': return 'fa fa-times-circle';
                case 'Payment Pending': return 'fa fa-exclamation-circle';
                case 'Payment Failed': return 'fa fa-info-circle';
                default: return 'fa fa-info-circle';
            }
        }

        /**
         * Formatuje kwotę pieniężną zgodnie z ustawieniami waluty.
         */
        function formatCurrency(amount, symbol, atRight, decimals = 0) {
            const val = parseFloat(amount).toFixed(decimals);
            return atRight ? (val + ' ' + symbol) : (symbol + ' ' + val);
        }

        /**
         * Renderuje lub aktualizuje wykres sprzedaży za pomocą Chart.js.
         * Niszczy poprzednią instancję wykresu, jeśli istnieje, aby uniknąć problemów.
         */
        function renderChart(chartNode, data, labels, currency, currencyAtRight, decimals) {
            const ctx = chartNode.getContext('2d');
            const gradientFill = ctx.createLinearGradient(0, 0, 0, chartNode.height);
            gradientFill.addColorStop(0, 'rgba(59,130,246,0.8)');
            gradientFill.addColorStop(1, 'rgba(29,78,216,0.8)');
            const xTicks = { color: '#334155', font: { weight: 'bold' } };
            const yTicks = {
                color: '#334155', font: { weight: 'bold' },
                callback: function(value) {
                    const val = parseFloat(value).toFixed(decimals);
                    return currencyAtRight ? (val + currency) : (currency + val);
                }
            };
            if (window.mySalesChart) window.mySalesChart.destroy();
            window.mySalesChart = new Chart(ctx, {
                type: 'bar',
                data: {
                    labels: labels,
                    datasets: [{
                        label: '', data: data, backgroundColor: gradientFill, borderColor: '#3B82F6',
                        borderWidth: 1, borderRadius: 8, borderSkipped: 'bottom'
                    }]
                },
                options: {
                    responsive: true, maintainAspectRatio: false,
                    layout: { padding: { bottom: 10 } },
                    events: ['mousemove', 'touchstart', 'touchmove', 'touchend', 'click'],
                    plugins: {
                        legend: { display: false },
                        tooltip: {
                            mode: 'index', intersect: false, padding: 12,
                            titleFont: { size: 14, weight: 'bold' }, bodyFont: { size: 13 },
                            callbacks: {
                                label: function(context) {
                                    const rawValue = context.parsed.y;
                                    const val = parseFloat(rawValue).toFixed(decimals);
                                    return currencyAtRight ? (val + currency) : (currency + val);
                                }
                            }
                        }
                    },
                    scales: {
                        x: { display: true, grid: { display: true, color: '#e2e8f0' }, ticks: xTicks },
                        y: {
                            display: true, beginAtZero: true, min: 0,
                            grid: { display: true, color: '#e2e8f0', borderColor: 'transparent', lineWidth: 1 },
                            ticks: yTicks
                        }
                    }
                }
            });
        }

        /**
         * Zarządza stylami przycisków (Tydzień, Miesiąc, Rok), aby wizualnie
         * zaznaczyć, który zakres jest aktualnie aktywny.
         */
        function setActiveChartButton(buttonId) {
            const ids = ['weekBtn', 'monthBtn', 'yearBtn'];
            ids.forEach(id => {
                const btn = document.getElementById(id);
                if (!btn) return;
                if (id === buttonId) {
                    btn.classList.remove('bg-white', 'text-slate-700', 'hover:bg-slate-100', 'font-normal', 'border', '!border-slate-300');
                    btn.classList.add('bg-blue-500', 'text-white', 'font-semibold');
                } else {
                    btn.classList.remove('bg-blue-500', 'text-white', 'font-semibold');
                    btn.classList.add('bg-white', 'text-slate-700', 'hover:bg-slate-100', 'font-normal', 'border', '!border-slate-300');
                }
            });
        }

        // Globalny event listener do obsługi przekierowań na podstawie atrybutu `data-url`.
        document.body.addEventListener('click', function(e) {
            if (e.target && e.target.classList.contains('redirecttopage')) {
                const url = e.target.getAttribute('data-url');
                window.location.href = url;
            }
        });
    });
</script>

<script src="https://cdn.jsdelivr.net/npm/moment@2.29.1/moment.min.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css">
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
@endsection