import { Injectable } from '@angular/core';
import PouchDB from 'pouchdb';
import each from 'async/each';
import * as Relational from 'relational-pouch';

PouchDB.plugin(Relational);

@Injectable()
export class DataProvider {

    data: any;

    constructor() {
        this.initialize();
    }

    /**
     *
     */
    private initialize(): void {
        this.data = new PouchDB('odoo');

        this.data.setSchema([
            {
                singular: 'partner',
                plural: 'partners'
            },
            {
                singular: 'user',
                plural: 'users',
                relations: {
                    partner: {
                        belongsTo: 'partner'
                    }
                }
            },
            {
                singular: 'currency',
                plural: 'currencies'
            },
            {
                singular: 'company',
                plural: 'companies',
                relations: {
                    currency: {
                        belongsTo: 'currency'
                    }
                }
            },
            {
                singular: 'product',
                plural: 'products',
                relations: {
                    company: {
                        belongsTo: 'product'
                    }
                }
            },
            {
                singular: 'warehouse',
                plural: 'warehouses',
            },
            {
                singular: 'stock',
                plural: 'stocks'
            },
            {
                singular: 'lead',
                plural: 'leads',
                relations: {
                    partner: {
                        belongsTo: 'partner'
                    }
                }
            }
        ]);
    }

    /**
     * Save object or array of objects to database
     * @argument type: string
     * @argument data: object or array of objects
     */
    save(type: string, data: any): Promise<any> {
        return new Promise((resolve, reject) => {
           
            if (data instanceof Array) {

                each(data, (i, c) => { 
                    this.data.rel.save(type, i).then(() => { 
                        c();
                    }).catch(e => { 
                        c(e);
                    });
                }, e => { 
                    if (e) {
                        reject(e);
                    } else {
                        resolve();
                    }
                });

            } else {
                 resolve(this.data.rel.save(type, data));
            }

        });
    }

    /**
     *
     */
    delete(type: string, data: any): any {
        return new Promise((resolve, reject) => {
            resolve(data.remote_id ? this.save(type, data) : this.data.rel.del(type, data));
        });
    }

    /**
     *
     */
    deleteAll(type: string): Promise<any> {
        return new Promise((resolve, reject) => { 
            this.getAll(type).then(data => {
                each(data[type], (i, c) => { 
                    this.data.rel.del(type, i).then(r => {
                        c();
                    }).catch(e => {
                        c(e);
                    });
                }, e => { 
                    if (e) {
                        reject(e);
                    } else {
                        resolve();
                    }
                });
            }).catch(e => { 
                reject(e);    
            });
        });    
    }

    /**
     *
     */
    getAll(type: string): Promise<any> {
        return new Promise((resolve, reject) => {
            resolve(this.data.rel.find(type));
        });
        
    }

    /**
     *
     */
    dropDatabase(): any {
        return new Promise((resolve, reject) => {
            resolve(this.data.destroy());
        });
    }

    /**
     *
     */
    parseDocID(id: string): any {
        return this.data.rel.parseDocID(id);
    }
}
