import { Component, inject, Input, OnChanges } from '@angular/core';
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
import { KeysOf } from '@iqser/common-ui/lib/utils';
import { AnnotationWrapper } from '@models/file/annotation.wrapper';
import { ListItem } from '@models/file/list-item';
import { TranslateModule, TranslateService } from '@ngx-translate/core';
import { annotationChangesTranslations } from '@translations/annotation-changes-translations';
import { MultiSelectService } from '../../services/multi-select.service';
import { LogEntryEngine, LogEntryEngines } from '@red/domain';
import { NgForOf, NgIf } from '@angular/common';
import { MatTooltip } from '@angular/material/tooltip';
import { MatIcon } from '@angular/material/icon';
import { CdkConnectedOverlay, CdkOverlayOrigin } from '@angular/cdk/overlay';

interface Engine {
    readonly icon: string;
    readonly description: string;
    readonly show: boolean;
    readonly translateParams?: Record<string, any>;
}

function isBasedOn(annotation: AnnotationWrapper, engineName: LogEntryEngine) {
    return !!annotation.engines?.includes(engineName);
}

const changesProperties: KeysOf<AnnotationWrapper>[] = [
    'hasBeenResized',
    'hasBeenRecategorized',
    'hasLegalBasisChanged',
    'hasBeenRemovedByManualOverride',
    'hasBeenForcedRedaction',
    'hasBeenForcedHint',
];

@Component({
    selector: 'redaction-annotation-details [annotation]',
    templateUrl: './annotation-details.component.html',
    styleUrls: ['./annotation-details.component.scss'],
    standalone: true,
    imports: [NgIf, MatTooltip, MatIcon, CdkOverlayOrigin, NgForOf, CdkConnectedOverlay, TranslateModule],
})
export class AnnotationDetailsComponent implements OnChanges {
    @Input() annotation: ListItem<AnnotationWrapper>;
    isPopoverOpen = false;
    engines: Engine[];
    changesTooltip: string;
    noSelection: boolean;
    private readonly _translateService = inject(TranslateService);
    private readonly _multiSelectService = inject(MultiSelectService);

    getChangesTooltip(): string | undefined {
        const changes = changesProperties.filter(key => this.annotation.item[key]);

        if (!changes.length && !this.annotation.item.engines?.includes(LogEntryEngines.MANUAL)) {
            return;
        }

        const details = [];
        if (this.annotation.item.engines?.includes(LogEntryEngines.MANUAL)) {
            details.push(this._translateService.instant(_('annotation-changes.added-locally')));
        }

        if (changes.length) {
            details.push(...changes.map(change => this._translateService.instant(annotationChangesTranslations[change])));
        }

        const header = this._translateService.instant(_('annotation-changes.header'));
        return [header, ...details.map(change => `• ${change}`)].join('\n');
    }

    ngOnChanges() {
        this.engines = this.#extractEngines(this.annotation.item).filter(engine => engine.show);
        this.changesTooltip = this.getChangesTooltip();
        this.noSelection = !this.annotation.isSelected || this._multiSelectService.inactive();
    }

    #extractEngines(annotation: AnnotationWrapper): Engine[] {
        return [
            {
                icon: 'red:dictionary',
                description: _('annotation-engines.dictionary'),
                show: isBasedOn(annotation, LogEntryEngines.DICTIONARY),
                translateParams: { isHint: annotation.HINT },
            },
            {
                icon: 'red:folder',
                description: _('annotation-engines.dossier-dictionary'),
                show: isBasedOn(annotation, LogEntryEngines.DOSSIER_DICTIONARY),
            },
            {
                icon: 'red:ai',
                description: _('annotation-engines.ner'),
                show: isBasedOn(annotation, LogEntryEngines.NER),
            },
            {
                icon: 'red:rule',
                description: _('annotation-engines.rule'),
                show: isBasedOn(annotation, LogEntryEngines.RULE),
                translateParams: { rule: annotation.legalBasisValue || '' },
            },
            {
                icon: 'red:import_redactions',
                description: _('annotation-engines.imported'),
                show: isBasedOn(annotation, LogEntryEngines.IMPORTED),
            },
        ];
    }
}
