import { Component, OnInit } from '@angular/core';
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
import { FormBuilder, UntypedFormGroup } from '@angular/forms';
import { DetailsRadioOption, IconButtonTypes, IqserDialogComponent, IqserPermissionsService } from '@iqser/common-ui';
import { Dictionary, Dossier, IAddRedactionRequest } 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 { Roles } from '@users/roles';
import { tap } from 'rxjs/operators';
import { getRedactOrHintOptions, RedactOrHintOption, RedactOrHintOptions } from '../../utils/dialog-options';
import { AddHintData, AddHintResult } from '../../utils/dialog-types';

@Component({
    templateUrl: './add-hint-dialog.component.html',
    styleUrls: ['./add-hint-dialog.component.scss'],
})
export class AddHintDialogComponent extends IqserDialogComponent<AddHintDialogComponent, AddHintData, AddHintResult> implements OnInit {
    #applyToAllDossiers: boolean;
    readonly #dossier: Dossier;
    readonly #isRss = this._iqserPermissionsService.has(Roles.getRss);
    readonly roles = Roles;
    readonly iconButtonTypes = IconButtonTypes;
    readonly options: DetailsRadioOption<RedactOrHintOption>[];
    dictionaryRequest = false;
    dictionaries: Dictionary[] = [];
    form!: UntypedFormGroup;

    constructor(
        private readonly _justificationsService: JustificationsService,
        private readonly _activeDossiersService: ActiveDossiersService,
        private readonly _dictionaryService: DictionaryService,
        private readonly _iqserPermissionsService: IqserPermissionsService,
        private readonly _formBuilder: FormBuilder,
    ) {
        super();
        this.#dossier = _activeDossiersService.find(this.data.dossierId);
        this.#applyToAllDossiers = this.data.applyToAllDossiers ?? true;
        this.options = getRedactOrHintOptions(this.#dossier, this.#applyToAllDossiers, this.data.isApprover, false, true, this.#isRss);

        this.form = this.#getForm();

        this.form
            .get('option')
            .valueChanges.pipe(
                tap((option: DetailsRadioOption<RedactOrHintOption>) => {
                    this.dictionaryRequest = option.value === RedactOrHintOptions.IN_DOSSIER;
                    this.#setDictionaries();
                    this.#resetValues();
                }),
                takeUntilDestroyed(),
            )
            .subscribe();
    }

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

    get disabled() {
        return this.#isRss || !this.form.get('dictionary').value;
    }

    async ngOnInit(): Promise<void> {
        this.#setDictionaries();
        this.#resetValues();
    }

    extraOptionChanged(option: DetailsRadioOption<RedactOrHintOption>): void {
        this.#applyToAllDossiers = option.extraOption.checked;

        this.#setDictionaries();
        if (this.#applyToAllDossiers && this.form.get('dictionary').value) {
            const selectedDictionaryLabel = this.form.get('dictionary').value;
            const selectedDictionary = this.dictionaries.find(d => d.type === selectedDictionaryLabel);
            if (!selectedDictionary) {
                this.form.get('dictionary').setValue(null);
            }
        }
    }

    typeChanged() {
        if (!this.#applyToAllDossiers) {
            const selectedDictionaryType = this.form.get('dictionary').value;
            const selectedDictionary = this.dictionaries.find(d => d.type === selectedDictionaryType);
            this.options[1].extraOption.disabled = selectedDictionary.dossierDictionaryOnly;
        }
    }

    save(): void {
        this.#enhanceManualRedaction(this.data.manualRedactionEntryWrapper.manualRedactionEntry);
        const redaction = this.data.manualRedactionEntryWrapper.manualRedactionEntry;
        this.dialogRef.close({
            redaction,
            dictionary: this.dictionaries.find(d => d.type === this.form.get('dictionary').value),
        });
    }

    #setDictionaries() {
        this.dictionaries = this._dictionaryService.getAddHintDictionaries(
            this.#dossier.dossierTemplateId,
            !this.#applyToAllDossiers,
            this.dictionaryRequest,
        );
    }

    #getForm(): UntypedFormGroup {
        return this._formBuilder.group({
            selectedText: this.data?.manualRedactionEntryWrapper?.manualRedactionEntry?.value,
            comment: [null],
            dictionary: [null],
            option: [this.options[0]],
        });
    }

    #enhanceManualRedaction(addRedactionRequest: IAddRedactionRequest) {
        addRedactionRequest.reason = 'Dictionary Request';
        addRedactionRequest.type = this.form.get('dictionary').value;
        addRedactionRequest.section = null;
        addRedactionRequest.value = this.form.get('selectedText').value;

        const selectedType = this.dictionaries.find(d => d.type === addRedactionRequest.type);
        addRedactionRequest.addToDictionary = this.dictionaryRequest && !!selectedType?.hasDictionary;

        const commentValue = this.form.get('comment').value;
        addRedactionRequest.comment = commentValue ? { text: commentValue } : null;
        addRedactionRequest.addToAllDossiers = this.data.isApprover && this.dictionaryRequest && this.#applyToAllDossiers;
    }

    #resetValues() {
        this.#applyToAllDossiers = this.data.applyToAllDossiers ?? true;
        if (!this.#isRss) {
            this.options[1].extraOption.checked = this.#applyToAllDossiers;
        }
        this.form.get('dictionary').setValue(null);
    }
}
