import React from 'react';
import { IPagination } from '../pagination/types';
import { IColumn } from './types';

export const mapFixedClass = (fixed: 'left' | 'right' | undefined, last: boolean) => {
    switch (fixed) {
        case 'left':
            return `fix-left-cell${last ? ' fixed-last' : ''}`;
        case 'right':
            return `fix-right-cell${last ? ' fixed-last' : ''}`;
        default:
            return '';
    }
};

export const calcOffsets = (
    columns: IColumn[],
    showChecker: boolean
): [number[], (number | undefined)[], number, number] => {
    const rightFixedIndex = columns.findIndex(col => col.fixed === 'right');
    const leftFixedIndex = columns.length - 1 - [...columns].reverse().findIndex(col => col.fixed === 'left');
    if (leftFixedIndex >= rightFixedIndex && leftFixedIndex !== -1 && rightFixedIndex !== -1) {
        throw new Error('请检查columns参数的设置');
    }
    const left: number[] = [];
    let leftOffset = showChecker ? 70 : 0;
    const right: (number | undefined)[] = [];
    let rightOffset = 0;
    columns.forEach((col, index) => {
        if (index <= leftFixedIndex && leftFixedIndex !== columns.length) {
            if (typeof col.width !== 'number') {
                throw new Error('固定的列必须指定宽度，且必须为数字，默认px单位');
            }
            left.push(leftOffset);
            leftOffset += col.width;
        }
    });
    [...columns].reverse().forEach((col, index) => {
        if (index < columns.length - rightFixedIndex && rightFixedIndex !== -1) {
            if (typeof col.width !== 'number') {
                throw new Error('固定的列必须指定宽度，且必须为数字，默认px单位');
            }
            right.push(rightOffset);
            rightOffset += col.width;
        } else {
            right.push(undefined);
        }
    });
    return [left, right.reverse(), leftFixedIndex, rightFixedIndex];
};

export const setFilterState = (columns: IColumn[], state: any, dispatch: any) => {
    const payload: any = {};
    columns.forEach(col => {
        const key = col.key + 'Filter';
        if (col.filter && !(key in state)) {
            if (col.filterMultiple) {
                payload[key] = col.defaultFiltered || [];
            } else {
                payload[key] = col.defaultFiltered;
            }
        }
        if (
            col.sorter &&
            col.defaultSortDirection &&
            col.key !== state.sortKey &&
            col.defaultSortDirection !== state.sortOrder
        ) {
            payload.sortKey = col.key;
            payload.sortOrder = col.defaultSortDirection;
        }
    });
    Object.keys(payload).length && dispatch(payload);
};

export const filterNSortDataSource = (columns: IColumn[], dataSource: any[], state: any) => {
    const filters: any[] = [];
    const sorters: any[] = [];
    columns.forEach(col => {
        if (col.filter && col.sorter) {
            throw new Error('过滤和排序只能定义其一');
        }
        if (col.filter && col.filterLocal && state[col.key + 'Filter']) {
            filters.push(col.filterLocal.bind(null, state[col.key + 'Filter']));
        }
        if (typeof col.sorter === 'function') {
            sorters.push({ fn: col.sorter, direction: col.defaultSortDirection, key: col.key });
        }
        if (sorters.filter(s => s.direction).length > 1) {
            throw new Error('只能指定一个默认排序');
        }
    });
    return dataSource
        .filter((row, index) => !filters.length || filters.map(f => f(row, index)).every(Boolean))
        .sort((a, b) => {
            if (sorters.length && state.sortOrder && state.sortKey) {
                const find = sorters.find(s => s.key === state.sortKey);
                const result = find.fn(a, b);
                return state.sortOrder === 'descend' ? -1 * result : result;
            } else {
                return 0;
            }
        });
};

export const getPageInfo = (state: any, pagination: Partial<IPagination>) => {
    const controlledDataSource = 'page' in pagination;

    const page = pagination.page || state.page;

    const pageSize = pagination.pageSize || state.pageSize;

    return { controlledDataSource, page, pageSize };
};
