import { Injectable } from "@angular/core";
import { Observable } from "rxjs/Observable";
import { Observer } from "rxjs/Observer";

import { OdooRPCService } from "angular2-odoo-jsonrpc";
import { PouchService } from "./pouch-service";
import { SyncService } from "./sync-service";

import "rxjs/add/observable/fromPromise";
import "rxjs/add/operator/concatMap";

@Injectable()
export class AuthService {

    constructor(
        public odooRPC: OdooRPCService,
        public pouch: PouchService,
        public sync: SyncService
    ) { }

    /**
     *
     */
    private initialize(url: string, port?: number) {
        let host = url;

        if (port) {
            host = host + ":" + port;
        }
        
        this.odooRPC.init({
            odoo_server: host,
            http_auth: "username:password"
        });
    }

    /**
     *
     */
    signin(loginInformation: any): Observable<any> {
        this.initialize(loginInformation.host);

        return Observable.fromPromise(this.odooRPC.login(loginInformation.database, loginInformation.username, loginInformation.password))
            .concatMap(response => this.normalizeUserInformation(response, loginInformation.password))
            .concatMap(userInformation => this.storeUserInformation(userInformation));
    }

    /**
     *
     */
    skipSignin(): Observable<any> {
        return this.pouch.getAll('user').concatMap(result => this.playUsersInformations(result));
    }

    /**
     *
     */
    signout(): Observable<any> {
        return Observable.fromPromise(this.odooRPC.logout());
    }

    /**
     *
     */
    private normalizeUserInformation(response: any, password: string): Observable<any> {
        return Observable.create((observer: Observer<any>) => {
            observer.next(Object.assign(response, { password: password }));
        });
    }

    /**
     *
     */
    private storeUserInformation(userInformation: any): Observable<any> {
        return this.pouch.save(Object.assign(userInformation, { type: 'user' }));
    }

    /**
     *
     */
    private playUsersInformations(result: any): Observable<any> {
        let users: any = {
            count: result.docs.length,
            users: result.docs
        }

        return Observable.create((observer: Observer<any>) => { 
            observer.next(users);
        });
    }
}