import { Dossier, File, User, UserType } from '@red/domain';
import { handleCheckedValue, INestedFilter } from '@iqser/common-ui/lib/filtering';

export function handleFilterDelta(oldFilters: INestedFilter[], newFilters: INestedFilter[], allFilters: INestedFilter[]) {
    const newFiltersDelta = {};
    for (const newFilter of newFilters) {
        const oldFilter = oldFilters.find(f => f.id === newFilter.id);

        if (!oldFilter) {
            newFiltersDelta[newFilter.id] = {};
            newFilter.children.forEach(filter => (newFiltersDelta[newFilter.id][filter.id] = {}));
            continue;
        }

        if (oldFilter.matches < newFilter.matches) {
            newFiltersDelta[newFilter.id] = {};
        }

        for (const childFilter of newFilter.children) {
            const oldFilterChild = oldFilter.children.find(f => f.id === childFilter.id);
            if (!oldFilterChild || oldFilterChild.matches < childFilter.matches) {
                if (!newFiltersDelta[newFilter.id]) {
                    newFiltersDelta[newFilter.id] = {};
                }
                newFiltersDelta[newFilter.id][childFilter.id] = {};
            }
        }
    }

    for (const key of Object.keys(newFiltersDelta)) {
        const foundFilter = allFilters.find(f => f.id === key);
        if (foundFilter) {
            // if has children
            if (!foundFilter.children?.length) {
                foundFilter.checked = true;
            } else {
                for (const subKey of Object.keys(newFiltersDelta[key])) {
                    const childFilter = foundFilter.children.find(f => f.id === subKey);
                    if (childFilter) {
                        childFilter.checked = true;
                    }
                }
            }
        }
    }

    allFilters.forEach(handleCheckedValue);
}

export const annotationFilterChecker = (file: File, filter: INestedFilter, currentUserId: string) => {
    switch (filter.id) {
        case 'analysis': {
            return file.analysisRequired;
        }
        case 'suggestion': {
            return file.hasSuggestions;
        }
        case 'redaction': {
            return file.hasRedactions;
        }
        case 'hint': {
            return file.hintsOnly;
        }
        case 'none': {
            return file.hasNone;
        }
        case 'updated': {
            return file.hasUpdates && file.assignee === currentUserId && !file.isApproved;
        }
        case 'image': {
            return file.hasImages;
        }
        case 'comment': {
            return file.hasAnnotationComments;
        }
    }
};

export const dossierMemberChecker = (dw: Dossier, filter: INestedFilter) => dw.hasMember(filter.id);

export const dossierOwnerQuickChecker = (userId: string) => (dw: Dossier) => dw.ownerId === userId;

export const dossierMemberQuickChecker = (userId: string) => (dw: Dossier) => dw.hasMember(userId);

export const dossierTemplateChecker = (dw: Dossier, filter: INestedFilter) => dw.dossierTemplateId === filter.id;

export const dossierStateChecker = (dw: Dossier, filter: INestedFilter) =>
    dw.dossierStatusId === (filter.id === 'undefined' ? null : filter.id);

export const userTypeFilters: { [key in UserType]: (user: User) => boolean } = {
    INACTIVE: (user: User) => !user.hasAnyRole,
    REGULAR: (user: User) => user.roles.length === 1 && user.roles[0] === 'RED_USER',
    RED_MANAGER: (user: User) => user.isManager && !user.isAdmin,
    MANAGER_ADMIN: (user: User) => user.isManager && user.isAdmin,
    RED_USER_ADMIN: (user: User) => user.isUserAdmin && !user.isAdmin,
    RED_ADMIN: (user: User) => user.isAdmin && !user.isManager,
};

export const userTypeChecker = (user: User, filter: INestedFilter) => userTypeFilters[filter.id](user);
