const ASCII_a = 97;
const ASCII_z = 122;

window.initValue = function(key = '', $value = '')
{
    if(!key) return $('#dataform').data('initvalue');
    const data = $('#dataform').data('initvalue');
    data[key] = $value;
    $('#dataform').attr('data-initvalue', JSON.stringify(data));
    return data;
};

window.postCreate = function(errors)
{
    const data = initValue();
    const postUrl = $('#dataform').data('posturl');
    const formData = zui.createFormData({initValue: JSON.stringify(data), errors: JSON.stringify(errors)});
    postAndLoadPage(postUrl, formData, `pageJS/.zin-page-js,#configJS,#dataform`, {modal: true, partial: true});
};

window.addHypo = function()
{
    const {hypo} = initValue();

    var charMap = Object.keys(hypo);
    var canAdd   = false;
    var currChar = '';
    for(var i = ASCII_a; i <= ASCII_z; i ++)
    {
        var letter = String.fromCharCode(i);
        if(!charMap.includes(letter))
        {
            currChar = letter;
            canAdd = true;
            break;
        }
    }

    if(!canAdd) return;

    hypo[currChar] = {variable: currChar, varName: '', type: 'dist', distribution: ''};
    initValue('hypo', hypo);
    postCreate();
};

window.removeHypo = function($this)
{
    const index = $this.data('index');
    let {hypo} = initValue();
    delete hypo[index];
    initValue('hypo', hypo);
    postCreate();
};

window.changeType = function($this)
{
    const $hypoRow = $this.closest('.hypo-row');
    const index = $hypoRow.data('index');
    const {hypo} = initValue();
    hypo[index].type = $this.val();
    hypo[index].distribution = '';
    initValue('hypo', hypo);
    postCreate();
};

window.changeDecisionStus = function($this)
{
    const checked = $('[name=decisionStus]:checked').val();
    initValue('decisionStus', checked);
    postCreate();
};

window.addDecision = function()
{
    const {decision} = initValue();
    var xnameMap = decision.map((x) => x.decisionXname);
    var canAdd = false;
    var currX = '';
    for(var i = 1; i <= 9 ; i ++)
    {
        if(!xnameMap.includes('x' + i))
        {
            canAdd = true;
            currX = 'x' + i;
            break;
        }
    }
    if(!canAdd) return;
    decision.push({decisionXname: currX, decisionName: '', decisionVar: ''});
    initValue('decision', decision);
    postCreate();
};

window.removeDecision = function($this)
{
    const index = $this.data('index');
    let {decision} = initValue();
    decision = decision.filter((x) => x.decisionXname !== index);
    initValue('decision', decision);
    postCreate();
};
window.addForecast = function()
{
    const {forecast} = initValue();
    var ynameMap = forecast.map((x) => x.forecastYname);
    var canAdd = false;
    var currY = '';
    for(var i = 1; i <= 9 ; i ++)
    {
        if(!ynameMap.includes('y' + i))
        {
            canAdd = true;
            currY = 'y' + i;
            break;
        }
    }
    if(!canAdd) return;
    forecast.push({forecastYname: currY, exportY: '', forecastName: '', formula: ''});
    initValue('forecast', forecast);
    postCreate();
};

window.removeForecast = function($this)
{
    const index = $this.data('index');
    let {forecast, target} = initValue();
    forecast = forecast.filter((x) => x.forecastYname !== index);
    let findExportY = forecast.find((x) => x.exportY === 'checked');
    if(!findExportY) forecast[0].exportY = 'checked';

    findExportY = forecast.find((x) => x.exportY === 'checked');
    if(findExportY) target[0].targetYname = findExportY.forecastYname;
    initValue('forecast', forecast);
    initValue('target', target);
    postCreate();
};

window.changeExportY = function($this)
{
    const checked = $('[name=exportY]:checked').val();
    const {forecast, target} = initValue();
    const forecastIndex = forecast.findIndex((x) => x.forecastYname === checked);
    if(forecastIndex === -1) return;

    target[0].targetYname = checked;
    forecast.forEach((x) => x.exportY = '');
    forecast[forecastIndex].exportY = 'checked';
    initValue('forecast', forecast);
    initValue('target', target);
    postCreate();
}

window.addRequest = function()
{
    const {forecast, request} = initValue();
    const firstY = forecast[0].forecastYname;
    request.push({reqVar: firstY, reqStat: 'mean', reqCondition: 'gt', reqValue: ''});
    initValue('request', request);
    postCreate();
};

window.removeRequest = function($this)
{
    const index = $this.data('index');
    let {request} = initValue();
    request.splice(index, 1);
    initValue('request', request);
    postCreate();
};

window.changeRunNumber = function($this)
{
    const value = $this.val();
    initValue('runNumber', value);
}

window.changeFormControl = function($this)
{
    const $formRow = $this.closest('.form-row');
    let [type, index] = $formRow.attr('id').split('-');
    const name  = $this.attr('name').replace(/\[.*\]/g, '');
    const value = $this.val();

    let varibaleField = 'variable';
    if(type === 'forecast') varibaleField = 'forecastYname';
    if(type === 'decision') varibaleField = 'decisionXname';
    if(type === 'target')   varibaleField = 'targetYname';

    const data = initValue()[type];
    if(type !== 'request' && type !== 'hypo') index = data.findIndex((x) => x[varibaleField] === index);
    if(type === 'hypo') data[index][name] = value;
    data[index][name] = value;
    $formRow.find('.text-error').addClass('hidden');

    initValue(type, data);
}

window.openAdddist = function(event)
{
    const url     = $(event).data('url');
    const varName = $(event).closest('.form-row').find('.group-varName .label').text();
    loadModal(url.replace('{letter}', varName).replace('[value]', ''));
}

window.setDist = function(id, str, varName)
{
    $("input[name='" + id + "']").val(str);
    window.changeFormControl($("input[name='" + id + "']"));
    $distBtn = $(`.form-row[data-index='${varName}']`).find('[name^="distribution["]').siblings('.btn');
    const btnText = getDistLang(str);
    $distBtn.html(btnText).attr('title', btnText);
    str = btoa(str);
    let url = $.createLink('montecarlo', 'addDist', `var=${varName}&value=${str}`);
    $distBtn.attr('href', url);
}

function getDistLang(str)
{
    const distKey = ['normal', 'triangular'];
    distKey.forEach(function(key)
    {
        if(str.indexOf(key) != -1) str = str.replace(key, dists[key].title);
    });

    return str;
}

window.submitMontecarlo = async function(draft)
{
    const url  = $('#dataform form').attr('action');
    const form = new FormData($('#dataform form')[0]);

    draft = draft ? '1' : '0';

    form.append('draft', draft);

    if(draft == '0')
    {
        let result = await ajaxCheckSettings();
        result = JSON.parse(result);
        if(result.result == 'fail')
        {
            showError(result.errors);
            return;
        }
    }

    $.ajaxSubmit({url, data: form});
}


window.ajaxCheckSettings = async function()
{
    const url = $.createLink('montecarlo', 'ajaxCheckSettings');
    return await $.post(url, {initValue: JSON.stringify(initValue())});
}

window.showError = function(errors)
{
    window.postCreate(errors);
}

window.createFromExcel = function(data)
{
    data = atob(data);
    data = JSON.parse(data);
    const {hypo, forecast, decision, decisionStus} = data;
    initValue('hypo', hypo);
    initValue('forecast', forecast);
    initValue('decision', decision);
    initValue('decisionStus', decisionStus);
    window.changeExportY();
}
