window.resetChanged = function()
{
    $('#pivotState').attr('data-changed', JSON.stringify([]));
}

window.getStateChange = function()
{
    const ignores = ['queryCols', 'queryData', 'pivotCols', 'pivotData', 'pivotCellSpan', 'default[]'];
    const data = {};
    let changed = $('#pivotState').data('changed');
    changed = changed.filter(key => !ignores.includes(key));
    changed.forEach(key => (data[key] = pivotState()[key]));

    return data;
}

window.pivotState = function(key, value)
{
    const state = $('#pivotState').data('state');
    let changed = $('#pivotState').data('changed');

    if(key?.length && state.hasOwnProperty(key))
    {
        state[key] = value;
        changed.push(key);
        changed = Array.from(new Set(changed));
        $('#pivotState').attr('data-state', JSON.stringify(state));
        $('#pivotState').attr('data-changed', JSON.stringify(changed));
    }

    return state;
}

window.postQueryResult = function(e, info)
{
    const { item } = info;
    const { page } = item;
    const { pager } = pivotState();
    const { pageID, pageTotal } = pager;

    if(page == 'first' && pageID != 1)            pager.pageID = 1;
    if(page == 'last' && pageTotal != pageID)     pager.pageID = pageTotal;
    if(page == 'prev' && pageID - 1 >= 1)         pager.pageID = pageID - 1;
    if(page == 'next' && pageID + 1 <= pageTotal) pager.pageID = pageID + 1;

    pivotState('pager', pager);
    updateDesignPage('query');
}

window.updateDesignPage = function(action, index)
{
    const {link, formData, selectors} = buildPostParams(action, index);

    postAndLoadPage(link, formData, selectors, {modal: true});
}

window.postDesignPage = function(action, index)
{
    const {link, formData} = buildPostParams(action, index);
    postAndLoadPage(link, formData, `pageJS/.zin-page-js,#configJS`, {modal: true});
}

window.buildPostParams = function(action, index)
{
    if(!action) action = pivotState.action;
    pivotState.action = action;

    let actionSelectors = actionLoadTarget[action] ?? '#stepContent';
    if(Number.isInteger(index) || index) {
        let regex = new RegExp('%s', "g");
        actionSelectors = actionSelectors.replace(regex, index);
    }

    const data = getStateChange();
    if(action.startsWith('sqlBuilder-'))
    {
        const builder = getSqlBuilderPost(action, index);
        data.sqlbuilder = builder.data;
        actionSelectors = builder.selectors;
    }

    const formData  = zui.createFormData({action, data: JSON.stringify(data)});
    let selectors = [actionSelectors, '#dictionarySideBar', '#pivotState', '#sqlModal', '#saveAsDraft', '#stepNav', 'pageJS/.zin-page-js', 'pageCSS/.zin-page-css>*', '#configJS'];
    const link = $('#pivotState').data('url');

    return {link, formData, selectors: selectors.filter(selector => selector?.length != 0).join(',')};
}

window.allowAutoGenDrills = function()
{
    pivotState('autoGenDrills', true);
}

window.setDrillType = function(modalID, type)
{
  setDrillField(modalID, 'type', type);
}

window.setDesignChangedWarning = function(targetField = 'all', showWarning = true)
{
    const {drills} = pivotState();
    drills.forEach(function(value, index, drills)
    {
        if(!drills[index]) return;
        if(targetField == 'all' || targetField == value.field || value.field == '' || !value.field) drills[index]['warning'] = showWarning;
    });
    pivotState('drills', drills);
}

window.saveSettings = function()
{
    pivotState('checkStepDesign', true);
    updateDesignPage('table');
}

window.savePivot = function(saveStage = 'publish')
{
    const {stage, used} = pivotState();
    let isPublished = stage == 'published';
    if(saveStage == 'draft')
    {
        if(isSqlChanged())
        {
            clearAll4SaveDraft(isPublished);
        }
        else
        {
            confirmSaveDraft(isPublished);
        }
        return;
    }

    if(used)
    {
        zui.Modal.confirm({message: confirmPublish}).then((res) =>
        {
            if(res) save(saveStage);
        });
    }
    else
    {
        save(saveStage);
    }
}

window.save = function(stage)
{
    pivotState('stage', stage);
    const data = getStateChange();
    const formData = zui.createFormData(data ? {action: 'publish', data: JSON.stringify(data)} : {action: 'publish'});
    const link = $('#pivotState').data('url');

    $.post(link, formData, function(response)
    {
        response = JSON.parse(response);
        if(response.result == 'success')
        {
            zui.Messager.show({content: response.message, type: 'success', time: 1000});
            setTimeout(() => loadPage(response.locate), 1000);
        }
    });
}

/**
 * 查询条件改变时重新加载自定义透视表。
 * Reload custom pivot table when query conditions changed.
 *
 * @access public
 * @return void
 */
window.loadCustomPivot = function()
{
    updateDesignPage('table');
}

/**
 * Judge whether filter is query type.
 *
 * @access public
 * @return bool
 */
window.isQueryFilter = function()
{
    const {filters} = pivotState();
    return filters.some(function(filter) {
        return filter.from === 'query';
    });
}

window.handleFilterChange = function(event, name, suffix)
{
    const $target = $(event?.target);
    if(!$target) return;

    const value     = $target.val();
    let valueKey    = '';

    if(suffix) valueKey = suffix

    let {pivotFilters} = pivotState();
    pivotFilters = pivotFilters.map((filters) => {
        return filters.map((filter) => {
            if(filter.name == name)
            {
                filter.value = valueKey.length ? {...filter.value, [valueKey]: value} : value;
            }
            return filter;
        });
    });

    pivotState('pivotFilters', pivotFilters);
}

window.ajaxQuery = function()
{
    updateDesignPage('query');
}

window.changeStep = function(e)
{
    const $a = $(e.target).closest('a');
    const step = $a.attr('step');
    if(step == pivotState().step) return;

    if(isSqlChanged()) return clearAllConfirm(step);
    switchStep(step);
}

window.isSqlChanged = function()
{
    const {step, step2FinishSql, sql} = pivotState();
    return step == 'query' && step2FinishSql.length && step2FinishSql != sql;
}

window.clearAllConfirm = function(step)
{
    zui.Modal.confirm({message: resetSettingsTip}).then((res) =>
    {
        if(res)
        {
            pivotState('settings', []);
            if(!isQueryFilter())
            {
                pivotState('filters', []);
                pivotState('pivotFilters', []);
            }
            pivotState('drills', []);
            pivotState('step2FinishSql', '');

            switchStep(step);
        }
    });
}

window.clearAll4SaveDraft = function(isPublished)
{
    zui.Modal.confirm({message: resetSettingsTip}).then((res) =>
    {
        if(res)
        {
            pivotState('settings', []);
            if(!isQueryFilter())
            {
                pivotState('filters', []);
                pivotState('pivotFilters', []);
            }
            pivotState('drills', []);
            pivotState('step2FinishSql', '');

            confirmSaveDraft(isPublished);
        }
    });
}

window.confirmSaveDraft = function(isPublished)
{
    if(pivotState().used)
    {
        zui.Modal.confirm({message: confirmDraft}).then((res) =>
        {
            if(res) save('draft');
        });
    }
    else
    {
        if(isPublished)
        {
            zui.Modal.confirm({message: draftSave}).then((res) =>
            {
                if(res) save('draft');
            });
        }
        else
        {
            save('draft');
        }
    }
}

window.setChanged = function(changed = true)
{
    pivotState('filterChanged', changed);
}

window.getChanged = function()
{
    return pivotState().changedWithoutSave;
}

window.nextStep = function()
{
    const currentStep = pivotState().step;
    const index       = stepOrder.findIndex(s => s == currentStep);
    if(index + 1 >= stepOrder.length) return;
    const nextStep    = stepOrder[index + 1];

    if(isSqlChanged()) return clearAllConfirm(nextStep);

    switchStep(nextStep);
}

window.switchStep = function(step)
{
    const designActions = $('#pivotState').data('actions');
    const action = designActions[step][0];

    pivotState('step', step);
    if(pivotState().mode == 'builder')
    {
        const {sqlbuilder} = pivotState();
        sqlbuilder.step = 'table';
        pivotState('sqlbuilder', sqlbuilder);
    }
    updateDesignPage(action);
}

window.handleSqlChange = function()
{
    const sql = $('#sqlForm').find('textarea[name="sql"]').val();
    pivotState('sql', sql);
    if(pivotState().mode == 'text')
    {
        const canChangeMode = !sql?.trim()?.length;
        pivotState('canChangeMode', canChangeMode);
        canChangeMode ? $('#changeMode').removeClass('hidden')      : $('#changeMode').addClass('hidden')
        canChangeMode ? $('#changeModeDisabled').addClass('hidden') : $('#changeModeDisabled').removeClass('hidden')
    }
}

window.saveFields = function()
{
    let $form    = $('#fieldSettingsForm');
    let formData = new FormData($form[0]);
    let data = {};
    for (var [key, value] of formData.entries()) {
        const pureKey = key.substring(0, key.indexOf("["));
        if(!data[pureKey]) data[pureKey] = [];
        data[pureKey].push(value);
    }

    let fieldSettings = {};
    data.key.forEach((key, index) => {
        fieldSettings[key] = {};
        Object.keys(data).forEach(itemKey => {
            if(itemKey == 'key') return;
            fieldSettings[key][itemKey] = data[itemKey][index];
        });
    });

    pivotState('fieldSettings', fieldSettings);

    updateDesignPage('saveFields');
}

window.exportData = function()
{
    var $domObj = $('#stepContent').find(".table-condensed")[0];

    exportFile($domObj);
}

window.renderDrillResult = function(result, {col, row})
{
    if(col.name == 'name' && row.data.type == 'program') result[0].props.href = $.createLink('program', 'kanban');

    return result;
}
