import { connect } from 'react-redux';
import {
    toggleFeature,
    fetchFeatureToggles,
} from '../../../store/feature-toggle/actions';
import { updateSettingForGroup } from '../../../store/settings/actions';
import FeatureToggleList from './FeatureToggleList';

function checkConstraints(strategy, regex) {
    if (!strategy.constraints) {
        return;
    }
    return strategy.constraints.some(c => c.values.some(v => regex.test(v)));
}

function resolveCurrentProjectId(settings) {
    if (!settings.currentProjectId || settings.currentProjectId === '*') {
        return 'default';
    }
    return settings.currentProjectId;
}

export const mapStateToPropsConfigurable = isFeature => state => {
    const featureMetrics = state.featureMetrics.toJS();
    const flags = state.uiConfig.toJS().flags;
    const settings = state.settings.toJS().feature || {};
    let features = isFeature
        ? state.features.toJS()
        : state.archive.get('list').toArray();

    if (settings.currentProjectId && settings.currentProjectId !== '*') {
        features = features.filter(
            f => f.project === settings.currentProjectId
        );
    }
    if (settings.filter) {
        try {
            const regex = new RegExp(settings.filter, 'i');
            features = features.filter(feature => {
                if (!isFeature) {
                    return (
                        regex.test(feature.name) ||
                        regex.test(feature.description) ||
                        (settings.filter.length > 1 &&
                            regex.test(JSON.stringify(feature)))
                    );
                }
                return (
                    feature.strategies.some(s => checkConstraints(s, regex)) ||
                    regex.test(feature.name) ||
                    regex.test(feature.description) ||
                    feature.strategies.some(
                        s => s && s.name && regex.test(s.name)
                    ) ||
                    (settings.filter.length > 1 &&
                        regex.test(JSON.stringify(feature)))
                );
            });
        } catch (e) {
            // Invalid filter regex
        }
    }

    if (!settings.sort) {
        settings.sort = 'name';
    }

    if (settings.sort === 'enabled') {
        features = features.sort((a, b) =>
            // eslint-disable-next-line
            a.enabled === b.enabled ? 0 : a.enabled ? -1 : 1
        );
    } else if (settings.sort === 'stale') {
        features = features.sort((a, b) =>
            // eslint-disable-next-line
            a.stale === b.stale ? 0 : a.stale ? -1 : 1
        );
    } else if (settings.sort === 'created') {
        features = features.sort((a, b) =>
            new Date(a.createdAt) > new Date(b.createdAt) ? -1 : 1
        );
    } else if (settings.sort === 'Last seen') {
        features = features.sort((a, b) =>
            new Date(a.lastSeenAt) > new Date(b.lastSeenAt) ? -1 : 1
        );
    } else if (settings.sort === 'name') {
        features = features.sort((a, b) => {
            if (a.name < b.name) {
                return -1;
            }
            if (a.name > b.name) {
                return 1;
            }
            return 0;
        });
    } else if (settings.sort === 'project') {
        features = features.sort((a, b) =>
            a.project.length > b.project.length ? -1 : 1
        );
    } else if (settings.sort === 'type') {
        features = features.sort((a, b) => {
            if (a.type < b.type) {
                return -1;
            }
            if (a.type > b.type) {
                return 1;
            }
            return 0;
        });
    } else if (settings.sort === 'metrics') {
        const target = settings.showLastHour
            ? featureMetrics.lastHour
            : featureMetrics.lastMinute;

        features = features.sort((a, b) => {
            if (!target[a.name]) {
                return 1;
            }
            if (!target[b.name]) {
                return -1;
            }
            if (target[a.name].yes > target[b.name].yes) {
                return -1;
            }
            return 1;
        });
    }

    return {
        features,
        currentProjectId: resolveCurrentProjectId(settings),
        featureMetrics,
        archive: !isFeature,
        settings,
        flags,
        loading: state.apiCalls.fetchTogglesState.loading,
    };
};
const mapStateToProps = mapStateToPropsConfigurable(true);
const mapDispatchToProps = {
    toggleFeature,
    fetcher: () => fetchFeatureToggles(),
    updateSetting: updateSettingForGroup('feature'),
};

const FeatureToggleListContainer = connect(
    mapStateToProps,
    mapDispatchToProps
)(FeatureToggleList);

export default FeatureToggleListContainer;
