(function (window, $) {
    if (!$) return;

    $(function () {
        var i18n = (window.nnaxFmAjax && window.nnaxFmAjax.i18n) ? window.nnaxFmAjax.i18n : {};
        function t(key, fallback) {
            return (i18n && typeof i18n[key] === 'string' && i18n[key] !== '') ? i18n[key] : fallback;
        }

        // Share modal is optional in some template contexts.
        // Bail out early to keep this module side-effect free when absent.
        var $modal = $('#nnaxfuf-share-modal');
        if (!$modal.length) return;
        var $shareForm = $modal.find('form.nnaxfuf-share-modal-form');

        // Cache frequently used nodes once. This keeps event handlers small
        // and avoids repeated DOM lookups.
        var $shareTitle = $('#nnaxfuf_share_modal_title');
        var $fileIdInput = $('#nnaxfuf_share_file_id');
        var $searchInput = $('#nnaxfuf_recipient_search');
        var $resultsContainer = $('#nnaxfuf_user_search_results');
        var $selectedList = $('#nnaxfuf_selected_users');
        var $hiddenContainer = $('#nnaxfuf_selected_users_hidden');
        var shareOptions = (window.nnaxFmAjax && window.nnaxFmAjax.share_options) ? window.nnaxFmAjax.share_options : {};
        var allowTimeLimit = Boolean(shareOptions.allow_time_limit);
        var allowOwnerRights = Boolean(shareOptions.allow_owner_rights);
        var allowSharedFolderFileDelete = Boolean(shareOptions.allow_shared_folder_file_delete);
        var $actionInput = $('#nnaxfuf_share_action');
        var $folderIdInput = $('#nnaxfuf_share_folder_id');
        var $nonceInput = $shareForm.find('input[name="nnaxfuf_nonce"]').first();
        var currentItemType = 'file';
        var currentUserId = parseInt((window.nnaxFmAjax && window.nnaxFmAjax.current_user_id) ? window.nnaxFmAjax.current_user_id : 0, 10);
        if (!Number.isFinite(currentUserId) || currentUserId <= 0) {
            currentUserId = 0;
        }
        var currentOwnerId = 0;
        var currentLayout = normalizeLayout((window.nnaxFmAjax && window.nnaxFmAjax.share_layout) ? window.nnaxFmAjax.share_layout : 'table');
        var searchTimeout = null;
        var userSearchRequest = null;

        var $sendNotificationBtn = $('#nnaxfuf_send_notification');
        var $notificationMsgContainer = $('#nnaxfuf_notification_msg_container');

        // Toggle notification message textarea visibility
        $sendNotificationBtn.on('change', function() {
            if ($(this).is(':checked')) {
                $notificationMsgContainer.slideDown('fast');
            } else {
                $notificationMsgContainer.slideUp('fast');
            }
        });

        // Layout is validated defensively so unknown values from settings
        // or future migrations cannot break modal rendering.
        function normalizeLayout(layout) {
            var value = (layout || '').toString().toLowerCase();
            if (value === 'card' || value === 'compact') return value;
            return 'table';
        }

        // The layout class is applied at modal root so CSS can switch
        // all inner row/list variants from one single state.
        function applyLayoutClass(layout) {
            var nextLayout = normalizeLayout(layout);
            $modal.removeClass('nnaxfuf-share-layout-table nnaxfuf-share-layout-card nnaxfuf-share-layout-compact');
            $modal.addClass('nnaxfuf-share-layout-' + nextLayout);
            currentLayout = nextLayout;
        }

        // Small public API for other modules/settings UI to change share layout live.
        window.NUFMShare = window.NUFMShare || {};
        window.NUFMShare.setLayout = function (layout) {
            applyLayoutClass(layout);
        };
        window.NUFMShare.getLayout = function () {
            return currentLayout;
        };
        applyLayoutClass(currentLayout);

        // Empty state helper keeps the selected list visually stable
        // (no "jumping" when the list is currently empty).
        function renderEmptySelectionState() {
            if (!$selectedList.length) return;
            if ($selectedList.children().length > 0) return;
            $selectedList.append($('<li>', { class: 'uk-text-muted nnaxfuf-selected-empty' }).text(t('share_empty', 'Currently shared with nobody.')));
        }

        // Always reset modal state before opening for a new file/folder.
        // This avoids stale recipients from previous interactions.
        function resetModal() {
            $searchInput.val('');
            $searchInput.attr('placeholder', t('search_placeholder_default', 'Enter name, username or email'));
            $resultsContainer.empty();
            $selectedList.empty();
            $hiddenContainer.empty();
            currentItemType = 'file';
            currentOwnerId = 0;
            if ($shareTitle.length) $shareTitle.text(t('share_title_item', 'Share Item'));
            renderEmptySelectionState();
        }

        // Backend expects repeated nnaxfuf_share_user_ids[] hidden fields.
        function addHiddenUserInput(userId) {
            $hiddenContainer.append($('<input>', { type: 'hidden', name: 'nnaxfuf_share_user_ids[]', value: String(userId) }));
        }

        // Duplicate protection is based on hidden payload, not visible rows,
        // because hidden inputs are the source of truth for submit data.
        function isUserSelected(userId) {
            var found = false;
            $hiddenContainer.find('input[name="nnaxfuf_share_user_ids[]"]').each(function () {
                if (String($(this).val()) === String(userId)) {
                    found = true;
                    return false;
                }
            });
            return found;
        }

        function isUserInVisibleList(userId) {
            return $selectedList.find('li[data-user-id="' + String(userId) + '"]').length > 0;
        }

        // Build per-user advanced controls (role/time window) depending on
        // admin feature flags passed from backend settings.
        function buildSharePermissionsControls(user, options) {
            var opts = options || {};
            if (opts.readonly || Boolean(user && user.is_owner)) {
                return $('<div>', { class: 'nnaxfuf-share-user-controls uk-flex-right@m' });
            }

            var role = opts.role || (opts.owner_rights ? 'manager' : 'normal');
            var startsOn = opts.starts_on || '';
            var expiresOn = opts.expires_on || '';
            var userId = String(user.id);
            var $wrap = $('<div>', { class: 'nnaxfuf-share-user-controls uk-flex-right@m' });

            if (allowOwnerRights) {
                var $roleField = $('<div>', { class: 'nnaxfuf-share-field nnaxfuf-share-field-role' });
                var $roleSelect = $('<select>', {
                    class: 'uk-select uk-form-small nnaxfuf-share-role-select',
                    name: 'nnaxfuf_share_user_configs[' + userId + '][role]'
                });
                $roleSelect.append($('<option>', { value: 'normal' }).text(t('role_normal', 'Normal')));
                $roleSelect.append($('<option>', { value: 'manager' }).text(t('role_manager', 'Manager')));
                if (allowSharedFolderFileDelete && currentItemType === 'folder') {
                    $roleSelect.append($('<option>', { value: 'admin' }).text(t('role_admin', 'Admin')));
                }
                if (role !== 'manager' && role !== 'admin') {
                    role = 'normal';
                }
                if (role === 'admin' && !(allowSharedFolderFileDelete && currentItemType === 'folder')) {
                    role = 'manager';
                }
                $roleSelect.val(role);
                $roleField.append($('<span>', { class: 'nnaxfuf-share-inline-label' }).text(t('label_role', 'Role')));
                $roleField.append($roleSelect);
                $wrap.append($roleField);
            }

            if (allowTimeLimit) {
                var $startDateField = $('<div>', { class: 'nnaxfuf-share-field nnaxfuf-share-field-date' });
                var $startDateInput = $('<input>', {
                    class: 'uk-input uk-form-small nnaxfuf-share-date-input',
                    type: 'date',
                    name: 'nnaxfuf_share_user_configs[' + userId + '][starts_on]',
                    value: startsOn
                });
                $startDateField.append($('<span>', { class: 'nnaxfuf-share-inline-label' }).text(t('label_from', 'From')));
                $startDateField.append($startDateInput);
                $wrap.append($startDateField);

                var $dateField = $('<div>', { class: 'nnaxfuf-share-field nnaxfuf-share-field-date' });
                var $dateInput = $('<input>', {
                    class: 'uk-input uk-form-small nnaxfuf-share-date-input',
                    type: 'date',
                    name: 'nnaxfuf_share_user_configs[' + userId + '][expires_on]',
                    value: expiresOn
                });
                $dateField.append($('<span>', { class: 'nnaxfuf-share-inline-label' }).text(t('label_until', 'Until')));
                $dateField.append($dateInput);
                $wrap.append($dateField);
            }

            return $wrap;
        }

        // Build one visual row for selected user list.
        // The row is layout-aware so table/card/compact share the same data model.
        function buildUserRow(user, options, layoutVariant) {
            var variant = normalizeLayout(layoutVariant);
            var opts = options || {};
            var isReadonlyUser = Boolean(opts.readonly || (user && user.is_owner));
            var label = user.display_name;
            // if (user.user_login) label += ' (' + user.user_login + ')';

            var $row = $('<div>', { class: 'uk-flex uk-flex-middle uk-flex-between uk-flex-wrap nnaxfuf-share-user-row nnaxfuf-share-user-row--' + variant });
            if (!isReadonlyUser) {
                $row.append($('<button>', {
                    type: 'button',
                    class: 'uk-button uk-button-text uk-text-danger nnaxfuf-share-remove nnaxfuf-remove-user',
                    'aria-label': t('remove', 'Remove'),
                    title: t('remove', 'Remove')
                }).html('<span class="uk-icon" uk-icon="icon: trash; ratio:0.8" style="vertical-align: text-bottom;"></span>'));
            }
            $row.append($('<span>', { class: 'nnaxfuf-share-user-name' }).text(label + ' '));
            $row.append(buildSharePermissionsControls(user, $.extend({}, opts, { readonly: isReadonlyUser })));

            return $row;
        }

        // Add selected user in all 3 places:
        // - hidden submit payload
        // - visible selected list
        // - empty-state placeholder cleanup
        function addUserToSelection(user, options, layoutVariant, isRole) {
            var opts = options || {};
            var skipHiddenInput = Boolean(opts.skipHiddenInput);
            var isReadonlyUser = Boolean(opts.readonly || (user && user.is_owner));
            if (!skipHiddenInput && isUserSelected(user.id)) return;
            if (skipHiddenInput && isUserInVisibleList(user.id)) return;

            $selectedList.find('.nnaxfuf-selected-empty').remove();
            if (!skipHiddenInput) {
                addHiddenUserInput(user.id);
            }

            var $li = $('<li>', { 'data-user-id': user.id });
            if (isRole || user.is_role) {
                $li.addClass('nnaxfuf-share-is-role');
            }
            if (isReadonlyUser) {
                $li.attr('data-locked', '1');
            }
            $li.append(buildUserRow(user, $.extend({}, opts, { readonly: isReadonlyUser }), layoutVariant || currentLayout));
            $selectedList.append($li);
        }

        // Loads current server state so opening the modal always reflects
        // persisted shares (and not only client-side transient state).
        function loadExistingShares(itemId, itemType) {
            if (!itemId) {
                renderEmptySelectionState();
                return;
            }

            $selectedList.empty().append($('<li>', { class: 'uk-text-muted nnaxfuf-selected-loading' }).text(t('loading_existing_shares', 'Loading existing shares...')));

            $.ajax({
                url: nnaxFmAjax.ajax_url,
                method: 'POST',
                dataType: 'json',
                data: {
                    action: 'nnaxfuf_get_item_share_state',
                    share_state_nonce: nnaxFmAjax.share_state_nonce || nnaxFmAjax.item_details_nonce || nnaxFmAjax.nonce,
                    item_id: itemId,
                    item_type: itemType
                }
            }).done(function (response) {
                $selectedList.empty();
                $hiddenContainer.empty();

                // Defensive response shape check because this endpoint may
                // be called by older plugin versions with different payloads.
                if (!response || !response.success || !response.data || !Array.isArray(response.data.users)) {
                    currentOwnerId = 0;
                    renderEmptySelectionState();
                    UIkit.notification({ message: t('shares_load_failed', 'Could not load existing shares.'), status: 'warning' });
                    return;
                }

                currentOwnerId = parseInt(response.data.owner_id, 10);
                if (!Number.isFinite(currentOwnerId) || currentOwnerId <= 0) {
                    currentOwnerId = 0;
                }

                response.data.users.forEach(function (user) {
                    var parsedUserId = parseInt(user.id, 10);
                    var isCurrentUser = Number.isFinite(parsedUserId) && parsedUserId > 0 && parsedUserId === currentUserId;
                    var isOwnerEntry = Boolean(user.is_owner) || (Number.isFinite(parsedUserId) && parsedUserId > 0 && parsedUserId === currentOwnerId);

                    if (!isOwnerEntry && isCurrentUser) {
                        return;
                    }

                    var displayName = (user.display_name || '').toString();
                    if (isOwnerEntry && displayName.indexOf(t('owner_suffix', '(Owner)')) === -1) {
                        displayName += ' ' + t('owner_suffix', '(Owner)');
                    }

                    var mappedRole = 'normal';
                    if (Boolean(user.can_delete) && allowSharedFolderFileDelete && currentItemType === 'folder') {
                        mappedRole = 'admin';
                    } else if (Boolean(user.owner_rights)) {
                        mappedRole = 'manager';
                    }
                    addUserToSelection({
                        id: user.id,
                        display_name: displayName,
                        user_login: user.user_login,
                        is_role: user.is_role,
                        is_owner: Boolean(user.is_owner)
                    }, {
                        owner_rights: Boolean(user.owner_rights),
                        role: mappedRole,
                        starts_on: (user.starts_on || '').toString(),
                        expires_on: (user.expires_on || '').toString(),
                        readonly: isOwnerEntry,
                        skipHiddenInput: isOwnerEntry
                    }, currentLayout, Boolean(user.is_role));
                });
                renderEmptySelectionState();
            }).fail(function () {
                $selectedList.empty();
                $hiddenContainer.empty();
                renderEmptySelectionState();
                UIkit.notification({ message: t('network_error_existing_shares', 'Network error while loading existing shares.'), status: 'danger' });
            });
        }

        // Open modal from action menu (file or folder).
        // We populate hidden action/id fields here so submit can stay generic.
        $(document).on('click', '.nnaxfuf-open-share-modal', function () {
            resetModal();

            var $btn = $(this);
            var itemType = $btn.data('nnaxfuf-item-type') || 'file';
            var itemTitle = $btn.data('nnaxfuf-item-title') || '';
            if (!itemTitle) {
                itemTitle = ($('#nnaxfuf_detail_title_input').val() || '').toString().trim();
            }
            currentItemType = itemType === 'folder' ? 'folder' : 'file';
            var itemId = '';
            $fileIdInput.val('');
            $folderIdInput.val('');

            if (itemType === 'folder') {
                var folderId = $btn.data('nnaxfuf-folder-id');
                $folderIdInput.val(folderId);
                itemId = folderId;
                $actionInput.val('nnaxfuf_share_folder');
                $nonceInput.val(($shareForm.data('folder-share-nonce') || '').toString());
                if ($shareTitle.length) $shareTitle.text(t('share_title_folder', 'Share Folder'));
                $searchInput.attr('placeholder', t('search_placeholder_folder', 'Search person'));
            } else {
                var fileId = $btn.data('nnaxfuf-file-id');
                $fileIdInput.val(fileId);
                itemId = fileId;
                $actionInput.val('nnaxfuf_share_file');
                $nonceInput.val(($shareForm.data('file-share-nonce') || '').toString());
                if ($shareTitle.length) $shareTitle.text(t('share_title_file', 'Share'));
                $searchInput.attr('placeholder', t('search_placeholder_file', 'Search person'));
            }

            // Resolve placeholders for notification message
            var template = (window.nnaxFmAjax && window.nnaxFmAjax.default_notification_msg) ? window.nnaxFmAjax.default_notification_msg : '';
            if (template) {
                var resolved = template
                    .replace(/{item_title}/g, itemTitle)
                    .replace(/{owner_name}/g, (window.nnaxFmAjax && window.nnaxFmAjax.current_user_name) ? window.nnaxFmAjax.current_user_name : '')
                    .replace(/{site_url}/g, (window.nnaxFmAjax && window.nnaxFmAjax.site_url) ? window.nnaxFmAjax.site_url : '');
                $('#nnaxfuf_notification_msg').val(resolved);
            }

            loadExistingShares(itemId, itemType);
        });

        // Remove selected user from both visible list and hidden payload.
        $(document).on('click', '.nnaxfuf-remove-user', function () {
            var $li = $(this).closest('li');
            if (String($li.attr('data-locked') || '') === '1') {
                return;
            }
            var userId = $li.data('user-id');

            $hiddenContainer.find('input[name="nnaxfuf_share_user_ids[]"]').each(function () {
                if (String($(this).val()) === String(userId)) {
                    $(this).remove();
                }
            });

            $li.remove();
            renderEmptySelectionState();
        });

        // Debounced type-ahead user search:
        // - waits 250ms for calmer UX/server load
        // - aborts previous request to avoid race conditions/outdated results
        $searchInput.on('input', function () {
            var term = $(this).val().trim();
            clearTimeout(searchTimeout);

            if (term.length < 2) {
                if (userSearchRequest && typeof userSearchRequest.abort === 'function') {
                    userSearchRequest.abort();
                    userSearchRequest = null;
                }
                $resultsContainer.empty();
                return;
            }

            searchTimeout = setTimeout(function () {
                $resultsContainer.html('<p class="uk-text-muted uk-text-small nnaxfuf-user-search-loading"><span uk-spinner="ratio: 0.6"></span> <span class="uk-margin-small-left">' + t('search_loading', 'Searching for matching users...') + '</span></p>');

                if (userSearchRequest && typeof userSearchRequest.abort === 'function') {
                    userSearchRequest.abort();
                }

                userSearchRequest = $.ajax({
                    url: nnaxFmAjax.ajax_url,
                    method: 'POST',
                    dataType: 'json',
                    data: {
                        action: 'nnaxfuf_search_users',
                        term: term,
                        nonce: nnaxFmAjax.nonce
                    }
                }).done(function (response) {
                    $resultsContainer.empty();

                    if (!response || !response.success || !response.data || !response.data.length) {
                        $resultsContainer.html('<p class="uk-text-muted uk-text-small">' + t('search_no_results', 'No matching users found.') + '</p>');
                        return;
                    }

                    var $list = $('<ul>', { class: 'uk-list uk-list-divider uk-margin-small' });
                    response.data.forEach(function (user) {
                        var label = user.display_name;
                        var isOwnerResult = currentOwnerId > 0 && parseInt(user.id, 10) === currentOwnerId;
                        if (isOwnerResult) {
                            label += ' ' + t('owner_suffix', '(Owner)');
                        }

                        var $btn = $('<button>', {
                            type: 'button',
                            class: 'uk-button uk-button-text nnaxfuf-add-user-btn',
                            'data-user-id': user.id,
                            'data-display-name': user.display_name,
                            'data-user-login': user.user_login
                        }).text(label);

                        if (isOwnerResult) {
                            $btn.prop('disabled', true)
                                .addClass('uk-text-muted')
                                .attr('aria-disabled', 'true')
                                .attr('data-owner-user', '1');
                        }

                        $list.append($('<li>').append($btn));
                    });

                    $resultsContainer.append($list);
                }).fail(function (xhr, textStatus) {
                    // Ignore expected abort errors caused by rapid typing.
                    if (textStatus === 'abort') return;
                    $resultsContainer.html('<p class="uk-text-danger uk-text-small">' + t('search_failed', 'Search failed. Please try again.') + '</p>');
                }).always(function () {
                    userSearchRequest = null;
                });
            }, 250);
        });

        // Click on search result inserts user into the selected list.
        $(document).on('click', '.nnaxfuf-add-user-btn', function () {
            if ($(this).prop('disabled') || String($(this).attr('data-owner-user') || '') === '1') {
                return;
            }

            addUserToSelection({
                id: $(this).data('user-id'),
                display_name: $(this).data('display-name'),
                user_login: $(this).data('user-login'),
                is_role: $(this).data('is-role')
            }, {}, currentLayout);
        });

        // Load roles button
        $(document).on('click', '#nnaxfuf_load_roles_btn', function () {
            var $btn = $(this);
            $btn.attr('disabled', true);
            $resultsContainer.html('<p class="uk-text-muted uk-text-small"><span uk-spinner="ratio: 0.6"></span> ' + t('roles_loading', 'Loading shared roles...') + '</p>');

            $.ajax({
                url: nnaxFmAjax.ajax_url,
                method: 'POST',
                dataType: 'json',
                data: {
                    action: 'nnaxfuf_get_roles',
                    nonce: nnaxFmAjax.nonce
                }
            }).done(function (response) {
                $resultsContainer.empty();
                if (!response || !response.success || !response.data) {
                    $resultsContainer.html('<p class="uk-text-danger">' + t('roles_load_failed', 'Error while loading roles.') + '</p>');
                    return;
                }

                var $list = $('<ul>', { class: 'uk-list uk-list-divider uk-margin-small' });
                response.data.forEach(function (role) {
                    $list.append($('<li>').append($('<button>', {
                        type: 'button',
                        class: 'uk-button uk-button-text nnaxfuf-add-user-btn',
                        'data-user-id': role.id,
                        'data-display-name': role.display_name,
                        'data-is-role': true
                    }).text(role.display_name)));
                });
                $resultsContainer.append($list);
            }).fail(function () {
                $resultsContainer.html('<p class="uk-text-danger">' + t('network_error_roles', 'Network error while loading roles.') + '</p>');
            }).always(function () {
                $btn.attr('disabled', false);
            });
        });
        
        // Ensure simple reset on hide
        if (window.UIkit && UIkit.util) {
            UIkit.util.on($modal[0], 'hidden', function () {
                resetModal();
            });
        }
    });
})(window, window.jQuery);
