import { Injectable, EventEmitter } from '@angular/core';
import { Http, Response, Headers } from '@angular/http';
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/operator/catch';
import 'rxjs/add/operator/map';
import 'rxjs/add/observable/throw';

import { Notification } from '../model/notification';
import { NotificationFileModel } from '../model/file-model';
import { SessionContext } from '../common/session-context';
import { Globals } from '../common/globals';
import { BaseHttpService } from './base-http.service';
import { MessageService } from './message.service';
import { IMPORT_NOTIFICATION_FILES } from './../test-data/import-notification-files';
import { ONE_IMPORT_NOTIFICATION_FILE } from './../test-data/import-notification-files';
@Injectable()
export class ImportService extends BaseHttpService {

    constructor(
        private _http: Http,
        private _sessionContext: SessionContext,
        protected messageService: MessageService) {
        super(messageService);
    }

   public getImportFiles(): Observable<NotificationFileModel[]> {

        const headers = new Headers();
        const url = super.getBaseUrl() + '/getImportFiles/';
        this.createCommonHeaders(headers, this._sessionContext);
        
        return this._http.get(url, { headers: headers })
             .map(res => super.extractData(res, this._sessionContext))
             .catch(super.handleErrorPromise);
    }

    public deleteImportFile(fileName: string): Observable<boolean> {
        const headers = new Headers();
        const url = super.getBaseUrl() + '/deleteImportedFiles/' + fileName;

        this.createCommonHeaders(headers, this._sessionContext);
        return this._http.delete(url, { headers: headers })
            .map(res => super.extractData(res, this._sessionContext))
            .catch(super.handleErrorPromise);
    }

    public importFile(): Observable<NotificationFileModel[]> {
        
        const headers = new Headers();
        const url = super.getBaseUrl() + '/importFile/';
        this.createCommonHeaders(headers, this._sessionContext);
        
        return this._http.get(url, { headers: headers })
            .map(res => super.extractData(res, this._sessionContext))
            .catch(super.handleErrorPromise);
    }
}