import { ChangeDetectionStrategy, Component, computed, Inject, untracked } from '@angular/core';
import { ReactiveFormsModule, UntypedFormGroup, Validators } from '@angular/forms';
import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog';
import { Justification } from '@red/domain';
import { JustificationsService } from '@services/entity-services/justifications.service';
import { BaseDialogComponent, CircleButtonComponent, HasScrollbarDirective, IconButtonComponent } from '@iqser/common-ui';
import { firstValueFrom } from 'rxjs';
import { TranslateModule } from '@ngx-translate/core';
import { formControlToSignal } from '@utils/functions';
import { toSignal } from '@angular/core/rxjs-interop';

interface DialogData {
    justification?: Justification;
    dossierTemplateId: string;
}

@Component({
    templateUrl: './add-edit-justification-dialog.component.html',
    changeDetection: ChangeDetectionStrategy.OnPush,
    standalone: true,
    imports: [TranslateModule, ReactiveFormsModule, IconButtonComponent, CircleButtonComponent, HasScrollbarDirective],
})
export class AddEditJustificationDialogComponent extends BaseDialogComponent {
    readonly form = this.#getForm();
    readonly name = formControlToSignal(this.form.controls['name']);
    readonly allJustifications = toSignal(this._justificationService.all$);
    readonly technicalName = computed(() => {
        if (this.data.justification) {
            return this.data.justification.technicalName;
        }
        if (!this.name()) {
            return null;
        }
        let currentTechnicalName = Justification.toTechnicalName(this.name());
        const existingTechnicalNames = untracked(this.allJustifications).map(justification => justification.technicalName);
        let suffix = 1;
        while (existingTechnicalNames.includes(currentTechnicalName)) {
            currentTechnicalName =
                currentTechnicalName === '_' ? `${currentTechnicalName}${suffix++}` : [currentTechnicalName, suffix++].join('_');
        }
        return currentTechnicalName;
    });

    constructor(
        private readonly _justificationService: JustificationsService,
        protected readonly _dialogRef: MatDialogRef<AddEditJustificationDialogComponent>,
        @Inject(MAT_DIALOG_DATA) readonly data: DialogData,
    ) {
        super(_dialogRef, !!data.justification);

        this.initialFormValue = this.form.getRawValue();
    }

    async save() {
        const dossierTemplateId = this.data.dossierTemplateId;
        this._loadingService.start();
        try {
            const formValue = { ...this.form.getRawValue(), technicalName: this.technicalName() };
            await firstValueFrom(this._justificationService.createOrUpdate(formValue as Justification, dossierTemplateId));
            await firstValueFrom(this._justificationService.loadAll(dossierTemplateId));
            this._dialogRef.close(true);
        } catch (error) {
            this._toaster.rawError(error.error.message);
        }
        this._loadingService.stop();
    }

    #getForm(): UntypedFormGroup {
        return this._formBuilder.group({
            name: [{ value: this.data.justification?.name, disabled: !!this.data.justification }, Validators.required],
            reason: [this.data.justification?.reason],
            description: [this.data.justification?.description],
            technicalName: [this.data.justification?.technicalName ?? null],
        });
    }
}
