import { Injectable, inject } from '@angular/core';
import { HttpParams } from '@angular/common/http';
import { Observable } from 'rxjs';
import { map } from 'rxjs/operators';

import { ApiService } from '../api.service';
import {
    Jump,
    JumpByCategorie,
    JumpByDate,
    JumpByDay,
    JumpByModule,
    JumpFile,
    JumpList,
    JumpListConfig,
    JumpListFilters,
    JumpPageData,
    X2Data,
    SkydiverIdJumps,
} from '@models';

@Injectable({ providedIn: 'root' })
export class JumpsService {
    private apiService = inject(ApiService);

    private _apiDomain = '/skydive';

    query(config: JumpListConfig): Observable<JumpList> {
        // Convert any filters over to Angular's URLSearchParams
        /*
        const params: JumpListFilters = {
            date: config.filters.date,
            lieu: config.filters.lieu,
            oaci: config.filters.oaci,
            aeronef: config.filters.aeronef,
            imat: config.filters.imat,
            hauteur: config.filters.hauteur,
            voile: config.filters.voile,
            taille: config.filters.taille,
            categorie: config.filters.categorie,
            module: config.filters.module,
            participants: config.filters.participants,
            accessoires: config.filters.accessoires,
            zone: config.filters.zone,
            author: config.filters.author,
            limit: config.filters.limit,
            offset: config.filters.offset,
            numeroRangeStart: config.filters.numeroRangeStart!,
            numeroRangeEnd: config.filters.numeroRangeEnd!,
            tailleRangeStart: config.filters.tailleRangeStart!,
            tailleRangeEnd: config.filters.tailleRangeEnd!,
            participantsRangeStart: config.filters.participantsRangeStart!,
            participantsRangeEnd: config.filters.participantsRangeEnd!,
            hauteurRangeStart: config.filters.hauteurRangeStart!,
            hauteurRangeEnd: config.filters.hauteurRangeEnd!
        };
        */
        const params: JumpListFilters = {} as JumpListFilters;
        Object.assign(params, config.filters);
        return this.apiService.get(
            `${this._apiDomain}/jumps`,
            new HttpParams({ fromObject: <
                    {
                        [param: string]: string | number | boolean | readonly (string | number | boolean)[];
                    }
                >params }),
        );
    }

    get(slug: string): Observable<JumpPageData> {
        /* return this.apiService.get(`/jumps/${slug}`)
            .pipe(map(data => {
                return { jump: data.jump, prevJump: data.prevJump, nextJump: data.nextJump };
            })); */
        return this.apiService.get(`${this._apiDomain}/jumps/${slug}`);
    }

    getAll(): Observable<Array<Jump>> {
        return this.apiService.get(`${this._apiDomain}/jumps`).pipe(map((data) => data.jumps));
    }

    getAllByDate(): Observable<Array<JumpByDate>> {
        return this.apiService.get(`${this._apiDomain}/jumps/allByDate`).pipe(map((data) => data.jumps));
    }

    getAllByCategorie(): Observable<Array<JumpByCategorie>> {
        return this.apiService.get(`${this._apiDomain}/jumps/allByCategorie`).pipe(map((data) => data.jumps));
    }

    getAllByDay(config: JumpListConfig): Observable<Array<JumpByDay>> {
        const params: JumpListFilters = {} as JumpListFilters;
        Object.assign(params, config.filters);
        return this.apiService
            .get(
                `${this._apiDomain}/jumps/allByDay`,
                new HttpParams({ fromObject: <
                        {
                            [param: string]: string | number | boolean | readonly (string | number | boolean)[];
                        }
                    >params }),
            )
            .pipe(map((data) => data.days));
    }

    getAllByModule(): Observable<Array<JumpByModule>> {
        return this.apiService.get(`${this._apiDomain}/jumps/allByModule`).pipe(map((data) => data.jumps));
    }

    getAllFromSkydiverIdApi(config: JumpListConfig): Observable<SkydiverIdJumps> {
        const params: JumpListFilters = {} as JumpListFilters;
        Object.assign(params, config.filters);
        return this.apiService
            .get(
                `${this._apiDomain}/jumps/allFromSkydiverIdApi`,
                new HttpParams({ fromObject: <
                        {
                            [param: string]: string | number | boolean | readonly (string | number | boolean)[];
                        }
                    >params }),
            )
            .pipe(map((data) => data.jumps));
    }

    getLastJump(): Observable<Jump> {
        return this.apiService.get(`${this._apiDomain}/jumps/last`).pipe(map((data) => data.jump));
    }

    create(jump: Jump): Observable<Jump> {
        return this.apiService.post(`${this._apiDomain}/jumps/`, { jump: jump }).pipe(map((data) => data.jump));
    }

    update(jump: Jump): Observable<Jump> {
        return this.apiService
            .put(`${this._apiDomain}/jumps/${jump.slug}`, { jump: jump })
            .pipe(map((data) => data.jump));
    }

    destroy(slug: string): Observable<boolean> {
        return this.apiService.delete(`${this._apiDomain}/jumps/${slug}`).pipe(map((data) => data.deleted));
    }

    save(jump: Jump): Observable<Jump> {
        // If we're updating an existing jump
        if (jump.slug) {
            return this.apiService
                .put(`${this._apiDomain}/jumps/${jump.slug}`, { jump: jump })
                .pipe(map((data) => data.jump));

            // Otherwise, create a new jump
        } else {
            return this.apiService.post(`${this._apiDomain}/jumps/`, { jump: jump }).pipe(map((data) => data.jump));
        }
    }

    saveX2Data(slug: string, file: JumpFile, data: X2Data): Observable<Jump> {
        return this.apiService
            .post(`${this._apiDomain}/jumps/data/${slug}`, { file: file, data: data })
            .pipe(map((data) => data.jump));
    }

    saveFile(slug: string, file: JumpFile): Observable<JumpFile> {
        return this.apiService
            .post(`${this._apiDomain}/jumps/file/${slug}`, { file: file })
            .pipe(map((data) => data.file));
    }

    saveKml(slug: string, file: JumpFile): Observable<JumpFile> {
        return this.apiService
            .post(`${this._apiDomain}/jumps/kml/${slug}`, { file: file })
            .pipe(map((data) => data.file));
    }

    getAeronefs() {
        /*
        [
            {
                '$match': {
                'aeronef': 'Pilatus'
                }
            }, {
                '$group': {
                '_id': {
                    'Aeronef': '$aeronef', 
                    'Imat': '$imat'
                }, 
                'count': {
                    '$sum': 1
                }
                }
            }
        ]
        */
    }
}
