import { Component, computed, Input, OnChanges } from '@angular/core';
import { CircleButtonComponent, getConfig, HelpModeService, IqserAllowDirective, 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';
import { SkippedService } from '../../services/skipped.service';
import { AsyncPipe, NgIf } from '@angular/common';
import { TranslateModule } from '@ngx-translate/core';

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'],
    standalone: true,
    imports: [CircleButtonComponent, NgIf, TranslateModule, AsyncPipe, IqserAllowDirective],
})
export class AnnotationActionsComponent implements OnChanges {
    #annotations: AnnotationWrapper[] = [];
    readonly #isDocumine = getConfig().IS_DOCUMINE;
    protected _annotationId = '';
    @Input() buttonType: AnnotationButtonType = AnnotationButtonTypes.default;
    @Input() tooltipPosition: 'before' | 'above' = 'before';
    @Input() canPerformAnnotationActions: boolean;
    @Input() alwaysVisible: boolean;
    @Input() actionsHelpModeKey: string;
    readonly roles = Roles;
    annotationPermissions: AnnotationPermissions;
    isImage = true;
    readonly isVisible = computed(() => {
        const hidden = this._annotationManager.hidden();
        return this.#annotations.reduce((acc, annotation) => !hidden.has(annotation.id) && acc, true);
    });

    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 skippedService: SkippedService,
        readonly annotationActionsService: AnnotationActionsService,
        readonly annotationReferencesService: AnnotationReferencesService,
    ) {}

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

    get isImageHint(): boolean {
        return this.annotations.every(annotation => annotation.IMAGE_HINT);
    }

    @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;
    }

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

    get canResize(): boolean {
        return this.#annotationChangesAllowed && this.annotationPermissions.canResizeAnnotation && this.annotations.length === 1;
    }

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

    get canForceRedaction() {
        return this.#annotationChangesAllowed && this.annotationPermissions.canForceRedaction;
    }

    get canForceHint() {
        return this.#annotationChangesAllowed && this.annotationPermissions.canForceHint;
    }

    get canAcceptRecommendation() {
        return this.#annotationChangesAllowed && this.annotationPermissions.canAcceptRecommendation;
    }

    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 hideSkipped() {
        return this.skippedService.hideSkipped() && this.annotations.some(a => a.isSkipped);
    }

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

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

    removeRedaction() {
        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() {
        if (this.resized) {
            return this.annotationActionsService.acceptResize(this.#annotations[0], this.annotationPermissions);
        }
    }

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

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

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

    get #annotationChangesAllowed() {
        return (!this.#isDocumine || !this._state.file().excludedFromAutomaticAnalysis) && !this.#somePending;
    }

    get #somePending() {
        return this.#annotations.some(a => a.pending);
    }
}
