/**
 * @file Calculation vendor
 * @author liangxiaojun(liangxiaojun@derbysoft.com)
 */

import isArray from 'lodash/isArray';
import Valid from './Valid';
import SelectMode from '../_statics/SelectMode';
import Util from './Util';

function pageSize(pageSize, pageSizes, defaultValue) {

    if (pageSize) {
        return pageSize;
    }

    if (pageSizes && pageSizes.length > 0) {

        for (let item of pageSizes) {
            if (item > 0) {
                return item;
            }
        }
    }

    return defaultValue;

}

function displayIndexByScrollTop(data, listHeight, itemHeight, scrollTop = 0, buffer = 0) {

    if (!data || !listHeight || !itemHeight) {
        return {
            start: 0,
            stop: 0,
            startWithBuffer: 0,
            stopWithBuffer: 0
        };
    }

    const len = data.length,
        start = Math.floor(scrollTop / itemHeight),
        stop = start + Math.ceil(listHeight / itemHeight);

    return {
        start: Valid.range(start, 0, len - 1),
        stop: Valid.range(stop, 0, len - 1),
        startWithBuffer: Valid.range(start - buffer, 0, len - 1),
        stopWithBuffer: Valid.range(stop + buffer, 0, len - 1)
    };

}

function displayIndexByScrollTopMulColumns(data, listHeight, itemHeight, column, scrollTop = 0, buffer = 0) {

    if (!data || !listHeight || !itemHeight) {
        return {
            start: 0,
            stop: 0,
            startWithBuffer: 0,
            stopWithBuffer: 0
        };
    }

    const len = data.length,
        start = Math.floor(scrollTop / itemHeight) * column,
        stop = start + Math.ceil(listHeight / itemHeight) * column;

    return {
        start: Valid.range(start, 0, len - 1),
        stop: Valid.range(stop, 0, len - 1),
        startWithBuffer: Valid.range(Valid.range(start, 0, len - 1) - buffer, 0, len - 1),
        stopWithBuffer: Valid.range(stop + buffer, 0, len - 1)
    };

}

function getInitValue(props) {

    if (!props) {
        return;
    }

    const {value, selectMode} = props;

    if (!selectMode) {
        return;
    }

    if (value != null) {
        return value;
    }

    switch (selectMode) {
        case SelectMode.MULTI_SELECT:
            return [];
        case SelectMode.SINGLE_SELECT:
            return null;
        default:
            return value;
    }

}

function getMultiSelectItemIndex(item, value, {selectMode, valueField, displayField}) {

    if (selectMode !== SelectMode.MULTI_SELECT || !item || !value) {
        return -1;
    }

    if (!isArray(value)) {
        return -1;
    }

    return value.findIndex(valueItem => Util.isValueEqual(valueItem, item, valueField, displayField));

}

function isItemChecked(item, value, {selectMode, valueField, displayField}) {

    if (!item || value == null) {
        return false;
    }

    // Single Selection
    if (selectMode === SelectMode.SINGLE_SELECT) {
        return Util.isValueEqual(value, item, valueField, displayField);
    }

    // Multiple Selection
    if (!isArray(value) || value.length < 1) {
        return false;
    }
    for (let v of value) {
        if (Util.isValueEqual(v, item, valueField, displayField)) {
            return true;
        }
    }
    return false;

}

function isItemIndeterminate(node, value, {valueField, displayField}) {

    if (!node || !node.children || node.children.length < 1
        || !value || !value.length || value.length < 1) {
        return false;
    }

    let total = 0,
        count = 0;

    Util.preOrderTraverse(node, nodeItem => {
        total++;
        if (value.findIndex(item => Util.getValueByValueField(item, valueField, displayField) === Util.getValueByValueField(nodeItem, valueField, displayField)) > -1) {
            count++;
        }
    });

    return count > 0 && total !== count;

}

function filterAutoCompleteData(filter, props) {

    const {data, minFilterLength} = props;

    if (!filter || filter.length < minFilterLength) {
        return data;
    }

    const {valueField, displayField, renderer} = props;

    return data?.filter(item => {

        if (!item) {
            return false;
        }

        if (renderer) {
            return renderer(item).toString().toUpperCase().includes(filter.toUpperCase());
        }

        if (typeof item === 'object') {

            const itemDisplay = Util.getTextByDisplayField(item, displayField, valueField);

            if (itemDisplay) {
                return itemDisplay.toString().toUpperCase().includes(filter.toUpperCase());
            }

        }

        return item.toString().toUpperCase().includes(filter.toUpperCase());

    });

}

function filterLocalAutoCompleteData(filter, props) {

    const {data, minFilterLength} = props;

    if (!filter || filter.length < minFilterLength) {
        return data;
    }

    const {valueField, displayField, renderer, filterCallback} = props;

    if (filterCallback) {
        return filterCallback(filter, data);
    }

    return data?.filter(item => {

        if (!item) {
            return false;
        }

        if (renderer) {
            return renderer(item).toString().toUpperCase().includes(filter.toUpperCase());
        }

        if (typeof item === 'object') {

            const itemDisplay = Util.getTextByDisplayField(item, displayField, valueField);

            if (itemDisplay) {
                return itemDisplay.toString().toUpperCase().includes(filter.toUpperCase());
            }

        }

        return item.toString().toUpperCase().includes(filter.toUpperCase());

    });

}

export default {
    pageSize,
    displayIndexByScrollTop,
    getInitValue,
    getMultiSelectItemIndex,
    displayIndexByScrollTopMulColumns,
    isItemChecked,
    isItemIndeterminate,
    filterAutoCompleteData,
    filterLocalAutoCompleteData
};

@@ -82,16 +82,88 @@
 m)%0A */%0A%0A
+// Statics%0Aimport SelectMode from '../_statics/SelectMode';%0A%0A// Vendors%0A
 import i
@@ -225,57 +225,8 @@
 d';%0A
-import SelectMode from '../_statics/SelectMode';%0A
 impo
@@ -2405,32 +2405,57 @@
 dex(item, value,
+ props = %7B%7D) %7B%0A%0A    const
  %7BselectMode, va
@@ -2469,35 +2469,41 @@
 d, displayField%7D
-) %7B
+ = props;
 %0A%0A    if (select
@@ -3718,16 +3718,28 @@
 eld) ===
+%0A           
  Util.ge

update Calculation