llmApp.directive('datasetSelector', ['PythonService', 'SharedPromiseService','PLUGIN_PATHS', function (PythonService, SharedPromiseService,PLUGIN_PATHS) {
    return {
        restrict: 'E',
        templateUrl: PLUGIN_PATHS.WEBAPP +'bs-dataset-select-template.html',
        scope: {
            config: '=', formName: '=', labelText: '@', fieldRequired: '=', configProperty: '@', context: '@'
        },
        controller: ['$scope', '$timeout', '$element', function ($scope, $timeout, $element) {
            // Add to controller variables
            $scope.isDropdownHovered = false;
            $scope.isDatasetDropdownOpen = false;
            $scope.datasetFilter = ''; // This is now the main model for the input field
            $scope.datasets = [];
            $scope.datasetsByType = {};
            $scope.selectedDataset = null;
            //Flag to control when filtering is applied (starts false to show all on open)
            $scope.filterActive = false;
            var blurTimeout = null; // For managing blur event

            // --- Use a new event name triggered by the Parent ---
            var dataRefreshNeededListener = $scope.$on('dataNeedsRefresh', function (event, payload) {

                // This listener should react to the signal and refresh its data.

                SharedPromiseService.refreshData('datasets_names')
                    .then(function (updatedData) {

                        $scope.initDatasetData();
                    })
                    .catch(function (error) {

                    });
            });

            // --- Clean up the listener when the scope is destroyed ---
            $scope.$on('$destroy', function () {

                dataRefreshNeededListener(); // Call the deregistration function
            });
            // --- End of new listener logic ---

            $scope.initDatasetData = function () {

                SharedPromiseService.getData('datasets_names').then(function (data) {
                        if (data && data.choices) {
                            $scope.datasetsByType = {};
                            $scope.datasets = [];
                            Object.keys(data.choices).forEach(function (datasetType) {
                                $scope.datasetsByType[datasetType] = [];
                                data.choices[datasetType].forEach(function (datasetName) {
                                    var dataset = {
                                        id: datasetName, // Assuming name is unique enough for an ID here
                                        datasetName: datasetName,
                                        datasetDisplayName: datasetName,
                                        datasetType: datasetType,
                                        isHovered: false
                                    };
                                    $scope.datasets.push(dataset);
                                    $scope.datasetsByType[datasetType].push(dataset);
                                });
                            });

                            // Logic for pre-selecting dataset based on config
                            if ($scope.config[$scope.configProperty]) {
                                var datasetName = $scope.config[$scope.configProperty];
                                var foundDataset = $scope.datasets.find(function (d) {
                                    return d.datasetName === datasetName;
                                });
                                if (foundDataset) {
                                    $scope.selectedDataset = foundDataset;
                                    $scope.datasetFilter = foundDataset.datasetDisplayName; // Set input text
                                } else {
                                    // If the configured dataset is no longer available, clear selection and config
                                    $scope.config[$scope.configProperty] = null;
                                    $scope.selectedDataset = null;
                                    $scope.datasetFilter = ''; // Clear input text
                                }
                            }
                        } else {

                            $scope.datasets = [];
                            $scope.datasetsByType = {};
                        }
                    }, function (error) {

                        $scope.datasets = [];
                        $scope.datasetsByType = {};
                    }
                );
            };

            var documentClickHandler = function (event) {
                // Check if the click was outside the current directive's element
                if ($scope.isDatasetDropdownOpen && !$element[0].contains(event.target)) {
                    $scope.$apply(function () {
                        $scope.closeDropdownAndRevertText();
                    });
                }
            };

            $scope.closeDropdownAndRevertText = function () {
                $scope.isDatasetDropdownOpen = false;
                angular.element(document).off('click', documentClickHandler);
                if ($scope.selectedDataset) {
                    $scope.datasetFilter = $scope.selectedDataset.datasetDisplayName;
                }
                //Reset filterActive on close
                $scope.filterActive = false;
            };

            // Accepts a flag to clear the filter
            $scope.openDatasetDropdown = function (clearFilterOnOpen) {
                if (blurTimeout) $timeout.cancel(blurTimeout);

                if ($scope.isDatasetDropdownOpen) {
                    // Close the dropdown and revert the input text
                    $scope.closeDropdownAndRevertText();
                } else {
                    // Open the dropdown and clear the filter if required
                    if (clearFilterOnOpen) {
                        $scope.datasetFilter = '';
                    }
                    $scope.isDatasetDropdownOpen = true;
                    //Disable filtering initially (show all, even if datasetFilter has text)
                    $scope.filterActive = false;
                    $timeout(function () {
                        angular.element(document).on('click', documentClickHandler);
                    }, 0);
                }
            };

            $scope.selectDataset = function (dataset) {
                if (blurTimeout) $timeout.cancel(blurTimeout);

                $scope.selectedDataset = dataset;
                $scope.config[$scope.configProperty] = dataset.datasetName;
                $scope.datasetFilter = dataset.datasetDisplayName; // Update input field text
                $scope.isDatasetDropdownOpen = false; // Close dropdown after selection
                angular.element(document).off('click', documentClickHandler);
            };

            $scope.clearSelection = function () {
                $scope.datasetFilter = '';
                $scope.selectedDataset = null;
                $scope.config[$scope.configProperty] = null;
                // Optionally, re-open dropdown or focus input
                $scope.openDatasetDropdown();
                $element[0].querySelector('input').focus();
            };

            $scope.handleInputChange = function () {
                // If text in the input changes and doesn't match the currently selected dataset,
                // it means the user is either typing a new filter or has changed the selected one.
                // Deselect if the input text no longer matches the selected dataset's display name.
                if ($scope.selectedDataset && $scope.datasetFilter !== $scope.selectedDataset.datasetDisplayName) {
                    $scope.selectedDataset = null;
                    $scope.config[$scope.configProperty] = null;
                }

                //Activate filtering now that the user is typing
                $scope.filterActive = true;

                // Automatically open dropdown if not already open and user is typing (and there's text)
                // This ensures that as soon as a filter is typed, the dropdown appears.
                if (!$scope.isDatasetDropdownOpen && $scope.datasetFilter) {
                    // If clearing filter was intended (e.g., by arrow click), datasetFilter is '', so this block isn't entered.
                    // If user types something, this will open the dropdown.
                    $scope.openDatasetDropdown(false); // Don't clear filter, just open
                }
                // If datasetFilter becomes empty, and dropdown is open, handleInputChange is called.
                // $scope.isDatasetDropdownOpen will remain true until closed.
            };

            $scope.handleInputBlur = function () {
                // Use a short timeout to allow click events on dropdown items to process before closing.
                // This handler is called when the input loses focus (e.g., tabbing away or clicking outside).
                blurTimeout = $timeout(function () {
                    // The documentClickHandler should have already handled closing if click was outside.
                    // This logic is mainly for when the input loses focus without an external click
                    // (e.g., tabbing to the next element).
                    // If dropdown is still open, we close it and revert/commit the filter text.
                    if ($scope.isDatasetDropdownOpen) {
                        $scope.closeDropdownAndRevertText();
                    }
                }, 200); // ~200ms delay
            };

            //Handle input focus logic (open only if not already open)
            $scope.handleInputFocus = function () {
                if (!$scope.isDatasetDropdownOpen) {
                    $scope.openDatasetDropdown(false);
                }
            };

            //Filtering logic (use filterActive flag; simplified empty check)
            $scope.datasetMatchesFilter = function (dataset) {
                //If filter not active, show all
                if (!$scope.filterActive) return true;

                // Perform case-insensitive search on display name and type
                const filter = $scope.datasetFilter.toLowerCase();
                return dataset.datasetDisplayName.toLowerCase().includes(filter) || dataset.datasetType.toLowerCase().includes(filter);
            };

            $scope.typeHasMatchingDatasets = function (type) {
                if (!$scope.datasetsByType[type]) return false;
                return $scope.datasetsByType[type].some(d => $scope.datasetMatchesFilter(d));
            };

            $scope.hasMatchingDatasets = function () {
                if ($scope.datasets.length === 0) return false;
                // If no filter text, and datasets exist, then there are matching datasets (all of them).
                if (!$scope.datasetFilter) return true;
                // Otherwise, check if any dataset matches the current filter.
                return $scope.datasets.some(d => $scope.datasetMatchesFilter(d));
            };

            // Initial data load
            $scope.initDatasetData();
        }]
    };
}]);