import {createFeatureSelector, createSelector} from "@ngrx/store";
import {ApplicationState} from "../application-state";

export const applicationStateFeature = createFeatureSelector<ApplicationState>('application');

export const selectLists = createSelector(
    applicationStateFeature,
    (state: ApplicationState) => [...state.lists].sort((a, b) => a.title.localeCompare(b.title))
)
export const selectFollowings = createSelector(
    applicationStateFeature,
    (state: ApplicationState) => state.followings
);

export const selectMappings = createSelector(
    applicationStateFeature,
    (state: ApplicationState) => state.listsAccounts
);

export const selectListsWithAccounts = createSelector(
    selectLists,
    selectFollowings,
    selectMappings,
    (lists, followings, mappings) => {
        return lists.map(list => {
            const accountIds = mappings[list.id] || [];
            const accounts = followings.filter(account => accountIds.includes(account.id));
            return {...list, accounts};
        });
    }
);

export const selectFollowingsWithLists = createSelector(
    selectFollowings,
    selectLists,
    selectMappings,
    (followings, lists, mappings) => {
        return followings.map(account => {
            const listIds = Object.keys(mappings).filter(listId => mappings[listId].includes(account.id));
            const accountLists = lists.filter(list => listIds.includes(list.id));
            return {...account, lists: accountLists};
        });
    }
);

export const selectFilters = createSelector(
    applicationStateFeature,
    (state: ApplicationState) => state.filters
);

export const selectFiltersForForm = createSelector(
    applicationStateFeature,
    (state: ApplicationState) => {
        const filters = state.filters;
        const parts = [];
        if (filters.username) {
            parts.push(`@${filters.username}`);
        }
        parts.push(...filters.freeText);
        const fullText = parts.join(',');
        return {
            fullText: fullText.length > 0 ? fullText : undefined,
            lists: filters.lists,
            unlisted: filters.unlisted,
        }
    }
);

export const selectFilteredFollowingsWithLists = createSelector(
    selectFollowingsWithLists,
    selectFilters,
    (followings, filters) => {
        return followings.filter(account => {
            const usernameMatch = filters.username.length === 0 || account.username.toLowerCase().startsWith(filters.username.toLowerCase());
            const freeTextMatch = filters.freeText.length === 0 || filters.freeText
                .every(text => {
                    const lowerCaseText = text.toLowerCase();
                    return account.username.toLowerCase().includes(lowerCaseText)
                        || account.note.toLowerCase().includes(lowerCaseText)
                        || account.fields.some(field => field.name.toLowerCase().includes(lowerCaseText))
                        || account.fields.some(field => field.value.toLowerCase().includes(lowerCaseText));
                });
            const listsMatch = filters.lists.length === 0 || filters.lists.some(listId => account.lists.some(list => list.id === listId));
            const unlistedMatch = filters.unlisted ? account.lists.length === 0 : true;
            return usernameMatch && freeTextMatch && listsMatch && unlistedMatch;
        });
    }
);

export const selectLoading = createSelector(
    applicationStateFeature,
    (state: ApplicationState) => state.listsLoading || state.listAccountsLoading || state.followingsLoading
);
