// import { Config} from './config';

declare var fetch: any;
declare var _: any;

export class Api {

    public headers: any = {};
    public settings: any;
    public routes = {};
    public baseUrl = '/api';
    public idField = 'id';
    public entities: any = {};
    public cache = false;
    public credentials: any;

    constructor() { }

    public init(settings) {
        this.settings = settings;
        if (this.settings.host) {
            this.baseUrl = settings.host;
        }
        if (this.settings.routes) {
            this.initApiRoutes();
        }
        if (this.settings.headers) {
            const self = this;
            this.settings.headers.forEach((obj) => {
                for (const k in obj) {
                    self.headers[k] = obj[k];
                }
            });
        }
        if(this['httpHeaders']) {
            // Angular only
            Object.keys(this.headers).forEach((k) => {
                this['httpHeaders'].set(k, this.headers[k]);
            });
        }
    };


    // CRUD handlers
    public async post(path, object: any) {
        await fetch(`${this.baseUrl}${path}`, {
            headers: this.headers,
            method: 'post',
            // method: 'POST',
            body: JSON.stringify( object )
        });
    }

    public async get(path: string, params: any = undefined) {
        if (params) {
            path += '?';
            Object.keys(params).forEach(key => path += key + '=' + params[key] + '&');
        }
        let result: any = await fetch(`${this.baseUrl}${path}`, { headers: this.headers} )
            .then((response) => {
                if (response.status >= 400) {
                    throw new Error('Bad response from server');
                }
                return response.json();
            })
            .then((data) => {
                // if(data.data && data.data[this.idField]) {
                //     this.entities[data.data[this.idField]] = data;
                // }
                return data;
            });
        return result;
    }

    public async patch(path, id, data) {
        await fetch(`${this.baseUrl}${path}/`+id, {
            headers: this.headers,
            // method: 'PATCH',
            method: 'patch',
            body: JSON.stringify( data )
        })
    }

    // FIXME: causes php server error on drupal content page
    public async delete(path, id) {
        // await fetch(`${this.baseUrl}${path}/` + id, {
        //     headers: this.headers,
        // //  method: 'DELETE'
        //     method: 'delete'
        // });
    }



    login(username, password) {

    }

    logout(namespace: string = 'app:authData', refresh: boolean = false) {
        this.clearCredentials(namespace);
        this.settings.authenticated = false;
        if (refresh) {
            // location.href = location.origin;
            location.href = location.href;
        }
    }

    // todo: use btoa + atob
    setCredentials(credentials: any, namespace: string = 'app:authData') {
        this.credentials = credentials;
        // window.localStorage.setItem(namespace, btoa(JSON.stringify(credentials)));
        window.localStorage.setItem(namespace, JSON.stringify(credentials));
    }

    getCredentials(namespace: string = 'app:authData') {
        if (window.localStorage.getItem(namespace)) {
            // return JSON.parse(atob(window.localStorage.getItem(namespace)));
            return JSON.parse(window.localStorage.getItem(namespace));
        }
    }

    clearCredentials(namespace: string = 'app:authData') {
        if (window.localStorage.getItem(namespace)) {
            window.localStorage.removeItem(namespace);
        }
    }

    initApiRoutes() {
        const self = this;
        self.settings.routes.forEach((obj) => {
            for (let k in obj) {
                self.routes[k] = obj[k];
            }
        });
        if (self.settings.dev && self.settings.routes_dev) {
            self.settings.routes_dev.forEach((obj) => {
                for (let k in obj) {
                    self.routes[k] = obj[k];
                }
            });
        }
    }

    // todo
    errorHandler(error) {
        // AppService.scope.$broadcast('formError', error);
        console.error(error);
        if (!error) {
            return;
        }
        // if(error.data === "token expired"){
        //     toastr.warning($filter('translate')('LOGIN EXPIRED')+'.');
        //     service.logOut();
        //     return;
        // }
        // if (error.statusText === 'Bad Request' || error.status == 400) {
        //     if (error.data.message) {
        //         toastr.warning($filter('translate')(error.data.message));
        //     } else {
        //         toastr.warning($filter('translate')('ERROR BAD REQUEST') + '.');
        //     }
        // }
        // if(error.statusText === 'Unauthorized' || error.status == 401){
        //     toastr.warning($filter('translate')('UNAUTHORIZED ERROR')+'.');
        //     service.logOut();
        //     return;
        // }
        // if(error.statusText === 'Not found' || error.status == 404){
        //     toastr.warning($filter('translate')('ERROR NOT FOUND')+'.');
        // }
    }

    // todo: remove for Storage.js
    saveLocalResource(resource) {
        localStorage.setItem(resource.ID, resource);
    }

    loadLocalResource(ID) {
        if (localStorage.getItem(ID)) {
            localStorage.getItem(ID);
        }
    }

    flushLocalResource(ID) {
        if (localStorage.getItem(ID)) {
            localStorage.removeItem(ID);
        }
    }
}
