llmApp.directive('bsFileUpload', ['$q', '$timeout', 'customFileUploaderService','PLUGIN_PATHS',
    function ($q, $timeout, fileService,PLUGIN_PATHS) {
        return {
            restrict: 'E',
            scope: {
                config: '=',
                configProperty: '@',
                labelText: '@',
                buttonText: '@',
                acceptedMimeTypes: '@',
                uploadTargetType: '@',
                uploadTargetPath: '@',
                showPreview: '@',
                onUploadComplete: '&?',
                uploadType: '@',
                expectedFileName: '@',
                description: '@'
            },
            templateUrl: PLUGIN_PATHS.WEBAPP +'bs-file-upload.html',
            link: function (scope, element, attrs) {
                // --- 1. State Management ---
                scope.isDragOver = false;
                scope.isUploading = false;
                scope.uploadSuccess = null;
                scope.clientErrorMessage = null;
                scope.uploadStatusMessage = null;
                scope.uploadedFiles = [];
                scope.fileName = null;
                scope.previewSrc = fileService.getDefaultIconUrl();
                scope.shouldShowPreview = scope.showPreview !== 'false';
                scope.uploadType = scope.uploadType || 'file';
                scope.config[scope.configProperty] = scope.config[scope.configProperty] || '';
                scope.showDeleteTooltip = false;



                const fileInputElement = element.find('input[type="file"]')[0];
                fileInputElement.multiple = scope.uploadType === 'multiple-files' || scope.uploadType === 'folder';

                // Flag to prevent redundant watches/initializations
                let isInitialized = false;

                // --- 2. Core Logic Functions ---

                /**
                 * Ensures a theme name exists on the config object, creating one if necessary.
                 * @returns {string|null} The theme name, or null if config is not ready.
                 */
                function getThemeName() {
                    scope.config = scope.config || {};
                    if (!scope.config.custom_theme_name) {
                        scope.config.custom_theme_name = "Default customization";
                    }
                    return scope.config.custom_theme_name;
                }

                /**
                 * Updates the visuals (preview image, file list) based on the current config.
                 */
                /**
                 * Fetches the actual file list from the server for the current theme,
                 * finds the specific file corresponding to this component's configProperty,
                 * and then updates the component's state (including the config model) to match reality.
                 * This fixes bugs when switching between themes with different file extensions for the same base name.
                 */

                function refreshComponentState(shouldClearMessages = false) {
                    // Reset UI to a clean, loading state immediately.
                    scope.fileName = null;
                    scope.previewSrc = fileService.getDefaultIconUrl();
                    scope.uploadedFiles = [];

                    if (shouldClearMessages) {
                        clearMessages();
                    }

                    if (!scope.config) return;

                    const themeName = getThemeName();

                    if (!themeName) {
                        scope.config[scope.configProperty] = null;
                        return;
                    }

                    if(themeName === 'Default customization') {
                        if(scope.shouldShowPreview) {
                            let file = {}
                            if(scope.configProperty == "custom_logo_file_name") {
                                file = {
                                    "name": "custom_logo_file_name.png",
                                }
                                scope.previewSrc = `${window.location.origin}/plugins/agent-hub/resource/custom-ui-settings/images/custom_logo_file_name.png`;
                            } else {
                                file = {
                                    "name": "custom_icon_file_name.png",
                                }
                                scope.previewSrc = `${window.location.origin}/plugins/agent-hub/resource/custom-ui-settings/images/custom_icon_file_name.png`;
                            }

                            scope.uploadedFiles = [file];
                            return;
                        }
                    }

                    fileService.fetchUploadedFiles(scope.uploadTargetType)
                        .then(response => {
                            // Step 1: Get a clean, flat list of all files for the current theme.
                            const allFilesForTheme = fileService.getAllFilesForTheme(response.data, themeName);

                            // Step 2: From that list, find the *single specific file* this directive cares about.
                            let foundFile = null;

                            if (scope.expectedFileName) {
                                // Use case 1: The directive expects a file with an exact name (e.g., "fonts.css").
                                foundFile = allFilesForTheme.find(file => file.name === scope.expectedFileName);
                            } else {
                                // Use case 2: The directive looks for a file with the exact filename stored in config
                                const storedFileName = scope.config[scope.configProperty];
                                if (storedFileName) {
                                    foundFile = allFilesForTheme.find(file => file.name === storedFileName);
                                }
                            }

                            // Step 3: Update the entire component state based on whether the file was found.
                            if (foundFile) {
                                // A matching file was found. Update the model and UI.
                                const finalFileName = foundFile.name;
                                scope.config[scope.configProperty] = finalFileName;
                                scope.fileName = finalFileName;

                                if (scope.shouldShowPreview && fileService.isImageFileByName(finalFileName)) {
                                    scope.previewSrc = `${window.location.origin}/local/static/answers/${themeName}/images/${finalFileName}?v=${new Date().getTime()}`;
                                }

                                // The uploadedFiles list should contain ONLY the file this directive manages.
                                scope.uploadedFiles = [foundFile];

                            } else {
                                // No matching file was found. Ensure the state is clean.
                                //scope.config[scope.configProperty] = null;
                                scope.fileName = null;
                                scope.previewSrc = fileService.getDefaultIconUrl();
                                scope.uploadedFiles = [];
                            }
                        })
                        .catch(error => {

                            scope.config[scope.configProperty] = null;
                            scope.fileName = null;
                            scope.previewSrc = fileService.getDefaultIconUrl();
                            scope.uploadedFiles = [];
                        });
                }


                // ...(Other helpers like validateFiles, performUpload, etc. remain the same as the previous refactor)...
                function validateFiles(files) {
                    // We should check first if a Theme Folder is selected

                    const filesArray = Array.from(files);
                    const defaultAllowedFiles = fileService.getDefaultAllowedFiles();
                    const result = {validFiles: [], errors: [], previewFile: null};

                    filesArray.forEach(file => {
                        const {name: fileName, type: fileType} = file;
                        const lowerCaseFileName = fileName.toLowerCase();
                        let fileConfig = fileService.isImageFile(file) ? defaultAllowedFiles['image'] : defaultAllowedFiles[lowerCaseFileName];

                        if (scope.acceptedMimeTypes?.includes('image/') && !fileService.isImageFile(file)) {
                            result.errors.push("Unsupported file type. Please upload a file in .png, .jpg, or .jpeg format.");
                            return;
                        }
                        if (scope.expectedFileName && scope.expectedFileName !== fileName) {
                            result.errors.push(`Invalid file.Please upload a file named ${scope.expectedFileName} in .css format.`);
                            return;
                        }

                        if (fileService.isImageFile(file) && !fileService.isAcceptedImageType(fileType)) {
                            result.errors.push(`Invalid image type: ${fileType}. Only JPG, JPEG and PNG are supported.`);
                            return;
                        }

                        if (!fileConfig) {
                            result.errors.push(`Invalid file name: ${fileName}.`);
                            return;
                        }



                        result.validFiles.push({file, folder: fileConfig.folder || ''});
                        if (scope.uploadType !== 'multiple-files' && scope.shouldShowPreview && fileService.isImageFile(file) && !result.previewFile) {
                            result.previewFile = file;
                        }
                    });

                    return result;
                }

                function performUpload(validFiles, themeName) {
                    if (validFiles.length === 0) {
                        scope.isUploading = false;
                        updateUploadStatus('No valid files to upload.');
                        return;
                    }

                    // Determine the filename that will be saved to the config *after* a successful upload.
                    const primaryFile = validFiles[0].file;
                    let fileNameToRegister;

                    if (scope.expectedFileName) {
                        // SCENARIO 1: A specific filename is expected (e.g., 'font.css').
                        // We use that name directly. The validation step already confirmed the user provided the correct file.
                        fileNameToRegister = scope.expectedFileName;
                    } else {
                        // SCENARIO 2: No specific name is expected (e.g., an image upload).
                        // We generate a new filename based on the configProperty and the original file's extension.
                        /* const originalName = primaryFile.name;
                        const extension = originalName.slice((originalName.lastIndexOf(".") - 1 >>> 0) + 2);
                        fileNameToRegister = `${scope.configProperty}.${extension}`;*/

                        // Always use PNG for specific config properties
                        fileNameToRegister = primaryFile.name;


                    }
                    updateUploadStatus('Ensuring folder structure exists...');

                    // Step 1: Generate folder name and create folder if theme is DEFAULT
                    let folderCreationPromise;
                    const newFolderName = fileService.generateAppFilename();
                    updateUploadStatus('Creating new folder...');

                    folderCreationPromise = fileService.createFolder('LOCAL_STATIC', newFolderName, '')
                        .then(() => {
                            scope.config.custom_theme_name = newFolderName; // Update config
                            scope.$emit('folderCreated'); // Notify folderSelector to refresh
                            return newFolderName;
                        })
                        .catch(error => {
                            if (error.data?.detailedMessage?.includes('already exists')) {
                                scope.$emit('folderCreated'); // Notify folderSelector to refresh
                                return newFolderName;
                            } else {
                                throw error;
                            }
                        });

                    folderCreationPromise
                        .then(actualThemeName => {
                            // Update config with the actual theme name
                            scope.config.custom_theme_name = actualThemeName;
                            // Step 2: Ensure the main theme folder and subfolders exist
                            return fileService.ensureThemeFolderExists(scope.uploadTargetType, actualThemeName, 'answers')
                                .then(themePath => {
                                    const uniqueFolders = [...new Set(validFiles.map(vf => vf.folder).filter(Boolean))];
                                    const folderPromises = uniqueFolders.map(folder => fileService.ensureSubFolderExists(scope.uploadTargetType, themePath, folder));
                                    return $q.all(folderPromises).then(() => themePath);
                                });

                        }).then(themePath => {
                        updateUploadStatus(`Uploading ${validFiles.length} file(s)...`);

                        const uploadPromises = validFiles.map(({file, folder}, index) => {
                            let fileForUpload = file; // Default to the original file object.

                            // Only rename the primary file (index === 0) AND only if no `expectedFileName` was provided.
                            if (index === 0 && !scope.expectedFileName) {
                                // Use the standardized name we determined earlier.
                                fileForUpload = new File([file], fileNameToRegister, {type: file.type});
                            }

                            const targetPath = folder ? `${themePath}/${folder}` : themePath;
                            return fileService.uploadFile(scope.uploadTargetType, targetPath, fileForUpload);
                        });

                        return $q.all(uploadPromises);
                    })
                        .then(results => {
                            scope.uploadSuccess = true;
                            updateUploadStatus('Upload successful!');
                            // This reliably uses the name we determined at the start of the function.
                            scope.config[scope.configProperty] = fileNameToRegister;

                            refreshComponentState();

                            //Notify image selector to refresh
                            scope.$emit('imageUploaded', {
                                configProperty: scope.configProperty,
                                fileName: fileNameToRegister,
                                themeName: getThemeName()
                            });

                            if (scope.onUploadComplete) scope.onUploadComplete({success: true, results});

                            hideMessageAfterDelay();
                        })
                        .catch(error => {
                            scope.uploadSuccess = false;
                            updateUploadStatus(`Upload failed: ${error.data?.detailedMessage || error.message || 'Unknown error'}`);
                            if (scope.onUploadComplete) scope.onUploadComplete({success: false, error});
                        })
                        .finally(() => {
                            scope.isUploading = false;
                        });
                }


                // --- 3. Scope Functions (for Template Binding) ---

                scope.triggerFileInput = function () {
                    if (!scope.isUploading) fileInputElement.click();
                };
                scope.handleFileSelect = function (files) {
                    if (!files || !files.length || scope.isUploading) return;
                    scope.isUploading = true;
                    scope.clientErrorMessage = null;
                    updateUploadStatus('Validating files...');
                    const {validFiles, errors, previewFile} = validateFiles(files);
                    if (errors.length > 0) {
                        $timeout(() => {
                            scope.isUploading = false;
                            scope.clientErrorMessage = errors.join('; ');
                            $timeout(() => {
                                scope.uploadStatusMessage = "";
                            }, 0);
                        }, 0);

                        return;
                    }
                    if (previewFile) {
                        const reader = new FileReader();
                        reader.onload = (e) => scope.$applyAsync(() => scope.previewSrc = e.target.result);
                        reader.readAsDataURL(previewFile);
                    }
                    performUpload(validFiles, getThemeName());
                    fileInputElement.value = null;
                };
                scope.removeFile = function (fileNameToRemove) {
                    const file = scope.uploadedFiles.find(f => f.name === fileNameToRemove);
                    if (!file || !confirm(`Are you sure you want to delete "${fileNameToRemove}"?`)) return;

                    scope.isUploading = true;
                    updateUploadStatus(`Deleting ${fileNameToRemove}...`);

                    fileService.deleteFile(scope.uploadTargetType, file.path)
                        .then(() => {
                            scope.uploadSuccess = true;
                            updateUploadStatus(`"${fileNameToRemove}" deleted.`);
                            refreshComponentState();
                            // Notify image selector to refresh after deletion
                            scope.$emit('imageDeleted', {
                                configProperty: scope.configProperty,
                                fileName: fileNameToRemove,
                                themeName: getThemeName()
                            });

                            if (scope.onUploadComplete) scope.onUploadComplete({
                                success: true,
                                deletedFileName: fileNameToRemove
                            });
                            hideMessageAfterDelay();
                        })
                        .catch(error => {
                            scope.uploadSuccess = false;
                            updateUploadStatus(`Error deleting file: ${error.message || 'Unknown error'}`);
                        })
                        .finally(() => {
                            scope.isUploading = false;
                        });
                };


                // --- 4. Event Handlers & One-Time Setup ---

                function setupDragAndDrop() {
                    const dropArea = element.find('.drag-drop-area');
                    dropArea.on('dragover dragenter', (e) => {
                        e.preventDefault();
                        if (!scope.isDragOver) scope.$apply(() => scope.isDragOver = true);
                    });
                    dropArea.on('dragleave drop', (e) => {
                        e.preventDefault();
                        if (scope.isDragOver) scope.$apply(() => scope.isDragOver = false);
                    });
                    dropArea.on('drop', (e) => scope.handleFileSelect(e.originalEvent.dataTransfer.files));
                    element.on('$destroy', () => dropArea.off('dragover dragenter dragleave drop'));
                }

                function clearMessages() {
                    $timeout(() => {
                        scope.clientErrorMessage = null;
                        scope.uploadStatusMessage = null;
                        scope.uploadSuccess = null;
                    }, 0);
                }

                scope.clearMessages = clearMessages;


                // --- 5. Initialization & Watcher ---

                /**
                 * The main watcher. Deeply watches the `config` object.
                 * This correctly handles both the initial load AND any subsequent
                 * changes to the component's context (e.g., in an ng-repeat).
                 */
                scope.$watch('config.custom_theme_name', function (newThemeName, oldThemeName) {
                    if (newThemeName !== oldThemeName) {

                        // Then, proceed to refresh the component's UI as usual.
                        refreshComponentState(true);
                    }
                });


                // Initial setup, runs only once.
                function initializeComponent() {
                    if (isInitialized) return;
                    setupDragAndDrop();
                    refreshComponentState(); // Initial load
                    isInitialized = true;
                }

                initializeComponent();

                function updateUploadStatus(message) {
                    $timeout(() => {
                        scope.uploadStatusMessage = message;
                    }, 0);


                }

                function hideMessageAfterDelay() {
                    $timeout(() => {
                        scope.uploadStatusMessage = null;
                        scope.uploadSuccess = null;
                    }, 5000);
                }

                // Add to the link function in the customFileUploader directive
                scope.$on('imageSelectedFromSelector', function(event, data) {
                    if (data.configProperty === scope.configProperty) {
                        // An image was selected from the image selector for this uploader

                        // Refresh the component state to show the newly selected image
                        $timeout(function() {
                            refreshComponentState(true);
                        }, 100);
                    }
                });
            }
        };
    }]);