import {Directive, EventEmitter, Input, Output, OnInit, AfterViewInit} from '@angular/core';
import { FormGroup } from '@angular/forms';
import { Observable } from 'rxjs';
import { Router } from '@angular/router';
import { TranslateService } from '@ngx-translate/core';
import {ModalStatus} from "@app/_helpers/modal.states";

export type SaveFunction<T> = (item: T) => Observable<T>;
export type UpdateFunction<T> = (id: string | number, item: T) => Observable<T>;
export type DeleteFunction = (id: string | number) => Observable<any>;

export enum FormMode {
    Create = 'create',
    Edit = 'edit'
}

export interface FormSubmitEvent<T> {
    status: ModalStatus;
    data: T | null;
}

@Directive()
export abstract class AbstractDataFormComponent<T extends { [key: string]: any }> implements OnInit, AfterViewInit {
    @Input() data?: T;
    @Input() mode: FormMode = FormMode.Create;
    @Input() id?: string | number;
    @Input() redirectAfterDelete?: string;
    @Output() submit = new EventEmitter<FormSubmitEvent<T>>();
    @Output() deleted: EventEmitter<void> = new EventEmitter<void>();
    protected form!: FormGroup;

    constructor(
        protected formConfig: FormGroup,
        protected createFn?: SaveFunction<T>,
        protected updateFn?: UpdateFunction<T>,
        protected deleteFn?: DeleteFunction,
        protected translateService?: TranslateService,
        protected router?: Router
    ) {
        this.form = formConfig;
    }

    ngOnInit(): void {
        this.form.reset();

        if (this.data) {
            this.form.patchValue(this.data);
        } else if (this.mode === FormMode.Create) {
            this.data = this.getNewDataSet();
            this.form.patchValue(this.data);
        }
    }

    ngAfterViewInit() {
    }

    protected getNewDataSet(): T {
        return {} as T;
    }

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

        const formData = this.form.value as T;
        const request$ = this.mode === FormMode.Create
            ? (this.createFn ? this.createFn(formData) : undefined)
            : (this.updateFn ? this.updateFn(this.id!, formData) : undefined);

        if (request$ !== undefined) {
            request$.subscribe({
                next: (response) => {
                    this.data = response;
                    this.submit.emit({
                        status: ModalStatus.Submitted,
                        data: response
                    });
                },
                error: (error) => {
                    console.error('Error saving data:', error);
                    this.submit.emit({
                        status: ModalStatus.Cancelled,  // Statt Error verwenden wir Cancelled
                        data: null
                    });
                }
            });
        }
    }

    onDelete(): void {
        if (!this.isEditMode() || !this.deleteFn || !this.id || !this.translateService) {
            return;
        }

        this.translateService.get('basic.delete_confirm_related').subscribe((confirmMessage: string) => {
            if (confirm(confirmMessage)) {
                this.deleteFn!(this.id!).subscribe({
                    next: () => {
                        this.deleted.emit();
                        if (this.redirectAfterDelete && this.router) {
                            this.router.navigate([this.redirectAfterDelete]);
                        }
                    },
                    error: (error) => {
                        console.error('Error deleting data:', error);
                    }
                });
            }
        });
    }

    onDateChange(newDate: any, fieldName: string) {
        if (typeof newDate === 'string' || newDate === null) {
            this.form.patchValue({ [fieldName]: newDate });
        }
    }

    isEditMode(): boolean {
        return this.mode === FormMode.Edit;
    }
}