import { Injectable } from '@angular/core';
import { GenericService, QueryParam } from '@iqser/common-ui';
import { IRssData, IRssEntry, RssEntry } from '@red/domain';
import { catchError, map, tap } from 'rxjs/operators';
import { Observable, of } from 'rxjs';
import { HttpHeaders } from '@angular/common/http';
import { saveAs } from 'file-saver';

@Injectable({ providedIn: 'root' })
export class RssService extends GenericService<void> {
    protected readonly _defaultModelPath = 'import-redactions';

    getRSSData(dossierId: string, fileId: string): Observable<RssEntry> {
        const queryParams: QueryParam[] = [];
        queryParams.push({ key: 'fileId', value: fileId });

        return this._getOne<IRssData>([dossierId], 'rss/detailed', queryParams).pipe(
            map(data => data.files[0]),
            catchError(() => of({} as IRssEntry)),
            map(data => new RssEntry(data)),
        );
    }

    getRSSExportData(dossierId: string, fileId: string): Observable<any> {
        const queryParams: QueryParam[] = [];
        queryParams.push({ key: 'fileId', value: fileId });

        return this._getOne<any>([dossierId], 'rss', queryParams).pipe(
            map(data => data.files[0]),
            catchError(() => of({} as IRssEntry)),
        );
    }

    override(dossierId: string, fileId: string, componentOverrides: Record<string, string>): Observable<void> {
        return this._post({ componentOverrides }, `rss/override/${dossierId}/${fileId}`);
    }

    revertOverride(dossierId: string, fileId: string, components: string[]): Observable<void> {
        return this._post({ components }, `rss/override/revert/${dossierId}/${fileId}`);
    }

    exportJSON(dossierId: string, fileId: string, name: string): Observable<RssEntry> {
        return this.getRSSExportData(dossierId, fileId).pipe(
            tap(data => {
                const blob = new Blob([JSON.stringify(data, null, 2)], { type: 'application/json' });
                saveAs(blob, name + '.rss.json');
            }),
        );
    }

    exportXML(dossierId: string, fileId: string, name: string): Observable<string> {
        return this._getRSSDataAsXML(dossierId, fileId).pipe(
            tap(data => {
                const blob = new Blob([data], { type: 'application/xml' });
                saveAs(blob, name + '.rss.xml');
            }),
        );
    }

    private _getRSSDataAsXML(dossierId: string, fileId: string) {
        const queryParams: QueryParam[] = [];
        queryParams.push({ key: 'fileId', value: fileId });

        const entityPath = [dossierId].map(item => encodeURIComponent(item)).join('/');

        let headers = new HttpHeaders();
        headers = headers.set('accept', 'application/xml');

        return this._http.get(`/${this._serviceName}/${encodeURI('rss')}/${entityPath}`, {
            headers: headers,
            params: this._queryParams(queryParams),
            responseType: 'text',
            observe: 'body',
        });
    }
}
