var fields  = {};
var columns = {};
var rows    = [];
var modal;

/**
 * Query sql.
 *
 * @param function callback
 * @access public
 * @return void
 */
function query(callback)
{
    $.post(createLink('dataview', 'ajaxQuery'), {sql: $('#sql').val(), sourceID: $('#sourceID').val(), row: 25}, function(resp)
    {
        resp = JSON.parse(resp);
        if(resp.result !== 'success')
        {
            var message = resp.message.errorInfo ? resp.message.errorInfo[2] : resp.message;
            $('.error').removeClass('hidden');
            $('.error td').html(message);
            drawTable([], []);
        }
        else
        {
            $('.error').addClass('hidden');
            $('.error td').html('');

            fields  = resp.fields;
            columns = resp.columns;
            rows    = resp.rows;
            vars    = resp.vars;

            drawTable(resp.fields, resp.rows);
            addResult(resp);
            if(typeof callback == 'function') callback();
        }
    });
}

function addResult(resp)
{
    $('#queryResult').remove();

    var lineCount   = resp.lineCount;
    var columnCount = resp.columnCount;
    var queryMsg    = queryResult;

    queryMsg = queryMsg.replace('%s', lineCount);
    queryMsg = queryMsg.replace('%s', columnCount);
    if(lineCount > 25) queryMsg += resultGT25;

    $('.titleResult .btn-active-text').append("<span style='float:right;' id='queryResult'>" + queryMsg + "</span>");
}
/**
 * Save field settings.
 *
 * @access public
 * @return bool
 */
function saveSettings()
{
    for(let index in fields)
    {
        fieldSettings[index].name   = $('#' + index + 'Name').val();
        fieldSettings[index].object = $('#' + index + 'Type').val();
    }

    $('#addModal').modal('hide');
    this.drawTable(fields, rows);
    return false;
}

/**
 * Draw table content for sql result.
 *
 * @param object fields
 * @param array rows
 * @access public
 * @return void
 */
function drawTable(fields, rows)
{
    $('.table-empty-tip').addClass('hidden');
    if(rows.length == 0)
    {
        $('.table-empty-tip').removeClass('hidden');
        $('table.result').empty();
        return;
    }
    var head = '<tr>';
    for(let field in fields)
    {
        var fieldSetting = fieldSettings[field];
        var fieldName = fieldSetting ? fieldSetting.name : fields[field];
        head += '<th>' + fieldName + '</th>';
    }
    head += '</tr>';

    var html = '<thead>' + head + '</thead>';

    var body = '';
    for(let row of rows)
    {
        body += '<tr>';
        for(let index in row) body += '<td><div class="ellipsis-multi" title="' + row[index] + '">' + row[index] + '</div></td>';
        body += '</tr>';
    }

    html += '<tbody>' + body + '</tbody>';

    $('table.result').html(html);
}

/**
 * Get text width.
 *
 * @param string text
 * @access public
 * @return float
 */
function getTextWidth(text)
{
    var font = "bold 12pt arial"
    var canvas = document.createElement("canvas");
    var context = canvas.getContext("2d");
    context.font = font;
    var measure = context.measureText(text);

    return measure.width;
}

/**
 * Get field settings.
 *
 * @access public
 * @return float
 */
function getFieldSettings()
{
    for(let index in fields)
    {
        var field  = fields[index];
        var type   = columns[index];

        var defaultObject = type == 'date' ? 'date' : 'string';

        if(!fieldSettings[index])
        {
            fieldSettings[index] = {
                name: field,
                object: defaultObject,
                field: index,
                type: type
            };
        }
        else
        {
            var object = fieldSettings[index].object;
            object = object.length == 0 ? defaultObject : object;

            fieldSettings[index].type   = type;
            fieldSettings[index].object = object;
        }
    }
}

$(document).ready(function()
{
    if(fieldSettings instanceof Array) fieldSettings = {};

    $('#sql').on('input', function()
    {
        $('.error').addClass('hidden');
        fieldSettings = {};
    })
    $('.query').click(query);
    $('#back').click(function(){window.location.href = backLink;});

    $('.fieldSettings').click(function() {
        query(function() {
            getFieldSettings();

            var formTpl = $('#fieldSettingTpl').html();
            var formHtml = $(formTpl);

            var tbodyTpl = $('#tbodyTpl').html();

            var fieldTypeOptions = Object.keys(lang.fieldTypeList).map(function(key)
            {
                return {text: lang.fieldTypeList[key], value: key};
            });

            var tbodyHtmls = Object.keys(fieldSettings).map(function(field)
            {
                var html = $($.zui.formatString(tbodyTpl, {field: field, name: fieldSettings[field].name}));
                html.find('select.form-control').picker({list: fieldTypeOptions, defaultValue: fieldSettings[field].object});
                return html;
            });

            formHtml.find('tbody').append(tbodyHtmls);

            var modal = $('#addModal');
            modal.find('.modal-body').html(formHtml);
            modal.modal({});
        })
    });

    $('#save').click(function() {
        const $that = $(this);
        query(function() {
            if($('#fields').length == 0)  $('#dataform table').before($('<input>').attr({name: 'fields', id: 'fields'}).addClass('hidden'));

            getFieldSettings();

            /* Fix bug #26716. */
            for(let index in fieldSettings)
            {
                if(!Object.keys(fields).includes(index)) delete fieldSettings[index];
            }

            $('#fields').val(JSON.stringify(fieldSettings));
            $('#dataform').submit();
        })
    });
});
