import { Component, Inject, OnInit, Injectable, OnDestroy } from '@angular/core';
import { Http, RequestOptions } from '@angular/http';
import { Headers } from '@angular/http';
import { Observable } from 'rxjs';
import { catchError, tap } from 'rxjs/operators';
// import { Hero } from './hero';
import { HttpErrorHandler, HandleError } from '../auth/http-error-handler.service';
import { AuthService } from '../auth/auth.service';
import { HttpClient, HttpParams } from '@angular/common/http';
import { HttpHeaders } from '@angular/common/http';
import { RequireInteractiveControl } from '../interface/Interactive Component/RequireInteractiveControl';
import { SyncResponseErrorHandleService } from '../route/SyncResponseErrorHandle';

@Injectable()
export class BaseService<T extends RequireInteractiveControl> implements OnDestroy {
    // config: Config;
    public isLock = false;
    public handleError: HandleError;
    public data: T;
    public isAdd: boolean;
    public mode: string;
    public baseu: string;
    public generalhttp: HttpClient;
    queryParamObj: any;
    constructor(
        public authService: AuthService,
        public httpErrorHandler: HttpErrorHandler,
        public http: HttpClient,
        public baseUrl: string
        , public objectname: string
        , public subrouteurl: string = ''
        , public syncResponseErrorHandleService?: SyncResponseErrorHandleService) {
        this.handleError = httpErrorHandler.createHandleError('BaseService');
        this.baseu = baseUrl;
        this.generalhttp = http;
        this.init();
    }

    init() { }

    // optionss = {
    //     headers: this.GetHeaders(),
    //     params: new HttpParams()
    // };

    GetHeaders(): HttpHeaders {
        const httpHeaderss = new HttpHeaders()
            .set('Content-Type', 'application/json')
            .set('Authorization', this.authService.getAuthorizationHeaderValue())
            .set('OC', this.authService.getSelectedOc())
            .set('offset', new Date().getTimezoneOffset().toString());

        return httpHeaderss;
    }

    optionss() {
        return {
            headers: this.GetHeaders(),
            params: new HttpParams()
        };
    }

    Get(): Observable<T[]> {

        if (this.subrouteurl === '') {
            return this.generalhttp.get<T[]>(this.baseu + 'api/' + this.objectname, this.optionss())
                .pipe(
                    catchError(this.handleError('GetBaseService', []))
                );
        } else {
            return this.generalhttp.get<T[]>(this.baseu + 'api/' + this.subrouteurl + this.objectname, this.optionss())

                .pipe(
                    catchError(this.handleError('GetBaseService', []))
                );
        }
    }

    GetById(id: any): Observable<T> {

        if (this.subrouteurl === '') {
            return this.generalhttp.get<T>(this.baseu + 'api/' + this.objectname + '/' + id, this.optionss())

                .pipe(
                    catchError(this.handleError('GetBaseService', null))
                );
        } else {
            return this.generalhttp.get<T>(this.baseu + 'api/' + this.subrouteurl + this.objectname + '/' + id, this.optionss())

                .pipe(
                    catchError(this.handleError('GetBaseService', null))
                );
        }
    }

    Create(object: T): Observable<SyncResponse> {
        // console.log(object);
        return this.generalhttp.post<SyncResponse>(this.baseu + 'api/' + this.objectname + '/', object,
            this.optionss()).pipe(
                tap(r => { this.syncResponseErrorHandleService.SyncResponseErrorHandle(r); }),
                catchError(this.handleError('CreateBaseService', null))
            );
    }

    Update(object: T): Observable<SyncResponse> {
        return this.generalhttp.put<SyncResponse>(this.baseu + 'api/' + this.objectname + '/', object, this.optionss())
            .pipe(
                tap(r => { this.syncResponseErrorHandleService.SyncResponseErrorHandle(r); }),
                catchError(this.handleError('UpdateBaseService', null))
            );
    }

    Delete(object: T): Observable<SyncResponse> {
        return this.generalhttp.delete<SyncResponse>(this.baseu + 'api/' + this.objectname + '/' + object.id, this.optionss())
            .pipe(
                tap(r => { this.syncResponseErrorHandleService.SyncResponseErrorHandle(r); }),
                catchError(this.handleError('DeleteBaseService', null))
            );
    }

    BulkInsert(objList: T[]): Observable<SyncResponse> {
        return this.generalhttp.post<SyncResponse>(this.baseu + 'api/' + this.objectname + '/' + 'BulkInsert', objList,
            {
                headers: this.GetHeaders(),
            })
            .pipe(
                tap(r => { this.syncResponseErrorHandleService.SyncResponseErrorHandle(r); }),
                catchError(this.handleError('BulkInsert', null))
            );
    }
    BulkDelete(objList: T[]): Observable<SyncResponse> {
        return this.generalhttp.put<SyncResponse>(this.baseu + 'api/' + this.objectname + '/' + 'BulkDelete', objList,
            {
                headers: this.GetHeaders(),
            })
            .pipe(
                tap(r => { this.syncResponseErrorHandleService.SyncResponseErrorHandle(r); }),
                catchError(this.handleError('BulkDelete', null))
            );
    }
    BulkUpdate(objList: T[]): Observable<SyncResponse> {
        return this.generalhttp.put<SyncResponse>(this.baseu + 'api/' + this.objectname + '/' + 'BulkUpdate', objList,
            {
                headers: this.GetHeaders(),
            })
            .pipe(
                tap(r => { this.syncResponseErrorHandleService.SyncResponseErrorHandle(r); }),
                catchError(this.handleError('BulkUpdate', null))
            );
    }

    Restore(object: T): Observable<SyncResponse> {
        return this.generalhttp.put<SyncResponse>(this.baseu + 'api/' + this.objectname + '/' + 'Restore', object,
            {
                headers: this.GetHeaders(),
            })
            .pipe(
                tap(r => { this.syncResponseErrorHandleService.SyncResponseErrorHandle(r); }),
                catchError(this.handleError('Restore', null))
            );
    }

    ActivateContent(entityStatus: string, id: string, type?: string): Observable<SyncResponse> {

        return this.http.post(this.baseu + 'api/' + this.objectname + '/Activation/' + entityStatus + '/' + id, null, {
            headers: this.GetHeaders()
        })
            .pipe(
                catchError(this.handleError('ActivateContent', null))
            );
    }

    ngOnDestroy(): void {
    }
}

