import { Component, computed, Input, OnChanges } from '@angular/core';
import { getConfig, HelpModeService, IqserPermissionsService } from '@iqser/common-ui';
import { AnnotationPermissions } from '@models/file/annotation.permissions';
import { AnnotationWrapper } from '@models/file/annotation.wrapper';
import { PermissionsService } from '@services/permissions.service';
import { Roles } from '@users/roles';
import { REDAnnotationManager } from '../../../pdf-viewer/services/annotation-manager.service';
import { AnnotationActionsService } from '../../services/annotation-actions.service';
import { AnnotationReferencesService } from '../../services/annotation-references.service';
import { FilePreviewStateService } from '../../services/file-preview-state.service';
import { MultiSelectService } from '../../services/multi-select.service';
import { ViewModeService } from '../../services/view-mode.service';

export const AnnotationButtonTypes = {
    default: 'default',
    primary: 'primary',
} as const;

export type AnnotationButtonType = keyof typeof AnnotationButtonTypes;

@Component({
    selector: 'redaction-annotation-actions',
    templateUrl: './annotation-actions.component.html',
    styleUrls: ['./annotation-actions.component.scss'],
})
export class AnnotationActionsComponent implements OnChanges {
    @Input() buttonType: AnnotationButtonType = AnnotationButtonTypes.default;
    @Input() tooltipPosition: 'before' | 'above' = 'before';
    @Input() canPerformAnnotationActions: boolean;
    @Input() alwaysVisible: boolean;
    readonly roles = Roles;
    annotationPermissions: AnnotationPermissions;
    isImage = true;
    protected _annotationId = '';
    #annotations: AnnotationWrapper[] = [];
    readonly isVisible = computed(() => {
        const hidden = this._annotationManager.hidden();
        return this.#annotations.reduce((acc, annotation) => !hidden.has(annotation.id) && acc, true);
    });
    readonly #isDocumine = getConfig().IS_DOCUMINE;

    constructor(
        readonly viewModeService: ViewModeService,
        readonly helpModeService: HelpModeService,
        readonly multiSelectService: MultiSelectService,
        private readonly _state: FilePreviewStateService,
        private readonly _permissionsService: PermissionsService,
        private readonly _iqserPermissionsService: IqserPermissionsService,
        private readonly _annotationManager: REDAnnotationManager,
        readonly annotationActionsService: AnnotationActionsService,
        readonly annotationReferencesService: AnnotationReferencesService,
    ) {}

    get annotations(): AnnotationWrapper[] {
        return this.#annotations;
    }

    get canEdit(): boolean {
        const canEditRedactions =
            this.annotationPermissions.canChangeLegalBasis ||
            this.annotationPermissions.canRecategorizeAnnotation ||
            this.annotationPermissions.canForceHint ||
            this.annotationPermissions.canForceRedaction;
        return this.annotations.length > 1
            ? this.#isDocumine
                ? this.annotationPermissions.canEditAnnotations
                : this.annotationPermissions.canEditHints ||
                  this.annotationPermissions.canEditImages ||
                  this.annotationPermissions.canEditAnnotations
            : canEditRedactions;
    }

    get canRemoveRedaction(): boolean {
        return this.annotationPermissions.canRemoveRedaction && this.#sameType;
    }

    get viewerAnnotations() {
        return this._annotationManager.get(this.#annotations);
    }

    get resizing() {
        return this.#annotations?.length === 1 && this.#annotations?.[0].id === this._annotationManager.resizingAnnotationId;
    }

    get resized() {
        return this._annotationManager.annotationHasBeenResized;
    }

    get #sameType() {
        const type = this.annotations[0].superType;
        return this.annotations.every(a => a.superType === type);
    }

    @Input()
    set annotations(annotations: AnnotationWrapper[]) {
        this.#annotations = annotations.filter(a => a !== undefined);
        this.isImage = this.#annotations?.reduce((accumulator, annotation) => annotation.isImage && accumulator, true);
        this._annotationId = this.#annotations[0]?.id;
    }

    ngOnChanges(): void {
        this.#setPermissions();
    }

    removeOrSuggestRemoveRedaction() {
        this.annotationActionsService.removeRedaction(this.annotations, this.annotationPermissions);
    }

    acceptRecommendation() {
        return this.annotationActionsService.convertRecommendationToAnnotation(this.annotations);
    }

    hideAnnotation() {
        this._annotationManager.hide(this.viewerAnnotations);
        this._annotationManager.deselect();
        this._annotationManager.addToHidden(this.viewerAnnotations[0].Id);
    }

    showAnnotation() {
        this._annotationManager.show(this.viewerAnnotations);
        this._annotationManager.deselect();
        this._annotationManager.removeFromHidden(this.viewerAnnotations[0].Id);
    }

    resize() {
        return this.annotationActionsService.resize(this.#annotations[0]);
    }

    acceptResize() {
        return this.annotationActionsService.acceptResize(this.#annotations[0]);
    }

    cancelResize() {
        return this.annotationActionsService.cancelResize(this.#annotations[0]);
    }

    helpModeKey(action: string) {
        return this.#isDocumine ? `${action}_annotation` : '';
    }

    #setPermissions() {
        this.annotationPermissions = AnnotationPermissions.forUser(
            this._permissionsService.isApprover(this._state.dossier()),
            this.#annotations,
            this._state.dictionaries,
            this._iqserPermissionsService,
        );
    }
}
