import { Component, inject, Input, OnChanges } from '@angular/core';
import { AnnotationWrapper } from '@models/file/annotation.wrapper';
import { TranslateService } from '@ngx-translate/core';
import { annotationChangesTranslations } from '@translations/annotation-changes-translations';
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
import { ListItem } from '@models/file/list-item';
import { MultiSelectService } from '../../services/multi-select.service';
import { KeysOf } from '@iqser/common-ui/lib/utils';

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

const Engines = {
    DICTIONARY: 'DICTIONARY',
    NER: 'NER',
    RULE: 'RULE',
} as const;

type EngineName = keyof typeof Engines;

function isBasedOn(annotation: AnnotationWrapper, engineName: EngineName) {
    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'],
})
export class AnnotationDetailsComponent implements OnChanges {
    private readonly _translateService = inject(TranslateService);
    private readonly _multiSelectService = inject(MultiSelectService);
    @Input() annotation: ListItem<AnnotationWrapper>;
    isPopoverOpen = false;
    engines: Engine[];
    changesTooltip: string;
    noSelection: boolean;

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

        if (!changes.length) {
            return;
        }

        const header = this._translateService.instant(_('annotation-changes.header'));
        const details = changes.map(change => this._translateService.instant(annotationChangesTranslations[change]));
        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, Engines.DICTIONARY),
                translateParams: { isHint: annotation.hint },
            },
            {
                icon: 'red:ai',
                description: _('annotation-engines.ner'),
                show: isBasedOn(annotation, Engines.NER),
            },
            {
                icon: 'red:rule',
                description: _('annotation-engines.rule'),
                show: isBasedOn(annotation, Engines.RULE),
                translateParams: { rule: annotation.legalBasisValue || '' },
            },
        ];
    }
}
