import { Base } from './base.model';
import { UntypedFormBuilder, Validators, UntypedFormGroup } from '@angular/forms';
import { HttpClient } from '@angular/common/http';
import { environment } from 'src/environments/environment';
import { map } from 'rxjs';
import { Record } from 'src/app/models/record.model';

export enum LayerType {
    Import,
    Processed,
    Administration,
    Dictionary
}

export class Layer extends Base {
    // eslint-disable-next-line @typescript-eslint/ban-types
    number?: Number;
    source?: string;
    name?: string;
    records: Record[] = [];
    created?: string;
    modified?: string;
    type?: LayerType;
    isCancelled: boolean = false;

    constructor(data: Partial<Layer> = {}) {
        super();
        Object.assign(this, data);
    }
    // eslint-disable-next-line @typescript-eslint/no-explicit-any
    override deserialize(input: any): this {
        Object.assign(this, Object.assign(this, super.deserialize(input)));
        if (this.records) { this.records = this.records.map(x => new Record().deserialize(x)); }
        return this;
    }
    override serialize() {
        this.number = 0; // will be overrided in backend
        return Object.assign({}, this);
    }
    static getForm(fb: UntypedFormBuilder) {
        return fb.group({
            id: [null],
            name: ['', Validators.required],
            source: ['', Validators.required],
            sheetId: '',
            createdAt: '',
            modifiedAt: '',
            createdBy: '',
            modifiedBy: '',
            modified: '',
            created: ''
        });
    }
    fillForm(form: UntypedFormGroup) {
        form.patchValue(this);
        form.patchValue({
            createdBy: this.createdBy?.userName,
            modifiedBy: this.modifiedBy?.userName
        });
    }
    loadForm(form: UntypedFormGroup) {
        for (const field of Object.keys(form.controls)) {
            console.log(field);
            //this[field as keyof Layer] = form.controls[field].value;
        }
        this.createdBy = undefined;
        this.modifiedBy = undefined;
    }
    //API Actions 
    static add(input: Layer, _http: HttpClient): Promise<string> {
        return new Promise((resolve, reject) => {
            _http.post<string>(`${environment.api.url}/layers`, { ...input.serialize(), }).subscribe({
                next: (data) => resolve(data),
                error: (e) => reject(e)
            }
            );
        });
    }
    // eslint-disable-next-line @typescript-eslint/no-explicit-any
    static getList(_http: HttpClient, start: number, limit: number, name: string, type: LayerType | ''): any {
        return new Promise((resolve, reject) => {
            _http.get<Layer[]>(`${environment.api.url}/layers?start=${start}&limit=${limit}&name=${name}&type=${type}`)
                .pipe(map(data => data.map(x => new Layer().deserialize(x))))
                .subscribe({
                    next: (data) => resolve(data),
                    error: (e) => reject(e)
                })
        });
    }
    static getById(id: string, _http: HttpClient): Promise<Layer> {
        return new Promise((resolve, reject) => {
            _http.get<Layer>(`${environment.api.url}/layers/${id}`).pipe(map(x => new Layer().deserialize(x))).subscribe({
                next: (data) => resolve(data),
                error: (e) => reject(e)
            })
        });
    }
    static parseFile(file: File, _http: HttpClient): Promise<Layer[]> {
        const formData = new FormData();
        formData.append(file.name, file);
        return new Promise((resolve, reject) => {
            _http.post<Layer[]>(`${environment.api.url}/layers/parseFile`, formData,
            ).pipe(map(data => data.map(x => new Layer().deserialize(x))))
                .subscribe({
                    next: (data) => {
                        resolve(data);
                    },
                    error: (e) => reject(e)
                })
        })
    }
    static parseGoogleSheet(sheetId: string, _http: HttpClient): Promise<Layer> {
        return new Promise((resolve, reject) => {
            _http.get<Layer>(`${environment.api.url}/layers/parseGoogleSheet/${sheetId}`,
            ).pipe(map(data => new Layer().deserialize(data)))
                .subscribe({
                    next: (data) => {
                        resolve(data);
                    },
                    error: (e) => reject(e)
                })
        })
    }
    static exportToGoogleSheet(id: string, _http: HttpClient): Promise<boolean> {
        return new Promise((resolve, reject) => {
            _http.get<boolean>(`${environment.api.url}/layers/exportToGoogleSheet/${id}`,
            ).subscribe({
                next: (data) => {
                    resolve(data);
                },
                error: (e) => reject(e)
            })
        })
    }
    static processLayer(id: string, _http: HttpClient): Promise<boolean> {
        return new Promise((resolve, reject) => {
            _http.get<boolean>(`${environment.api.url}/layers/processLayer/${id}`,
            ).subscribe({
                next: (data) => {
                    resolve(data);
                },
                error: (e) => reject(e)
            })
        })
    }
}