/* global
 $, DataProviderHelper, SessionTimeoutError, ServerPermissionError
*/

var DataProvider = {};
(function () {
    'use strict';
    var context = window.parent;

    DataProvider.validateResponse = function validateResponse(xhr) {
        var error = DataProviderHelper.validateRequest(xhr);
        if (!error) {
            var responseText = xhr.responseText;
            if (typeof responseText === 'string') {
                if (responseText.indexOf('<form action="#" id="forgot_password_form"') !== -1 ||
                        responseText.indexOf('<form action="#" id="login_form"') !== -1 ||
                        responseText === "0") {

                    error = new SessionTimeoutError();
                    error.loginUrl = context.location.href;
                } else {
                    try {
                        var obj = JSON.parse(responseText);
                        if (obj.result === 'fail' && obj.type === 'permission') {
                            error = new ServerPermissionError(obj.error);
                        }
                    } catch (e) {}
                }
            }
        }
        return error;
    };

    function addQueryArg(uri, key, value) {
        var re = new RegExp("([?&])" + key + "=.*?(&|$)", "i");
        var separator = uri.indexOf('?') !== -1 ? "&" : "?";
        if (uri.match(re))
            return uri.replace(re, '$1' + key + "=" + value + '$2');
        return uri + separator + key + "=" + value;
    }

    function ajaxFailHandler(url, xhr, status, callback) {
        var error = DataProvider.validateResponse(xhr);
        if (!error) {
            error = DataProviderHelper.createCmsRequestError(url, xhr, status);
        }
        callback(error);
    }

    function createChunkedRequest(action, data) {
        return {
            'save': {
                'post': {
                    ajax: '1',
                    action : action,
                    controller: 'AdminAjax',
                    token : window.pluginData.token,
                    data: JSON.stringify(data),
                    themeName: window.pluginData.themeName
                },
                'url': window.pluginData.ajax
            },
            'clear': {
                'post': {
                    ajax: '1',
                    action : 'clear',
                    controller: 'AdminAjax',
                    token : window.pluginData.token,
                    themeName: window.pluginData.themeName
                },
                'url': window.pluginData.ajax
            },
            'errorHandler': DataProvider.validateResponse,
            'zip': true,
            'blob': true
        };
    }

    function doRequest(data, onError, onSuccess) {
        if (!onError || typeof onError !== 'function') {
            throw DataProviderHelper.getResultError('Invalid callback');
        }

        $.ajax({
            url: window.pluginData.ajax,
            type: 'post',
            dataType: 'json',
            data: jQuery.extend({
                ajax: '1',
                action: 'request',
                controller: 'AdminAjax',
                token : window.pluginData.token
            }, data)
        }).done(function requestSuccess(response, status, xhr) {
            var error = DataProvider.validateResponse(xhr);
            if (error) {
                onError(error);
            } else if (response.result === 'done') {
                if (typeof onSuccess === 'undefined') {
                    onError(error, response);
                } else {
                    onSuccess(response);
                }
            } else {
                var invalidResponseError = DataProviderHelper.createCmsRequestError(window.pluginData.ajax, xhr, status, (data.action || '') + ' server error: ' + JSON.stringify(response));
                onError(invalidResponseError);
            }
        }).fail(function requestFail(xhr, status) {
            ajaxFailHandler(window.pluginData.ajax, xhr, status, onError);
        });
    }

    function reloadInfo(action, callback) {
        if (!callback || typeof callback !== 'function') {
            throw DataProviderHelper.getResultError('Invalid callback');
        }

        $.ajax({
            url: window.pluginData.ajax,
            type: 'post',
            data: ({
                ajax: '1',
                action : action,
                controller: 'AdminAjax',
                token : window.pluginData.token,
                themeName: window.pluginData.themeName
            })
        }).done(function reloadTemplatesInfoSuccess(data, status, xhr) {
            var error = DataProvider.validateResponse(xhr);
            if (!error) {
                try {
                    var info = JSON.parse(data);
                    $.each(info, function(key, value) {
                        window.pluginData[key] = value;
                    });
                } catch(e) {
                    error = new Error(e);
                    error.args = { parseArgument: data };
                }
            } 
            callback(error, data);
        }).fail(function reloadTemplatesInfoFail(xhr, status) {
            ajaxFailHandler(window.pluginData.ajax, xhr, status, callback);
        });
    }

    DataProvider.backToAdmin = function backToAdmin() {
        window.location = window.pluginData.url.admin;
    };

    DataProvider.getMaxRequestSize = function getMaxRequestSize() {
        return window.pluginData.maxRequestSize;
    };

    DataProvider.getAllCssJsSources = function getAllCssJsSources() {
        return window.pluginData.cssJsSources;
    };

    DataProvider.getMd5Hashes = function getMd5Hashes() {
        return window.pluginData.md5Hashes;
    };

    DataProvider.getTheme = function getTheme(data, callback) {
        var url = window.pluginData.getTheme;
        data.srcTheme = window.pluginData.themeName;
        $.each(data, function(key, value) {
            url = addQueryArg(url, key, value);
        });
        callback(null, url);
    };

    DataProvider.doExport = function doExport(exportData, callback) {
        DataProviderHelper.chunkedRequest(createChunkedRequest('export', exportData), callback);
    };

    DataProvider.save = function save(saveData, callback) {
        DataProviderHelper.chunkedRequest(createChunkedRequest('save', saveData), callback);
    };

    DataProvider.load = function load() {
        return window.pluginData.project.projectData;
    };

    DataProvider.updatePreviewTheme = function updatePreviewTheme(callback) {
        doRequest({method: 'update', themeName: window.pluginData.themeName}, callback);
    };

    DataProvider.makeThemeAsActive = function makeThemeAsActive(callback, id) {
        var data = {method: 'activate', themeName: window.pluginData.themeName};
        if (typeof id !== 'undefined') {
            data.newName = id;
        }
        doRequest(data, callback);
    };

    DataProvider.removeTheme = function removeTheme(id, callback) {
        doRequest({method: 'remove', themeName: window.pluginData.themeName, newName: id}, callback);
    };

    DataProvider.copyTheme = function copyTheme(id, newName, callback) {
        var data = {method: 'copy', themeName: id};
        if (typeof newName !== 'undefined') {
            data.newName = newName;
        }
        doRequest(data, callback);
    };

    DataProvider.renameTheme = function renameTheme(themeName, newName, callback) {
        doRequest({method: 'rename', themeName: themeName, newName: newName}, callback, function() {
            callback(null, context.location.href.replace(new RegExp('theme_name=' + themeName), 'theme_name=' + newName));
        });
    };

    DataProvider.rename = function rename(newName, callback) {
        DataProvider.renameTheme(window.pluginData.themeName, newName, callback);
    };

    DataProvider.canRename = function canRename(themeName, callback) {
        doRequest({method: 'canRename', themeName: window.pluginData.themeName, newName: themeName}, callback, function(response) {
            if (response.message === '') {
                callback(null, true);
            } else {
                callback(null, false, response.message);
            }
        });
    };

    DataProvider.themeNameValidation = function validation(name, callback) {
        doRequest({method: 'validate', themeName: window.pluginData.themeName, newName: name}, callback, function(response) {
            if (response.message === '') {
                callback(null);
            } else {
                callback(null, response.message);
            }
        });
    };

    DataProvider.getFiles = function getFiles(mask, filter, callback) {
        $.ajax({
            type: 'post',
            url: window.pluginData.ajax,
            dataType: 'json',
            data: {
                ajax: '1',
                action: 'getFiles',
                controller: 'AdminAjax',
                token : window.pluginData.token,
                mask: mask || '*',
                filter: filter || '',
                themeName: window.pluginData.themeName
            }
        }).done(function getFilesSuccess(response, status, xhr) {
            var error = DataProvider.validateResponse(xhr);
            if (!error) {
                callback(null, response.files);
            } else {
                callback(error);
            }
        }).fail(function getFilesFail(xhr, status) {
            ajaxFailHandler(window.pluginData.ajax, xhr, status, callback);
        });
    };

    DataProvider.setFiles = function setFiles(files, callback) {
        DataProviderHelper.chunkedRequest(createChunkedRequest('setFiles', files), callback);
    };

    DataProvider.zip = function zip(data, callback) {
        DataProviderHelper.chunkedRequest(createChunkedRequest('fsoZip', data), callback);
    };

    DataProvider.reloadTemplatesInfo = function reloadTemplatesInfo(callback) {
        reloadInfo('reloadTemplatesInfo', callback);
    };
    
    DataProvider.reloadThemesInfo = function reloadTemplatesInfo(callback) {
        reloadInfo('reloadThemesInfo', callback);
    };

    DataProvider.getInfo = function getInfo(){
        return {
            cmsName: 'PrestaShop',
            cmsVersion: window.pluginData.cmsVersion,
            adminPage: window.pluginData.url.admin,
            startPage: window.pluginData.url.preview,
            uploadImage: window.pluginData.uploadImage,
            uploadTheme: window.pluginData.uploadTheme,
            unZip: window.pluginData.unZip,
            templates: $.extend({}, window.pluginData.templates),
            canDuplicateTemplatesConstructors: $.extend({}, window.pluginData.canDuplicateTemplatesConstructors),
            thumbnails: [{name: 'preview.jpg', width: 180, height: 226, version: '1.5.3'},{name: 'preview.jpg', width: 180, height: 226, version: '1.5.6'},{name: 'preview.jpg', width: 180, height: 226, version: '1.6'}],
            isThemeActive: window.pluginData.isActive,
            themeName: window.pluginData.themeName,
            themes: $.extend({}, window.pluginData.themes),
            pathToManifest: '/export/themler.manifest'
        };
    };

    DataProvider.getVersion = function () {
        return "0.0.2";
    };

    DataProvider.escapeCustomCode = function (content) {
        return '{literal}' + content + '{/literal}';
    };

    if (!window.pluginData || !window.pluginData.project) {
        var url = window.location.href;
        if (url.indexOf('#') !== -1)
            url = url.substring(0, url.indexOf('#'));
        window.location.href = addQueryArg(url, 'noCache', Math.floor(Math.random() * 1e5) + '');
    }
}());