import { inject, Injectable, NgZone } from '@angular/core';
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
import { getConfig, IqserPermissionsService } from '@iqser/common-ui';
import { BASE_HREF_FN } from '@iqser/common-ui/lib/utils';
import { AnnotationPermissions } from '@models/file/annotation.permissions';
import { AnnotationWrapper } from '@models/file/annotation.wrapper';
import { TranslateService } from '@ngx-translate/core';
import { IHeaderElement } from '@red/domain';
import { PermissionsService } from '@services/permissions.service';
import { REDAnnotationManager } from '../../pdf-viewer/services/annotation-manager.service';
import { AnnotationActionsService } from './annotation-actions.service';
import { FilePreviewStateService } from './file-preview-state.service';

@Injectable()
export class PdfAnnotationActionsService {
    readonly #permissionsService = inject(PermissionsService);
    readonly #state = inject(FilePreviewStateService);
    readonly #translateService = inject(TranslateService);
    readonly #ngZone = inject(NgZone);
    readonly #convertPath = inject(BASE_HREF_FN);
    readonly #annotationActionsService = inject(AnnotationActionsService);
    readonly #iqserPermissionsService = inject(IqserPermissionsService);
    readonly #annotationManager = inject(REDAnnotationManager);
    readonly #isDocumine = getConfig().IS_DOCUMINE;

    get(annotations: AnnotationWrapper[]): IHeaderElement[] {
        const availableActions: IHeaderElement[] = [];
        const permissions = this.#getAnnotationsPermissions(annotations);
        const sameType = annotations.every(a => a.type === annotations[0].type);

        // you can only resize one annotation at a time
        if (permissions.canResizeAnnotation) {
            const firstAnnotation = annotations[0];
            // if we already entered resize-mode previously
            if (firstAnnotation.id === this.#annotationManager.resizingAnnotationId) {
                const acceptResizeButton = this.#getButton('check', _('annotation-actions.resize-accept.label'), () =>
                    this.#annotationActionsService.acceptResize(firstAnnotation),
                );
                const cancelResizeButton = this.#getButton('close', _('annotation-actions.resize-cancel.label'), () =>
                    this.#annotationActionsService.cancelResize(firstAnnotation),
                );

                return this.#annotationManager.annotationHasBeenResized ? [acceptResizeButton, cancelResizeButton] : [cancelResizeButton];
            }

            const resizeButton = this.#getButton('resize', _('annotation-actions.resize.label'), () =>
                this.#annotationActionsService.resize(firstAnnotation),
            );

            availableActions.push(resizeButton);
        }

        const canEditRedactions =
            permissions.canChangeLegalBasis ||
            permissions.canRecategorizeAnnotation ||
            permissions.canForceHint ||
            permissions.canForceRedaction;
        const canEdit =
            annotations.length > 1
                ? this.#isDocumine
                    ? permissions.canEditAnnotations
                    : permissions.canEditHints || permissions.canEditImages || permissions.canEditAnnotations
                : canEditRedactions;
        if (canEdit) {
            const editButton = this.#getButton('edit', _('annotation-actions.edit-redaction.label'), () =>
                this.#annotationActionsService.editRedaction(annotations),
            );
            availableActions.push(editButton);
        }

        if (permissions.canAcceptRecommendation) {
            const acceptRecommendationButton = this.#getButton('check', _('annotation-actions.accept-recommendation.label'), () =>
                this.#annotationActionsService.convertRecommendationToAnnotation(annotations),
            );
            availableActions.push(acceptRecommendationButton);
        }

        if (permissions.canForceRedaction) {
            const forceRedactionButton = this.#getButton('thumb-up', _('annotation-actions.force-redaction.label'), () =>
                this.#annotationActionsService.forceAnnotation(annotations),
            );
            availableActions.push(forceRedactionButton);
        }

        if (permissions.canForceHint) {
            const forceHintButton = this.#getButton('thumb-up', _('annotation-actions.force-hint.label'), () =>
                this.#annotationActionsService.forceAnnotation(annotations, true),
            );
            availableActions.push(forceHintButton);
        }

        if (permissions.canRemoveRedaction && sameType) {
            const removeRedactionButton = this.#getButton('trash', _('annotation-actions.remove-annotation.remove-redaction'), () =>
                this.#annotationActionsService.removeRedaction(annotations, permissions),
            );
            availableActions.push(removeRedactionButton);
        }

        return availableActions;
    }

    #getButton(icon: string, title: string, action: () => void | Promise<void>): IHeaderElement {
        return {
            type: 'actionButton',
            img: this.#convertPath(`/assets/icons/general/${icon}.svg`),
            title: this.#translateService.instant(title),
            onClick: () => this.#ngZone.run(async () => action()),
        };
    }

    #getAnnotationsPermissions(annotations: AnnotationWrapper[]): AnnotationPermissions {
        const dossier = this.#state.dossier();
        const isApprover = this.#permissionsService.isApprover(dossier);
        const dictionaries = this.#state.dictionaries;
        const permissions = annotations.map(a => AnnotationPermissions.forUser(isApprover, a, dictionaries, this.#iqserPermissionsService));
        return AnnotationPermissions.reduce(permissions);
    }
}
