angular.module('odoo')

    /**
     *
     */
    .factory('leadsRemoteFactory', function (
        leadsStorageFactory,
        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', '=', 'lead']], function (response) {
                    success(response);
                }, function (odooErr) {
                    error(odooErr);
                });

            }
        }

        /**
         *
         */
        var push = function (id, data, success, error) {

            // Avoid odoo server warning message
            delete data.id;
            delete data.remote_id;
            delete data.modified;
            delete data.priority;

            if (id) {

                pull(id, function (response) {
                    if (response.length == 1) {
                        var remoteData = response[0];

                        var remoteDate = new Date(remoteData.__last_update);
                        var localDate = new Date(data.modifiedDate);

                        delete data.modifiedDate;

                        if (localDate > remoteDate) {

                            odooFactory.write('crm.lead', id, data, function (response) {
                                console.log(response);
                                success(response);
                            }, function (odooErr) {
                                console.log(odooErr);
                                error(odooErr);
                            });

                        } else {
                            success(response);
                        }

                    } else {
                        success(response);
                    }

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

            } else {

                delete data.modifiedDate;

                odooFactory.create('crm.lead', data, function (response) {
                    success(response);
                }, function (odooErr) {
                    error(odooErr);
                });

            }
        }

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

            odooFactory.unlink('crm.lead', id, function (response) {
                success(response);
            }, function (odooErr) {
                error(odooErr);
            });

        }

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

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

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

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

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

                    console.log(data);

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

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

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

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

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

        /**
         *
         */
        var downloadSyncData = function (success, error) {
            pull(null, function (leads) {
                leadsStorageFactory.removeAll(function () {
                    asyncLoopFactory(leads.length, function (loop) {
                        var data = leads[loop.iteration()];

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

                        leadsStorageFactory.save(data, function (leadId) {
                            loop.next();
                        }, function (saveErr) {
                            loop.next();
                        });

                        // end loop
                    }, function () {
                        success(leads);
                    });

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

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

        /**
         *
         */
        var sync = function (success, error) {
            syncNewData(function () {

                console.log("leads --> new data ok");
                syncUpdatedData(function () {

                    console.log("leads --> updated data ok");
                    syncDeletedData(function () {

                        console.log("leads -> deleted data ok");
                        downloadSyncData(function (data) {

                            console.log("leads -> download data ok");
                            success(data);
                        }, function (downloadErr) {
                            error(downloadErr);
                        });
                    }, function (syncErr) {
                        error(syncErr);
                    });
                }, function (syncErr) {
                    error(syncErr);
                });
            }, function (syncErr) {
                error(syncErr);
            });
        }

        return {
            pull: pull,
            push: push,
            destroy: destroy,
            sync: sync
        }
    });
