/*
 *  Copyright 2025 Anyware Services
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */

/**
 * This UI helper provides a dialog to choose a resource from project resources explorer. 
 * See #open method.
 */
Ext.define('Ametys.plugins.workspaces.project.helper.ChooseProjectResource', {
	singleton: true,
	
	/**
	 * @property {String} this._currentId The current selected resource. Can be null.
	 * @private
	 */
	/**
	 * @property {Ametys.window.DialogBox} _box The dialog box (containing the resource explorer tree).
	 * @private
	 */
	/**
	 * @property {Ametys.plugins.workspaces.project.resources.ProjectResourcesTree} _tree The resource explorer tree.
	 * @private
	 */
	/**
	 * @property {Function} _cbFn The call back function to call after a file has been chosen.
	 * @private
	 */
	
	/**
	 * Allow the user to choose a project resource file 
	 * @param {Object} config The configuration options :
	 * @param {String} [config.iconCls=ametysicon-file98] One or more CSS classes to apply to dialog's icon. Can be null to use the default one or use the icon instead.
	 * @param {String} [config.icon] The full path to icon (16x16) for the dialog box. If null the iconCls will be used
	 * @param {String} config.title The title of the dialog box.
	 * @param {String} [config.helpmessage] The message displayed at the top of the dialog box.
	 * @param {String} [config.value] The currently selected resource. can be null
	 * @param {Function} config.callback The method that will be called when the dialog box is closed. The method can return false to cancel the closing action (you might display an error message in this case). Callback parameters are : 
	 * @param {String} config.callback.id The id of the file
	 * @param {String} config.callback.filename: The name of the file
	 * @param {String} config.callback.size The size in byte of the file
	 * @param {String} config.callback.viewHref The url to VIEW the file
	 * @param {String} config.callback.downloadHref The url to DOWNLOAD the file
	 * @param {Function} [config.filter] A node filter. Choose one in {@link Ametys.explorer.tree.ExplorerTree}. (One argument, the tree node and reply true or false)
	 */
	open: function(config)
	{
		this._cbFn = config.callback || Ext.emptyFn;
		this._currentId = config.value || null;
		this._delayedInitialize(config.icon, config.iconCls, config.title, config.helpmessage);
		
		this._box.show();
	},
	
	/**
	 * Creates the dialog box. The box is destroyed on close action
	 * @param {String} icon The full path to icon (16x16 pixels) for the dialog box. Can be null to use CSS for icon
     * @param {String} iconCls One or more CSS classes to apply to dialog's icon. Can be null to use the default one or use the icon instead.
	 * @param {String} title The title of the dialog box.
	 * @param {String} helpmessage The message displayed at the top of the dialog box.
	 * @private
	 */
	_delayedInitialize: function(icon, iconCls, title, helpmessage)
	{
		this._tree = Ext.create('Ametys.plugins.workspaces.project.resources.ProjectResourcesTree', {
            flex: 1,
			itemId: 'project-resources-tree',
			inlineEditionEnable: false,
            allowDragAndDrop: false,
			border: true,
			listeners: {
				selectionchange: {fn: this._onSelectionChange, scope: this}
			}
		});
		
		this._box = Ext.create('Ametys.window.DialogBox', {
			title: title,
            icon: icon,
			iconCls: icon ? null : (iconCls || 'ametysicon-world-earth-communicating'),
			
			width: 410,
            height: 500,
            scrollable: false,
            
            bodyStyle: {
            	padding: 0
            },
            cls: 'ametys-dialogbox choose-resource-dialog',
            
            layout: {
                type: 'vbox',
                align : 'stretch',
                pack  : 'start'
            },
                
			items: [{
					xtype: 'component',
					cls: 'a-text',
					html: helpmessage || "{{i18n PLUGINS_WORKSPACES_CHOOSE_PROJECT_RESOURCE_HINT}}"
				}, 
				this._tree
			],
			
			closeAction: 'destroy',
			
			referenceHolder: true,
			defaultButton: 'validate',
			
			buttons : [{
				reference: 'validate',
				text: "{{i18n plugin.cms:PLUGINS_CMS_HELPER_CHOOSERESOURCESFILES_OKBUTTON}}",
				disabled: true,
				handler: Ext.bind(this._ok, this)
			}, {
				text: "{{i18n plugin.cms:PLUGINS_CMS_HELPER_CHOOSERESOURCESFILES_CANCELBUTTON}}",
				handler: Ext.bind(function() {this._box.close();}, this) // hide
			}],
			
			listeners: {
                show: {fn: this._init, scope: this},
                close: {fn: this._close, scope: this}//for callback on close
			}
		});
	},

    /**
     * @private
     * When dialog is closed
     */
    _close: function()
    {
        this._cbFn(null);
    },

	/**
	 * Initialize the project resources tree.
	 * @param {String} projectName name of current project, can be null
	 * @private
	 */
	_init: function (projectName)
	{
		this._refreshMask = Ext.create("Ext.LoadMask", {msg: "{{i18n plugin.core-ui:PLUGINS_CORE_UI_MSG_TOOLS_REFRESHING}}", target: this._tree});
		this._refreshMask.show();
				
		var me = this;
		if (this._currentId)
		{
			Ametys.data.ServerComm.callMethod({
    			role: "org.ametys.plugins.workspaces.documents.WorkspaceExplorerResourceDAO",
    			methodName: "getResourceProject",
    			parameters: [this._currentId],
    			callback: {
    				scope: this,
    				handler: function(result)
					{
						if (result.resourceNotFound)
						{
							this._currentId = null;
						}
						me._tree.initialize(Ext.bind(me._initCb, me, [result], 1), result.project);
					}
    			},
    			errorMessage: {
    				category: this.self.getName(),
    				msg: "{{i18n PLUGINS_WORKSPACES_CHOOSE_PROJECT_RESOURCE_ERROR}}"
    			}
    		});
		}
		else
		{
			this._tree.initialize(Ext.bind(this._initCb, this));
		}
	},
	
	/**
	 * @private
	 * Hide refresh mask and select resource in tree
	 */
	_initCb: function (tree, result)
	{
		if (tree)
		{	
			this._tree.getRootNode().expandChildren();
					
			if (this._currentId)
			{
				// Select and focus selected resource
			    var me = this;
				Ametys.explorer.ExplorerNodeDAO.getExplorerNode(this._currentId, function(resource) {
					if (resource)
					{
						me._tree.selectByPath(resource.getPath(), true);
						
			        }
				});
			}
			else
			{
				// Select and focus root node in tree
				var firstChild = this._tree.getRootNode().firstChild;
				if (firstChild)
				{
					this._tree.getSelectionModel().select(firstChild);
					this._tree.getView().focusNode(firstChild);
				}
			}
		}
		
		this._refreshMask.hide();
        Ext.destroy(this._refreshMask);
        this._refreshMask = null;
        
        if (result && result.resourceNotFound)
		{
	        Ametys.log.ErrorDialog.display({
				title: "{{i18n PLUGINS_WORKSPACES_DAOS_EXPLORER_NODE_NOT_FOUND}}", 
				text: "{{i18n PLUGINS_WORKSPACES_DAOS_EXPLORER_NODE_NOT_FOUND_HINT}}",
				details: result.resourceNotFound,
				category: Ext.getClassName(this)
			});
		}
	},
	
	/**
	 * @private
	 * 'ok' button click handler.
	 * Calls the callback function passed in {@link #method-open} and hide the dialog box.
	 */
	_ok: function()
	{
		var node = this._tree.getSelectionModel().getSelection()[0];
		
		var id = node.getId();
		var text = node.get('text');
		
		var size, viewHref, downloadHref;
		if (node.get('type') == Ametys.explorer.tree.ExplorerTree.RESOURCE_TYPE)
		{
		    size = node.get('size');
		    viewHref = Ametys.explorer.tree.ExplorerTree.getViewHref(id); 
		    downloadHref = Ametys.explorer.tree.ExplorerTree.getDownloadHref(id);
		}
		
        if (this._cbFn(id, text, size, viewHref, downloadHref, null) !== false)
        {
            this._box.hide();
        }
	},
	
	/**
	 * @private
	 * Listener on selection change in the tree.
	 */
	_onSelectionChange: function(sm, nodes)
	{
		var node = nodes[0],
		    okBtn = this._box.getDockedItems('toolbar[dock="bottom"] button')[0];
		
		if (node == null || node.isRoot())
	    {
		    okBtn.setDisabled(true);
	    }
		else
	    {
		    var type = node.get('type');
            okBtn.setDisabled(type != Ametys.explorer.tree.ExplorerTree.RESOURCE_TYPE);
	    }
	}
});