import { Injectable } from '@angular/core';
import { DataProvider } from './data-provider';
import { OdooProvider } from './odoo-provider';
// import { NetworkProvider } from './network-provider';

@Injectable()    
export class SyncProvider {

    constructor(
        public dataProvider: DataProvider,
        public odooProvider: OdooProvider
    ) { }

    /**
     *
     */
    doSync(): Promise<any> {
        return new Promise((resolve, reject) => {
            this.getCreatedProducts().then(products => {
                return products;
            }).then(products => {
                return this.odooProvider.post("products", products);
            }).then(() => {
                return this.getUpdatedProducts();
            }).then(products => {
                return this.odooProvider.put("products", products);
            }).then(() => {
                return this.getDeletedProducts();
            }).then(products => {
                return this.odooProvider.delete("products", products);
            }).then(() => {
                return this.odooProvider.get("products");
            }).then(products => {
                return this.storeProducts(products);
            }).then(() => {
                resolve(true);    
            }).catch(e => { 
                reject(e);
            });
        });
    }

    /**
     *
     */
    private getCreatedProducts(): Promise<any> {
        return new Promise((resolve, reject) => {
            this.dataProvider.getAll("product").then(r => {
                resolve(r.products.filter(item => {
                    return item.doc_state === "created" || (item.doc_state === "updated" && !item.remote_id);
                }));
            }).catch(e => {
                reject(e);
            });
        });
    }

    private 

    /**
     *
     */
    private getUpdatedProducts(): Promise<any> {
        return new Promise((resolve, reject) => {
            this.dataProvider.getAll("product").then(data => {
                let products = data.products.filter(item => {
                    return item.doc_state === "updated" && item.remote_id;
                });
                
                resolve(products.map(item => {
                    delete item.id;
                    return item;
                }));
            }).catch(e => {
                reject(e);
            });
        });
    }

    /**
     *
     */
    private getDeletedProducts(): Promise<any> {
        return new Promise((resolve, reject) => { 
            this.dataProvider.getAll("product").then(data => {
                let products = data.products.filter(item => { 
                    return item.doc_state === "deleted";
                });
                
                resolve(products.map(item => {
                    delete item.id;
                    return item;
                }));
            }).catch(e => { 
                reject(e);
            });
        });
    }

    /**
     *
     */
    private storeProducts(products: Array<any>): Promise<any> {
        return new Promise((resolve, reject) => {
            this.dataProvider.deleteAll("products").then(() => {
                return;
            }).then(() => {
                
                return this.dataProvider.save("products", products.map(item => {
                    item.remote_id = item.id;
                    item.doc_state = "sync";
                    delete item.id;

                    return item;
                }));
            }).then(() => { 
                resolve();
            }).catch(e => { 
                reject(e);    
            });
        });
    }
}