import { Component, Input, OnInit, ViewChild } from '@angular/core';
import { LoadingService } from '@iqser/common-ui';
import { List } from '@iqser/common-ui/lib/utils';
import { Dictionary, DictionaryEntryType, DictionaryEntryTypes, Dossier } from '@red/domain';
import { DictionaryService } from '@services/entity-services/dictionary.service';
import { PermissionsService } from '@services/permissions.service';
import { DictionaryManagerComponent } from '@shared/components/dictionary-manager/dictionary-manager.component';
import { firstValueFrom } from 'rxjs';
import { DossiersDialogService } from '../../../services/dossiers-dialog.service';
import { EditDossierSaveResult } from '../edit-dossier-section.interface';

@Component({
    selector: 'redaction-edit-dossier-dictionary',
    templateUrl: './edit-dossier-dictionary.component.html',
    styleUrls: ['./edit-dossier-dictionary.component.scss'],
})
export class EditDossierDictionaryComponent implements OnInit {
    @ViewChild(DictionaryManagerComponent, { static: false }) private readonly _dictionaryManager: DictionaryManagerComponent;
    @Input() dossier: Dossier;
    canEdit = false;
    dictionaries: Dictionary[];
    selectedDictionary: Dictionary;
    activeEntryType = DictionaryEntryTypes.ENTRY;
    entriesToDisplay: List = [];
    readonly entryTypes = DictionaryEntryTypes;

    constructor(
        private readonly _dictionaryService: DictionaryService,
        private readonly _permissionsService: PermissionsService,
        private readonly _loadingService: LoadingService,
        private readonly _dialogService: DossiersDialogService,
    ) {}

    get changed(): boolean {
        return this._dictionaryManager?.editor.hasChanges;
    }

    get disabled(): boolean {
        return !this.canEdit;
    }

    get valid(): boolean {
        return this._dictionaryManager?.editor.hasChanges;
    }

    async ngOnInit() {
        this._loadingService.start();
        this.canEdit = this._permissionsService.canEditDossierDictionary(this.dossier);
        await this.#updateDossierDictionary();
        this._loadingService.stop();
    }

    async save(): EditDossierSaveResult {
        try {
            await this._dictionaryService.saveEntries(
                this._dictionaryManager.editor.currentEntries,
                this._dictionaryManager.initialEntries,
                this.dossier.dossierTemplateId,
                this.selectedDictionary.type,
                this.dossier.id,
                false,
                this.activeEntryType,
            );

            await this.#updateDossierDictionary();
            return { success: true };
        } catch (error) {
            return { success: false };
        }
    }

    revert() {
        this._dictionaryManager.revert();
    }

    selectDictionary(dictionary: Dictionary, entryType?: DictionaryEntryType) {
        this.selectedDictionary = dictionary;
        this.selectEntryType(entryType);
    }

    selectEntryType(selectedEntryType: DictionaryEntryType) {
        this.activeEntryType = selectedEntryType ?? this.activeEntryType;
        const entryType = this.selectedDictionary.hint ? DictionaryEntryTypes.ENTRY : this.activeEntryType;

        switch (entryType) {
            case DictionaryEntryTypes.ENTRY: {
                this.entriesToDisplay = this.selectedDictionary.entries;
                break;
            }
            case DictionaryEntryTypes.FALSE_POSITIVE: {
                this.entriesToDisplay = this.selectedDictionary.falsePositiveEntries;
                break;
            }
            case DictionaryEntryTypes.FALSE_RECOMMENDATION: {
                this.entriesToDisplay = this.selectedDictionary.falseRecommendationEntries;
                break;
            }
        }

        this.entriesToDisplay = this.#toString([...this.entriesToDisplay]);
    }

    async #updateDossierDictionary() {
        const { dossierId, dossierTemplateId } = this.dossier;
        let dictionaryTypes = [
            ...this._dictionaryService.getRedactTextDictionaries(dossierTemplateId, true),
            ...this._dictionaryService.getAddHintDictionaries(dossierTemplateId, false, true),
        ].map(d => d.type);
        dictionaryTypes = [...new Set(dictionaryTypes)];
        this.dictionaries = await firstValueFrom(
            this._dictionaryService.loadDictionaryEntriesByType(dictionaryTypes, dossierTemplateId, dossierId),
        );
        //TODO remove this when backend will send also the type
        this.#setType(dictionaryTypes);
        this.dictionaries = this.dictionaries.sort((a, b) => a.label.localeCompare(b.label));
        let dictionaryToSelect = this.dictionaries[0];
        if (this.selectedDictionary) {
            dictionaryToSelect = this.dictionaries.find(d => d.type === this.selectedDictionary.type);
        }
        this.selectDictionary(dictionaryToSelect, this.activeEntryType);
    }

    //TODO remove this when backend will send also the type
    #setType(dictionaryTypes: string[]) {
        for (let i = 0; i < this.dictionaries.length; i++) {
            const { ...dictionaryWithType } = this.dictionaries[i];
            dictionaryWithType.type = dictionaryTypes[i];
            this.dictionaries[i] = dictionaryWithType as Dictionary;
        }
    }

    #toString(entries: string[]) {
        return entries.sort((a, b) => a.localeCompare(b, undefined, { sensitivity: 'accent' }));
    }
}
