angular.module('odoo')

    /**
    * -----------------------------------------------------------------------------
    *  Description:    Local storage manager for crm stage data
    * -----------------------------------------------------------------------------
    */
    .factory('opportunitiesDataFactory', function (
        opportunitiesStorageFactory,
        leadsRemoteFactory,
        odooFactory,
        sqlFactory,
        asyncLoopFactory
    ) {

        /**
         *
         */
        var pull = function (id, success, error) {
                if (id) {

                    odooFactory.read('crm.lead', [['id', '=', id]], function (response) {
                        success(response);
                    }, function (odooErr) {
                        error(odooErr);
                    });

                } else {

                    odooFactory.read('crm.lead', [['type', '=', 'opportunity']], function (response) {
                        success(response);
                    }, function (odooErr) {
                        error(odooErr);
                    });
                }
        }

        /**
         *
         */
        var push = function (id, data, success, error) {
            leadsRemoteFactory.push(id, data, function (response) {
                success(response);
            }, function (err) {
                error(err);
            });
        }

        /**
         *
         */
        var destroy = function (id, success, error) {
            leadsRemoteFactory.destroy(id, function (response) {
                success(response);
            }, function (err) {
                error(err);
            });
        }

        /**
         *
         */
        var get = function (constraint, success, error) {
            sqlFactory.selectByConstraint('lead', constraint, function (leads) {
                success(leads);
            }, function (err) {
                error(err);
            });
        }

        /**
         *
         */
        var getAll = function (success, error) {
            get("type = 'opportunity' AND modified != 2", function (opportunities) {
                var data = [];

                for (var i = 0; i < opportunities.length; i++) {
                    data.push(opportunities.item(i));
                }

                success(data);
            }, function (selectErr) {
                error(selectErr);
            });
        }

        /**
         *
         */
        var syncNewData = function (success, error) {
            get("remote_id = 0 AND type = 'opportunity'", function (newOpportunities) {
                asyncLoopFactory(newOpportunities.length, function (loop) {
                    var data = newOpportunities.item(loop.iteration());

                    push(null, data, function (response) {
                        loop.next();
                    }, function (pushErr) {
                        loop.next();
                    });

                    // end loop
                }, function () {
                    success(newOpportunities);
                });
            }, function (getErr) {
                error(getErr);
            });
        }

        /**
         *
         */
        var syncUpdatedData = function (success, error) {
            get("remote_id != 0 AND modified = 1 AND type = 'opportunity'", function (updatedOpportunities) {
                asyncLoopFactory(updatedOpportunities.length, function (loop) {
                    var data = updatedOpportunities.item(loop.iteration());

                    console.log(data);

                    push(data.remote_id, data, function (response) {
                        loop.next();
                    }, function (pushErr) {
                        loop.next();
                    });

                    // end loop
                }, function () {
                    success(updatedOpportunities);
                });
            }, function (getErr) {
                error(getErr);
            });
        }

        /**
         *
         */
        var syncDeletedData = function (success, error) {
            get("remote_id != 0 AND modified = 2 AND type = 'opportunity'", function (deletedOpportunities) {
                asyncLoopFactory(deletedOpportunities.length, function (loop) {
                    var id = deletedOpportunities.item(loop.iteration()).remote_id;

                    destroy(id, function (response) {
                        loop.next();
                    }, function (destroyErr) {
                        loop.next();
                    });

                    // end loop
                }, function () {
                    success(deletedOpportunities);
                });
            }, function (getErr) {
                error(getErr);
            });
        }

        /**
         *
         */
        var downloadSyncData = function (success, error) {
            pull(null, function (opportunities) {

                opportunitiesStorageFactory.removeAll(function () {
                    asyncLoopFactory(opportunities.length, function (loop) {
                        var data = opportunities[loop.iteration()];

                        data.remote_id = data.id;
                        delete data.id;

                        opportunitiesStorageFactory.save(data, function (opportunity) {
                            loop.next();
                        }, function (saveErr) {
                            loop.next();
                        });

                    }, function () {
                        success(opportunities);
                    });
                }, function (removeAllErr) {
                    error(removeAllErr);
                });

            }, function (pullErr) {
                error(pullErr);
            });
        }

        /**
         *
         */
        var sync = function (success, error) {
            syncNewData(function () {
                console.log('opportunities --> new data ok');

                syncUpdatedData(function () {
                    console.log('opportunities --> updated data ok');

                    syncDeletedData(function () {
                        console.log('opportunities --> deleted data ok');

                        downloadSyncData(function (data) {
                            console.log('opportunities --> download data ok');

                            success(data);
                        }, function (syncErr) {
                            error(syncErr);
                        });
                    }, function (syncErr) {
                        error(syncErr);
                    });
                }, function (syncErr) {
                    error(syncErr);
                });
            }, function (syncErr) {
                error(syncErr);
            });
        }

        return {
            pull: pull,
            push: push,
            destroy: destroy,
            getAll: getAll,
            sync: sync

        }
    });
