/**
 * RUHONDO BEACH RESORT HMS + POS System
 * Main Application JavaScript
 * Developer: JOACHIM'S INNOTECH
 * Version: 1.0.0
 */

// =============================================
// GLOBAL APP OBJECT
// =============================================
const App = {
    // Configuration
    config: {
        baseUrl: window.appConfig?.baseUrl || '',
        assetsUrl: window.appConfig?.assetsUrl || '',
        csrfToken: window.appConfig?.csrfToken || '',
        csrfParam: window.appConfig?.csrfParam || 'csrf_token',
        userId: window.appConfig?.userId || null,
        userName: window.appConfig?.userName || '',
        currencySymbol: window.appConfig?.currencySymbol || '$',
        dateFormat: window.appConfig?.dateFormat || 'Y-m-d',
        datetimeFormat: window.appConfig?.datetimeFormat || 'Y-m-d H:i:s'
    },

    // State
    state: {
        currentPage: window.location.pathname,
        isMobile: window.innerWidth < 768,
        sidebarCollapsed: localStorage.getItem('sidebarCollapsed') === 'true',
        theme: localStorage.getItem('theme') || 'light',
        notifications: []
    },

    // =========================================
    // INITIALIZATION
    // =========================================
    init: function() {
        console.log('App initialized');
        
        // Initialize components
        this.initTooltips();
        this.initPopovers();
        this.initSelect2();
        this.initDatepickers();
        this.initDataTables();
        this.initFormValidation();
        this.initNumberFormatting();
        
        // Setup event listeners
        this.setupEventListeners();
        
        // Load initial data
        this.loadNotifications();
        this.updateOnlineStatus();
        
        // Apply theme
        this.applyTheme(this.state.theme);
    },

    // =========================================
    // UI COMPONENTS INITIALIZATION
    // =========================================
    initTooltips: function() {
        const tooltipTriggerList = [].slice.call(document.querySelectorAll('[data-toggle="tooltip"]'));
        tooltipTriggerList.map(function(tooltipTriggerEl) {
            return new bootstrap.Tooltip(tooltipTriggerEl);
        });
    },

    initPopovers: function() {
        const popoverTriggerList = [].slice.call(document.querySelectorAll('[data-toggle="popover"]'));
        popoverTriggerList.map(function(popoverTriggerEl) {
            return new bootstrap.Popover(popoverTriggerEl);
        });
    },

    initSelect2: function() {
        $('.select2').select2({
            theme: 'bootstrap-5',
            width: '100%',
            dropdownParent: $('body')
        });
        
        $('.select2-tags').select2({
            theme: 'bootstrap-5',
            tags: true,
            tokenSeparators: [',', ' '],
            width: '100%'
        });
        
        $('.select2-ajax').each(function() {
            const $this = $(this);
            const url = $this.data('url');
            const minimumInputLength = $this.data('minimum-input-length') || 2;
            
            $this.select2({
                theme: 'bootstrap-5',
                width: '100%',
                minimumInputLength: minimumInputLength,
                ajax: {
                    url: url,
                    dataType: 'json',
                    delay: 250,
                    data: function(params) {
                        return {
                            q: params.term,
                            page: params.page || 1
                        };
                    },
                    processResults: function(data, params) {
                        params.page = params.page || 1;
                        return {
                            results: data.data,
                            pagination: {
                                more: (params.page * 30) < data.total
                            }
                        };
                    },
                    cache: true
                },
                placeholder: $this.data('placeholder') || 'Search...',
                allowClear: true
            });
        });
    },

    initDatepickers: function() {
        $('.datepicker').datepicker({
            format: 'yyyy-mm-dd',
            autoclose: true,
            todayHighlight: true,
            orientation: 'bottom'
        });
        
        $('.datepicker-range').datepicker({
            format: 'yyyy-mm-dd',
            autoclose: true,
            todayHighlight: true,
            orientation: 'bottom'
        });
        
        $('.datetimepicker').datetimepicker({
            format: 'YYYY-MM-DD HH:mm:ss',
            icons: {
                time: 'far fa-clock',
                date: 'far fa-calendar',
                up: 'fas fa-arrow-up',
                down: 'fas fa-arrow-down',
                previous: 'fas fa-chevron-left',
                next: 'fas fa-chevron-right',
                today: 'fas fa-calendar-check',
                clear: 'fas fa-trash',
                close: 'fas fa-times'
            }
        });
    },

    initDataTables: function() {
        if (!$.fn.DataTable) return;
        
        $.extend(true, $.fn.dataTable.defaults, {
            language: {
                lengthMenu: 'Show _MENU_ entries',
                zeroRecords: 'No records found',
                info: 'Showing _START_ to _END_ of _TOTAL_ entries',
                infoEmpty: 'Showing 0 to 0 of 0 entries',
                infoFiltered: '(filtered from _MAX_ total entries)',
                search: 'Search:',
                paginate: {
                    first: 'First',
                    last: 'Last',
                    next: 'Next',
                    previous: 'Previous'
                }
            },
            pageLength: 25,
            responsive: true,
            processing: true,
            serverSide: false,
            dom: "<'row'<'col-sm-12 col-md-6'l><'col-sm-12 col-md-6'f>>" +
                 "<'row'<'col-sm-12'tr>>" +
                 "<'row'<'col-sm-12 col-md-5'i><'col-sm-12 col-md-7'p>>"
        });
        
        $('.datatable').each(function() {
            const $this = $(this);
            const options = $this.data('options') || {};
            
            // Server-side processing if URL provided
            if ($this.data('ajax-url')) {
                options.serverSide = true;
                options.ajax = {
                    url: $this.data('ajax-url'),
                    type: 'POST',
                    data: function(d) {
                        d.csrf_token = App.config.csrfToken;
                    }
                };
            }
            
            // Add buttons if enabled
            if ($this.data('buttons')) {
                options.dom = "<'row'<'col-sm-12 col-md-6'l><'col-sm-12 col-md-6'f>>" +
                             "<'row'<'col-sm-12'tr>>" +
                             "<'row'<'col-sm-12 col-md-5'i><'col-sm-12 col-md-7'p>>" +
                             "<'row'<'col-sm-12'B>>";
                options.buttons = ['copy', 'csv', 'excel', 'pdf', 'print'];
            }
            
            $this.DataTable(options);
        });
    },

    initFormValidation: function() {
        if (!$.validator) return;
        
        $.validator.addMethod('strongPassword', function(value, element) {
            return this.optional(element) || /^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[@$!%*?&])[A-Za-z\d@$!%*?&]{8,}$/.test(value);
        }, 'Password must contain at least 8 characters, one uppercase, one lowercase, one number and one special character');
        
        $.validator.addMethod('phone', function(value, element) {
            return this.optional(element) || /^\+?[0-9]{10,15}$/.test(value);
        }, 'Please enter a valid phone number');
        
        $.validator.addMethod('date', function(value, element) {
            return this.optional(element) || /^\d{4}-\d{2}-\d{2}$/.test(value);
        }, 'Please enter a valid date (YYYY-MM-DD)');
        
        $('form.validate').each(function() {
            const $form = $(this);
            const options = $form.data('validation') || {};
            
            $form.validate({
                errorElement: 'span',
                errorClass: 'invalid-feedback',
                highlight: function(element) {
                    $(element).addClass('is-invalid');
                },
                unhighlight: function(element) {
                    $(element).removeClass('is-invalid');
                },
                errorPlacement: function(error, element) {
                    if (element.parent('.input-group').length) {
                        error.insertAfter(element.parent());
                    } else {
                        error.insertAfter(element);
                    }
                },
                ...options
            });
        });
    },

    initNumberFormatting: function() {
        $('.currency-input').on('input', function() {
            let value = $(this).val();
            value = value.replace(/[^\d.]/g, '');
            if (value) {
                value = parseFloat(value).toFixed(2);
                $(this).val(value);
            }
        });
        
        $('.number-input').on('input', function() {
            let value = $(this).val();
            value = value.replace(/[^\d]/g, '');
            $(this).val(value);
        });
    },

    // =========================================
    // EVENT LISTENERS
    // =========================================
    setupEventListeners: function() {
        // Window resize
        window.addEventListener('resize', () => {
            this.state.isMobile = window.innerWidth < 768;
        });
        
        // Sidebar toggle
        $(document).on('click', '[data-widget="pushmenu"]', (e) => {
            e.preventDefault();
            this.toggleSidebar();
        });
        
        // Confirm actions
        $(document).on('click', '[data-confirm]', (e) => {
            if (!this.confirmAction($(e.currentTarget).data('confirm'))) {
                e.preventDefault();
            }
        });
        
        // Delete confirm
        $(document).on('click', '.delete-confirm', (e) => {
            e.preventDefault();
            const url = $(e.currentTarget).attr('href');
            const message = $(e.currentTarget).data('message') || 'Are you sure you want to delete this item?';
            
            this.confirmDialog(message, 'Delete', 'warning').then((result) => {
                if (result) {
                    window.location.href = url;
                }
            });
        });
        
        // AJAX form submission
        $(document).on('submit', 'form.ajax-form', (e) => {
            e.preventDefault();
            this.submitAjaxForm(e.target);
        });
        
        // Print
        $(document).on('click', '[data-print]', (e) => {
            e.preventDefault();
            const target = $(e.currentTarget).data('print');
            this.print(target);
        });
        
        // Export
        $(document).on('click', '[data-export]', (e) => {
            e.preventDefault();
            const type = $(e.currentTarget).data('export');
            const url = $(e.currentTarget).attr('href');
            this.exportData(url, type);
        });
    },

    // =========================================
    // SIDEBAR FUNCTIONS
    // =========================================
    toggleSidebar: function() {
        this.state.sidebarCollapsed = !this.state.sidebarCollapsed;
        localStorage.setItem('sidebarCollapsed', this.state.sidebarCollapsed);
        
        if (this.state.sidebarCollapsed) {
            document.body.classList.add('sidebar-collapse');
        } else {
            document.body.classList.remove('sidebar-collapse');
        }
    },

    // =========================================
    // THEME FUNCTIONS
    // =========================================
    applyTheme: function(theme) {
        document.body.classList.remove('light-mode', 'dark-mode', 'auto-mode');
        document.body.classList.add(theme + '-mode');
        localStorage.setItem('theme', theme);
    },

    toggleTheme: function() {
        const newTheme = this.state.theme === 'light' ? 'dark' : 'light';
        this.state.theme = newTheme;
        this.applyTheme(newTheme);
    },

    // =========================================
    // NOTIFICATION FUNCTIONS
    // =========================================
    loadNotifications: function() {
        $.ajax({
            url: this.config.baseUrl + '/api/notifications.php',
            method: 'GET',
            success: (response) => {
                if (response.status === 'success') {
                    this.state.notifications = response.data;
                    this.updateNotificationBadge();
                }
            }
        });
    },

    updateNotificationBadge: function() {
        const unread = this.state.notifications.filter(n => !n.is_read).length;
        const badge = document.querySelector('.navbar-badge');
        
        if (badge) {
            if (unread > 0) {
                badge.textContent = unread;
                badge.style.display = 'inline';
            } else {
                badge.style.display = 'none';
            }
        }
    },

    markNotificationRead: function(notificationId) {
        $.ajax({
            url: this.config.baseUrl + '/api/notifications.php',
            method: 'POST',
            data: {
                action: 'mark_read',
                notification_id: notificationId,
                csrf_token: this.config.csrfToken
            },
            success: (response) => {
                if (response.status === 'success') {
                    this.loadNotifications();
                }
            }
        });
    },

    // =========================================
    // ONLINE STATUS
    // =========================================
    updateOnlineStatus: function() {
        if (!navigator.onLine) {
            this.showOfflineWarning();
        }
        
        window.addEventListener('online', () => {
            this.hideOfflineWarning();
            this.loadNotifications();
        });
        
        window.addEventListener('offline', () => {
            this.showOfflineWarning();
        });
    },

    showOfflineWarning: function() {
        const warning = document.createElement('div');
        warning.className = 'offline-warning alert alert-warning fixed-top text-center';
        warning.innerHTML = '<i class="fas fa-wifi-slash mr-2"></i> You are offline. Some features may be unavailable.';
        warning.id = 'offlineWarning';
        
        if (!document.getElementById('offlineWarning')) {
            document.body.prepend(warning);
        }
    },

    hideOfflineWarning: function() {
        const warning = document.getElementById('offlineWarning');
        if (warning) {
            warning.remove();
        }
    },

    // =========================================
    // DIALOG FUNCTIONS
    // =========================================
    confirmAction: function(message) {
        return confirm(message || 'Are you sure?');
    },

    confirmDialog: function(message, title = 'Confirm', type = 'warning') {
        return new Promise((resolve) => {
            if (typeof Swal !== 'undefined') {
                Swal.fire({
                    title: title,
                    text: message,
                    icon: type,
                    showCancelButton: true,
                    confirmButtonColor: '#d33',
                    cancelButtonColor: '#3085d6',
                    confirmButtonText: 'Yes'
                }).then((result) => {
                    resolve(result.isConfirmed);
                });
            } else {
                resolve(confirm(message));
            }
        });
    },

    showAlert: function(message, title = 'Alert', type = 'info') {
        if (typeof Swal !== 'undefined') {
            Swal.fire({
                title: title,
                text: message,
                icon: type
            });
        } else {
            alert(message);
        }
    },

    showToast: function(message, type = 'info', title = '') {
        if (typeof toastr !== 'undefined') {
            toastr[type](message, title);
        } else {
            alert(message);
        }
    },

    // =========================================
    // AJAX FUNCTIONS
    // =========================================
    submitAjaxForm: function(form) {
        const $form = $(form);
        const url = $form.attr('action');
        const method = $form.attr('method') || 'POST';
        const data = new FormData(form);
        
        // Add CSRF token
        data.append(this.config.csrfParam, this.config.csrfToken);
        
        $.ajax({
            url: url,
            method: method,
            data: data,
            processData: false,
            contentType: false,
            success: (response) => {
                if (response.status === 'success') {
                    if (response.message) {
                        this.showToast(response.message, 'success');
                    }
                    
                    if (response.redirect) {
                        setTimeout(() => {
                            window.location.href = response.redirect;
                        }, 1000);
                    } else if (response.reload) {
                        location.reload();
                    }
                    
                    // Trigger form success event
                    $form.trigger('form:success', [response]);
                } else {
                    this.showToast(response.message || 'An error occurred', 'error');
                    $form.trigger('form:error', [response]);
                }
            },
            error: (xhr) => {
                const response = xhr.responseJSON;
                this.showToast(response?.message || 'An error occurred', 'error');
                $form.trigger('form:error', [response]);
            }
        });
    },

    // =========================================
    // PRINT & EXPORT FUNCTIONS
    // =========================================
    print: function(elementId) {
        const element = document.getElementById(elementId);
        if (!element) return;
        
        if (typeof printJS !== 'undefined') {
            printJS({
                printable: elementId,
                type: 'html',
                style: '@page { size: auto; margin: 20mm; }',
                css: [
                    this.config.baseUrl + '/assets/css/style.css',
                    'https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css'
                ]
            });
        } else {
            const printWindow = window.open('', '_blank');
            printWindow.document.write(`
                <html>
                    <head>
                        <title>Print</title>
                        <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
                        <link href="${this.config.baseUrl}/assets/css/style.css" rel="stylesheet">
                    </head>
                    <body>
                        ${element.outerHTML}
                        <script>
                            window.onload = function() {
                                window.print();
                                window.close();
                            };
                        <\/script>
                    </body>
                </html>
            `);
            printWindow.document.close();
        }
    },

    exportData: function(url, type) {
        window.location.href = url + '?export=' + type + '&csrf_token=' + this.config.csrfToken;
    },

    // =========================================
    // UTILITY FUNCTIONS
    // =========================================
    formatCurrency: function(amount) {
        return this.config.currencySymbol + ' ' + parseFloat(amount).toFixed(2).replace(/\d(?=(\d{3})+\.)/g, '$&,');
    },

    formatDate: function(date, format = 'YYYY-MM-DD') {
        return moment(date).format(format);
    },

    formatDateTime: function(datetime, format = 'YYYY-MM-DD HH:mm:ss') {
        return moment(datetime).format(format);
    },

    timeAgo: function(datetime) {
        return moment(datetime).fromNow();
    },

    debounce: function(func, wait) {
        let timeout;
        return function executedFunction(...args) {
            const later = () => {
                clearTimeout(timeout);
                func(...args);
            };
            clearTimeout(timeout);
            timeout = setTimeout(later, wait);
        };
    },

    throttle: function(func, limit) {
        let inThrottle;
        return function(...args) {
            if (!inThrottle) {
                func.apply(this, args);
                inThrottle = true;
                setTimeout(() => inThrottle = false, limit);
            }
        };
    },

    getUrlParameter: function(name) {
        name = name.replace(/[\[]/, '\\[').replace(/[\]]/, '\\]');
        const regex = new RegExp('[\\?&]' + name + '=([^&#]*)');
        const results = regex.exec(location.search);
        return results === null ? '' : decodeURIComponent(results[1].replace(/\+/g, ' '));
    },

    copyToClipboard: function(text) {
        navigator.clipboard.writeText(text).then(() => {
            this.showToast('Copied to clipboard', 'success');
        }).catch(() => {
            this.showToast('Failed to copy', 'error');
        });
    }
};

// =============================================
// INITIALIZE ON DOCUMENT READY
// =============================================
$(document).ready(function() {
    App.init();
});

// Export for use in other scripts
window.App = App;