/*
 *  Copyright 2024 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 tool is a tool to run solr queries
 */
Ext.define('Ametys.plugins.cms.solrtool.SolrQueryTool', {
    extend: 'Ametys.tool.Tool',
    
    /**
     * @private
     * @property {Ametys.form.field.SolrCode} scriptEditor The codemirror editor for Solr
     */
    
    /**
     * @private
     * @property {Ext.Component} results The panel containing the results
     */
    
    defaultSolrCore: 'default',
    
    createPanel: function()
    {
        this.queryEditor = Ext.create('Ametys.form.field.Code', {
            mode: {name: "javascript", jsonld: true},
            stateful: true,
            stateId: this.getId() + "$code",
            
            cmParams: {
                foldcode: true,
                foldGutter: true,
                lineWrapping:true,
                gutters: ["CodeMirror-linenumbers", "CodeMirror-foldgutter"]
            }
        })
        
        this.leftPanel = Ext.create("Ext.panel.Panel", {
            stateful: true,
            stateId: this.getId() + "$leftPanel",
            layout: 'fit',
            split: true,
            minWidth:100,
            flex:0.5,
            items: [ this.queryEditor ],
            dockedItems: this._createTopToolBar()
        })
        
        this.results = Ext.create("Ext.Component", {
            stateId: this.self.getName() + "$results",
            stateful: true,
            scrollable: true,
            html: "{{i18n PLUGINS_CMS_SOLR_QUERY_TOOL_RESULT_DEFAULT_LABEL}}",
            minWidth:100,
            flex:0.5,
            split: true
        })
        
        return Ext.create("Ext.container.Container", {
            stateful: true,
            stateId: this.self.getName() + "$container",
            layout: { 
                type: 'hbox',
                align: 'stretch'
            },
            cls: 'uitool-solr-query',
            items: [ this.leftPanel, this.results ]
        })
    },
    
    /**
     * @protected
     * Get the top panel for choosing solr code and actions
     * @return {Ext.toolbar.Toolbar} the top toolbar
     */
    _createTopToolBar: function ()
    {
        return Ext.create({
            dock: 'top',
            xtype: 'toolbar',
            layout: {
                type: 'hbox',
                align: 'stretch'
            },
            cls: 'top',
            items: [
                this._getSolrCoresComboBox(),
                {
                    xtype: 'tbspacer',
                    flex: 0.0001
                },
                {
                    // Format
                    xtype: 'button',
                    iconCls: 'ametysicon-code-misc-lang-script',
                    tooltip: "{{i18n PLUGINS_CMS_SOLR_QUERY_TOOL_PRETTIFY_LABEL}}",
                    handler: this._formatCode,
                    scope: this,
                    cls: 'a-btn-light',
                }
            ]
        });
    },
    
    /**
     * @private
     * Get configuration for sorl cores combo box
     * @return {Object} the configuration object
     */
    _getSolrCoresComboBox: function ()
    {
        this._coreStore = Ext.create('Ext.data.Store', {
            proxy: {
                type: 'ametys',
                role: 'org.ametys.cms.solr.SolrQueryHandler',
                methodName: 'getSolrCoreNames',
                methodArguments: [],
            },
            
            fields: ['name'],
            
            autoLoad: true,
            
            listeners: {
                load: {fn: this._onLoadCores, scope: this},
            }
        });
        
        this.solrCoreCombo =  Ext.create("Ext.form.ComboBox", {
            xtype: 'combobox',
            itemId: 'cores-combo',
            
            cls: 'ametys',
                        
            forceSelection: true,
            editable: false,
            queryMode: 'local',
            allowBlank:false,
            
            store: this._coreStore,

            hidden:false,
            valueField: 'name',
            displayField: 'name',
            labelSeparator: '',
            fieldLabel: "{{i18n PLUGINS_CMS_SOLR_QUERY_TOOL_SOLR_CORE_LABEL}}",
            
            maxWidth: 200,
            labelWidth:40,
            labelAlign: "left",
            
            flex:1
        })
        
        return this.solrCoreCombo
    },
    
    /**
     * Listener called after load form display core combo box
     * @param {Object} store The store
     * @param {Object[]} data The data
     * @private
     */
    _onLoadCores: function(store, data)
    {
        this.solrCoreCombo.setValue(this.defaultSolrCore);
    },
    
    /**
     * Get the name of current solr core
     * @return {String} the current solr core's name
     */
    getCurrentSolrCoreName: function ()
    {
        return this.solrCoreCombo.getValue();
    },
    
    getMBSelectionInteraction: function() 
    {
        return Ametys.tool.Tool.MB_TYPE_NOSELECTION;
    },
    
    getType: function()
    {
        return Ametys.tool.Tool.SOLR_QUERY;  
    },
    
    /**
     * Handles the response
     * @param {String} result The result of the Solr Query.
     */
    updateResult: function(result)
    {
        var id = Ext.id();
        var html = "<div id='" + id + "'>";
        
        if (!Ext.isEmpty(result.result))
        {
            html += Ext.JSON.prettyEncode( Ext.JSON.decode(result.result || null)); // Encode/decode to ensure the json object reflect the sent one (e.g. eliminate "undefined" values)
        }
        if (Ext.isEmpty(result.result) && Ext.isEmpty(result.errorMessage))
        {
            html += "<div class='no-result'>{{i18n plugin.core-ui:PLUGINS_CORE_UI_TOOLS_SCRIPT_RESULTS_NO_RESULT}}</div>";
        }
        if (!Ext.isEmpty(result.errorMessage))
        {
            html += '<div class="fatalerror">' + result.errorMessage;
            
            if (!Ext.isEmpty(result.errorStackTrace))
            {
                html += "<br/><a href='javascript:void(0)' onclick='this.nextSibling.style.display = (this.nextSibling.style.display == \"none\" ? \"\" : \"none\")'>{{i18n plugin.core-ui:PLUGINS_CORE_UI_TOOLS_SCRIPT_ERROR_DETAILS}}</a>"
                     + "<div class='stacktrace' style='display: none'>" + Ext.String.stacktraceJavaToHTML(result.errorStackTrace) + "</div>"
            }
            
            html += '</div>';
        }
        html += '</div>';
        
        this.results.update(html);
    },
    
    /**
     * @private
     * Format the code in the editor
     */
    _formatCode: function ()
    {
        if (this.queryEditor.getValue())
        {
            try
            {
                var resultAsPrettyJson = this._formatJsonCode();
                
                this.queryEditor.setValue(resultAsPrettyJson);
            }
            catch (e)
            {
                Ametys.log.ErrorDialog.display({
                    title: "{{i18n PLUGINS_CMS_SOLR_QUERY_TOOL_PRETTIFY_ERROR_LABEL}}",
                    text: "{{i18n PLUGINS_CMS_SOLR_QUERY_TOOL_PRETTIFY_ERROR_DESC}} : <br/>" + e.message,
                    category: this.self.getName()
                });
            }
        }
    },
    
    /**
     * @private
     * Format the code in the editor
     */
    getQuery: function ()
    {
        var value = this.queryEditor.getValue();
        if (value)
        {
            try
            {
                this._formatJsonCode();
                return this.queryEditor.getValue();
            }
            catch (e)
            {
                var result = {}
                result.errorMessage = "{{i18n PLUGINS_CMS_SOLR_QUERY_TOOL_MALFORMED_QUERY_ERROR_DESC}} : <br/>" + e.message;
                this.updateResult(result);
                
                return null;
            }
        }
        else
        {
            var result = {}
            result.errorMessage = "{{i18n PLUGINS_CMS_SOLR_QUERY_TOOL_NO_QUERY_ERROR_DESC}}";
            this.updateResult(result);
            
            return null;
        }
    },
    
    _formatJsonCode: function()
    {
        return JSON.stringify(JSON.parse(this.queryEditor.getValue()), undefined, 4);
    }
})