angular.module('odoo')

    .factory('leadsRemoteFactory', function (
        leadsStorageFactory,
        odooFactory,
        configFactory,
        sqlFactory,
        asyncLoopFactory
    ) {

        // Pull server leads data
        var pull = function (id, success, error) {
            configFactory(function (configuration) {
                if (id) {

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

                } else {

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

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

        // Push leads data to server
        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;

            configFactory(function (configuration) {

                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, configuration, 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, configuration, function (response) {
                        success(response);
                    }, function (odooErr) {
                        error(odooErr);
                    });

                }

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

        // Destroy server lead data
        var destroy = function (id, success, error) {
            configFactory(function (configuration) {

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

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

        // Get local lead data
        var get = function (contraint, success, error) {
            sqlFactory.selectByConstraint('lead', contraint, function (leads) {
                success(leads);
            }, function (err) {
                error(err);
            });
        }

        // Send all new data from local to remote server
        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);
            });
        }

        // Update all data from server
        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);
            });
        }

        // Delete all data
        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);
            });
        }

        // Download all sync data from server
        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);
            });
        }

        // Sync all leads data between local and remote data
        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
        }
    });
