import { Directive, ViewChild } from '@angular/core';
import { AbstractDataFormComponent, FormSubmitEvent } from "@app/_components/_abstract/abstract-data-form-component";
import { FormGroup } from '@angular/forms';
import { ImageUploadComponent } from '@app/_components/image-upload/image-upload.component';
import { ImageUploadService } from '@app/_services/image-upload.service';
import { ModalStatus } from '@app/_helpers/modal.states';

@Directive()
export abstract class AbstractImageFormComponent<T extends { [key: string]: any }> extends AbstractDataFormComponent<T> {

    selectedFile: File | null = null;
    imageToDelete: string | null = null;

    @ViewChild('imageUpload') imageUpload!: ImageUploadComponent;

    constructor(
        protected imageUploadService: ImageUploadService,
        formGroup: FormGroup,
        createFunction: ((data: T) => any) | undefined,
        updateFunction: (id: string | number, data: T) => any,
        deleteFunction: (id: string | number) => any,
        protected imageIriControlName: string, // neuer Parameter
        protected imageDbIdPath: string,
        ...args: any[]
    ) {
        super(formGroup, createFunction, updateFunction, deleteFunction, ...args);

        this.submit.subscribe((event: FormSubmitEvent<T>) => {
            if (event.status === ModalStatus.Submitted) {
                this.resetImageStatus();
            }
        });
    }

    handleFileSelected(file: File): void {
        this.selectedFile = file;
    }

    handleFileDeleted(): void {
        // Speichere die aktuelle imageIri, um sie später zu löschen
        this.imageToDelete = this.form.get(this.imageIriControlName)?.value;

        // Aktualisiere den Formularwert
        const patchValue: any = {};
        patchValue[this.imageIriControlName] = null;
        this.form.patchValue(patchValue);

        // Falls eine Datei zum Hochladen ausgewählt wurde, entferne diese auch
        this.selectedFile = null;
    }

    resetImageStatus(): void {
        if (this.imageUpload) {
            this.imageUpload.reset();
        }

        // Zurücksetzen der temporären Variablen
        this.imageToDelete = null;
        this.selectedFile = null;
    }

    override onSubmit(): void {
        if (!this.form.valid) {
            return;
        }

        // Drei Fälle:
        // 1. Ein neues Bild wurde ausgewählt
        // 2. Ein bestehendes Bild soll gelöscht werden
        // 3. Keine Änderungen am Bild

        if (this.selectedFile && this.imageToDelete) {
            // Fall 1a: Ein neues Bild wurde ausgewählt UND ein altes soll gelöscht werden
            // Zuerst das alte Bild löschen, dann das neue hochladen
            const dbId = this.getNestedProperty(this.data, this.imageDbIdPath);
            if (dbId) {
                this.imageUploadService.deleteImage(dbId).subscribe({
                    next: (success) => {
                        // Altes Bild wurde gelöscht, jetzt neues hochladen
                        this.uploadNewFile();
                    },
                    error: () => {
                        // Fehlerbehandlung bereits im Service, trotzdem neues Bild hochladen
                        this.uploadNewFile();
                    }
                });
            } else {
                this.uploadNewFile();
            }
        } else if (this.selectedFile) {
            // Fall 1b: Nur ein neues Bild wurde ausgewählt (kein altes vorhanden)
            this.uploadNewFile();
        } else if (this.imageToDelete) {
            // Fall 2: Nur ein bestehendes Bild soll gelöscht werden
            const dbId = this.getNestedProperty(this.data, this.imageDbIdPath);
            this.imageUploadService.deleteImage(dbId).subscribe({
                next: (success) => {
                    this.imageToDelete = null;
                    super.onSubmit();
                },
                error: () => {
                    // Fehlerbehandlung bereits im Service
                    super.onSubmit();
                }
            });
        } else {
            // Fall 3: Keine Änderungen am Bild
            super.onSubmit();
        }
    }

    private uploadNewFile(): void {
        if (!this.selectedFile) return;

        this.imageUploadService.uploadImage(this.selectedFile).subscribe({
            next: (imageId) => {
                if (imageId) {
                    // Aktualisiere die Formulardaten mit dem neuen mediaObject
                    const patchValue: any = {};
                    patchValue[this.imageIriControlName] = imageId;
                    this.form.patchValue(patchValue);

                    // Rufe die übergeordnete Methode auf, um den Standard-Speicherprozess zu verarbeiten
                    super.onSubmit();
                } else {
                    this.submit.emit({
                        status: ModalStatus.Cancelled,
                        data: null
                    });
                }
            }
        });
    }

    protected getNestedProperty(obj: any, path: string): any {
        if (!obj || !path) return null;
        return path.split('.').reduce((o, p) => (o ? o[p] : null), obj);
    }
}