import { Component, inject, OnInit } from '@angular/core';
import { FormBuilder, FormControl } from '@angular/forms';
import { DetailsRadioOption, IconButtonTypes, IqserDialogComponent } from '@iqser/common-ui';
import { Dictionary, SuperTypes } from '@red/domain';
import { ActiveDossiersService } from '@services/dossiers/active-dossiers.service';
import { DictionaryService } from '@services/entity-services/dictionary.service';
import { JustificationsService } from '@services/entity-services/justifications.service';
import { firstValueFrom } from 'rxjs';
import { IMAGE_CATEGORIES } from '../../utils/constants';
import { getEditRedactionOptions, RedactOrHintOption } from '../../utils/dialog-options';
import { EditRedactionData, EditRedactResult } from '../../utils/dialog-types';
import { LegalBasisOption } from '../manual-redaction-dialog/manual-annotation-dialog.component';

@Component({
    templateUrl: './edit-redaction-dialog.component.html',
    styleUrls: ['./edit-redaction-dialog.component.scss'],
})
export class EditRedactionDialogComponent
    extends IqserDialogComponent<EditRedactionDialogComponent, EditRedactionData, EditRedactResult>
    implements OnInit
{
    readonly #dossier = inject(ActiveDossiersService).find(this.data.dossierId);
    readonly #applyToAllDossiers = this.data.applyToAllDossiers;
    readonly iconButtonTypes = IconButtonTypes;
    readonly redactedTexts?: string[];
    readonly isModifyDictionary: boolean;
    readonly isImage: boolean;
    readonly isManualRedaction: boolean;
    readonly isHint: boolean;
    readonly allRectangles = this.data.annotations.reduce((acc, a) => acc && a.rectangle, true);
    readonly showExtras: boolean;
    options: DetailsRadioOption<RedactOrHintOption>[] | undefined;
    legalOptions: LegalBasisOption[] = [];
    dictionaries: Dictionary[] = [];
    readonly form = this.#getForm();

    constructor(
        private readonly _justificationsService: JustificationsService,
        private readonly _dictionaryService: DictionaryService,
        private readonly _formBuilder: FormBuilder,
    ) {
        super();
        const annotations = this.data.annotations;
        this.isImage = annotations.reduce((acc, next) => acc && [...IMAGE_CATEGORIES, 'ocr'].includes(next.type), true);
        this.redactedTexts = !this.isImage ? annotations.map(annotation => annotation.value) : null;
        this.isModifyDictionary = annotations.every(annotation => annotation.isModifyDictionary);
        this.isManualRedaction = annotations.every(annotation => annotation.type === SuperTypes.ManualRedaction);
        this.isHint = annotations.every(annotation => annotation.isHint);
        this.showExtras = !(this.isImage || this.isHint);
    }

    get displayedDictionaryLabel() {
        const selectedDictionaryType = this.form.controls.type.value;
        if (selectedDictionaryType) {
            return this.dictionaries.find(d => d.type === selectedDictionaryType)?.label ?? null;
        }
        return null;
    }

    get disabled() {
        return this.form.invalid || (this.showExtras ? !this.form.controls.reason.value : false);
    }

    async ngOnInit() {
        this.#setTypes();
        const data = await firstValueFrom(this._justificationsService.loadAll(this.#dossier.dossierTemplateId));
        this.legalOptions = data.map(lbm => ({
            legalBasis: lbm.reason,
            description: lbm.description,
            label: lbm.name,
        }));

        const reason = this.legalOptions.find(o => o.legalBasis === this.data.annotations[0].legalBasis);
        const sameLegalBasis = this.data.annotations.every(annotation => annotation.legalBasis === reason?.legalBasis);
        this.form.patchValue({
            reason: sameLegalBasis ? reason : null,
        });

        this.legalOptions.sort((a, b) => a.label.localeCompare(b.label));
        this.initialFormValue = this.form.getRawValue();
    }

    typeChanged() {
        const selectedDictionaryType = this.form.controls.type.value;
        this.#setOptions(selectedDictionaryType);
    }

    save() {
        const value = this.form.value;
        this.close({
            legalBasis: value.reason?.legalBasis ?? '',
            section: value.section,
            comment: value.comment,
            type: value.type,
            value: this.allRectangles ? value.value : null,
        });
    }

    #setTypes() {
        this.dictionaries = this._dictionaryService.getEditableRedactionTypes(
            this.#dossier.dossierTemplateId,
            this.isImage,
            this.isHint,
            this.data.annotations.every(annotation => annotation.isOCR),
        );
    }

    #setOptions(type: string, reasonChanged = false) {
        const selectedDictionary = this.dictionaries.find(d => d.type === type);
        this.options = getEditRedactionOptions(
            this.#dossier.dossierName,
            this.#applyToAllDossiers,
            !!selectedDictionary?.dossierDictionaryOnly,
            this.isModifyDictionary,
        );
        this.form.patchValue(
            {
                option: !this.isModifyDictionary || reasonChanged ? this.options[0] : this.options[1],
            },
            { emitEvent: false },
        );
    }

    #getForm() {
        const sameType = this.data.annotations.every(annotation => annotation.type === this.data.annotations[0].type);
        const sameSection = this.data.annotations.every(annotation => annotation.section === this.data.annotations[0].section);
        return this._formBuilder.group({
            reason: new FormControl<LegalBasisOption>(null),
            comment: new FormControl<string>(null),
            type: new FormControl<string>(sameType ? this.data.annotations[0].type : null),
            section: new FormControl<string>(sameSection ? this.data.annotations[0].section : null),
            option: new FormControl<LegalBasisOption>(null),
            value: new FormControl<string>(this.allRectangles ? this.data.annotations[0].value : null),
        });
    }
}
