import { AnnotationWrapper } from './annotation.wrapper';
import { Dictionary } from '@red/domain';
import { isArray } from 'lodash-es';
import { IqserPermissionsService } from '@iqser/common-ui';
import { Roles } from '@users/roles';
import {
    canAcceptRecommendation,
    canAcceptSuggestion,
    canChangeLegalBasis,
    canForceHint,
    canForceRedaction,
    canMarkAsFalsePositive,
    canRecategorizeImage,
    canRejectSuggestion,
    canRemoveOrSuggestToRemoveFromDictionary,
    canRemoveOrSuggestToRemoveOnlyHere,
    canRemoveOrSuggestToRemoveRedaction,
    canResizeAnnotation,
    canUndo,
} from './annotation-permissions.utils';

export class AnnotationPermissions {
    canUndo = true;
    canAcceptRecommendation = true;
    canMarkAsFalsePositive = true;
    canRemoveOrSuggestToRemoveOnlyHere = true;
    canRemoveOrSuggestToRemoveFromDictionary = true;
    canRemoveOrSuggestToRemoveRedaction = true;
    canAcceptSuggestion = true;
    canRejectSuggestion = true;
    canForceRedaction = true;
    canChangeLegalBasis = true;
    canResizeAnnotation = true;
    canRecategorizeImage = true;
    canForceHint = true;

    static forUser(
        isApprover: boolean,
        annotations: AnnotationWrapper | AnnotationWrapper[],
        entities: Dictionary[],
        permissionsService: IqserPermissionsService,
    ) {
        if (!isArray(annotations)) {
            annotations = [annotations];
        }

        const summedPermissions: AnnotationPermissions = new AnnotationPermissions();
        const canAddRedaction = permissionsService.has(Roles.redactions.write);
        const canRequestRedaction = permissionsService.has(Roles.redactions.request);
        const canProcessManualRedaction = permissionsService.has(Roles.redactions.processManualRequest);
        const canAddOrRequestRedaction = canAddRedaction || canRequestRedaction;

        for (const annotation of annotations) {
            const permissions: AnnotationPermissions = new AnnotationPermissions();
            const annotationEntity = entities.find(entity => entity.type === annotation.type);

            permissions.canUndo = canUndo(annotation, isApprover);
            permissions.canAcceptSuggestion = canAcceptSuggestion(annotation, isApprover, canProcessManualRedaction);
            permissions.canRejectSuggestion = canRejectSuggestion(annotation, isApprover, canProcessManualRedaction);
            permissions.canForceHint = canForceHint(annotation, canAddOrRequestRedaction);
            permissions.canForceRedaction = canForceRedaction(annotation, canAddOrRequestRedaction);
            permissions.canAcceptRecommendation = canAcceptRecommendation(annotation);
            permissions.canMarkAsFalsePositive = canMarkAsFalsePositive(annotation, annotationEntity);
            permissions.canRemoveOrSuggestToRemoveOnlyHere = canRemoveOrSuggestToRemoveOnlyHere(annotation, canAddOrRequestRedaction);
            permissions.canRemoveOrSuggestToRemoveFromDictionary = canRemoveOrSuggestToRemoveFromDictionary(annotation);
            permissions.canRemoveOrSuggestToRemoveRedaction = canRemoveOrSuggestToRemoveRedaction(annotations, permissions);
            permissions.canChangeLegalBasis = canChangeLegalBasis(annotation, canAddOrRequestRedaction);
            permissions.canRecategorizeImage = canRecategorizeImage(annotation);
            permissions.canResizeAnnotation = canResizeAnnotation(annotation, canAddOrRequestRedaction);

            summedPermissions._merge(permissions);
        }
        return summedPermissions;
    }

    private _merge(permissions: AnnotationPermissions) {
        for (const key of Object.keys(this)) {
            if (typeof this[key] === 'boolean') {
                this[key] = this[key] && permissions[key];
            }
        }
    }
}
