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 { Article, ArticleList, ArticleListConfig, ArticleListFilters, ArticlePageData } from '@models';

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

    private _apiDomain = '/cms';

    query(config: ArticleListConfig): Observable<ArticleList> {
        // Convert any filters over to Angular's URLSearchParams
        const params: ArticleListFilters = {} as ArticleListFilters;
        Object.assign(params, config.filters);
        return this.apiService.get(
            `${this._apiDomain}/articles` + (config.type === 'feed' ? '/feed' : ''),
            new HttpParams({ fromObject: <
                    {
                        [param: string]: string | number | boolean | readonly (string | number | boolean)[];
                    }
                >params }),
        );
    }

    get(slug: string): Observable<ArticlePageData> {
        /*return this.apiService.get(`${this._apiDomain}/articles/${slug}`).pipe(map(data => {
            data.article.tagList = data.article.tagNameTagTagLists;
            delete data.article.tagNameTagTagLists;
            return data;
        }));*/
        return this.apiService.get(`${this._apiDomain}/articles/${slug}`);
    }

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

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

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

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

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

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

    favorite(slug: string): Observable<Article> {
        return this.apiService.post(`${this._apiDomain}/articles/${slug}/favorite`);
    }

    unfavorite(slug: string): Observable<Article> {
        return this.apiService.delete(`${this._apiDomain}/articles/${slug}/favorite`);
    }
}
