'use strict';
define([
        'oro/loading-mask',    
        'jquery',
        'webkuldam/asset/media-field',
        'underscore',
        'routing',
        'pim/attribute-manager',
        'webkuldam/template/awsintegration/product/field/media', 
        'pim/dialog',
        'oro/mediator',
        'oro/messenger',
        'pim/media-url-generator',
        'pim/common/property',
        'jquery.slimbox'
    ],
    function (LoadingMask, $, Field, _, Routing, AttributeManager, fieldTemplate, Dialog, mediator, messenger, MediaUrlGenerator, propertyAccessor) {
        return Field.extend({
            fieldTemplate: _.template(fieldTemplate),
            events: {
                'change input[type="file"]': 'updateModel',
                'click  .clear-field': 'clearField',
                'click  .open-media': 'previewImage',
                'click .edit-media' : 'editimage',
                'click .show-url': 'showS3Url',
                'blur .ak-input-copy-link': 'removeS3Link',
                'click .change-visibility': 'changeFileVisibility',
            },
            fileUrl: '',
            showS3Url: function(e) {
                var slug = encodeURIComponent(this.getCurrentValue().data.filePath);
              
                var elem = $(e.target).closest('.show-url');
                if(elem.next() && !elem.next().hasClass('ak-input-copy-link')) {
                    if(this.fileUrl) {
                        elem.after(this.showUrlTemplate({'url': this.fileUrl}));
                        elem.next().focus().select();
                    } else {
                        var self = this;
                        $.get(Routing.generate('webkul_awsintegration_connector_media_get_url', { name: slug }))
                        .done(function(response) {
                            if(typeof(response.url) !== 'undefined' && response.url) {
                                self.fileUrl = response.url;
                                elem.after(self.showUrlTemplate({'url': self.fileUrl}));
                                elem.next().focus().select();                                 
                            }
                        });
                    }
                }
            },
            changeFileVisibility: function(e) {
                var slug = encodeURIComponent(this.getCurrentValue().data.filePath);
                $.get(Routing.generate('webkul_awsintegration_connector_change_visibility', { name: slug }))
                .then(this.postSave.bind(this))
                .fail(this.fail.bind(this));
            },            
            removeS3Link: function(e) {
                $('.ak-input-copy-link').remove();
            },
            showUrlTemplate: _.template('<input type="text" class="ak-input-copy-link AknTextField" value="<%- url %>">'),
            /**
             * What to do after a save
             */
            postSave: function (response, responseJSON) {
                var msg = 'Visibility changed to successfully.';
                
                if(typeof(response.visibility) !== 'undefined' && response.visibility) {
                    msg = " Visibility successfully changed to " + response.visibility;
                }
                
                messenger.notify(
                    'success',
                    msg
                );
            },
            /**
             * On save fail
             *
             * @param {Object} response
             */
            fail: function (response, responseJSON) {
                var msg = "Can't change visibility make sure PutObjectAcl permission is given to bucket.";
                if(typeof(response.responseJSON.visibility) !== 'undefined' && response.responseJSON.visibility) {
                    msg += " Current visibility is " + response.responseJSON.visibility;
                }
                messenger.notify(
                    'error',
                     msg
                );
            } ,
            renderInput: function (context) {
                
                return this.fieldTemplate(context);
            },
            getTemplateContext: function () {
                return Field.prototype.getTemplateContext.apply(this, arguments)
                    .then(function (templateContext) {
                        templateContext.inUpload          = !this.isReady();
                        templateContext.mediaUrlGenerator = MediaUrlGenerator;
                        templateContext.Routing = Routing;
                                                
                        if(this.getCurrentValue()) {
                            templateContext.value = this.getCurrentValue();
                        }

                        return templateContext;
                    }.bind(this));
            },

            renderCopyInput: function (value) {
                return this.getTemplateContext()
                    .then(function (context) {
                        var copyContext = $.extend(true, {}, context);
                        copyContext.value = value;
                        copyContext.context.locale    = value.locale;
                        copyContext.context.scope     = value.scope;
                        copyContext.editMode          = 'view';
                        copyContext.mediaUrlGenerator = MediaUrlGenerator;
                        copyContext.Routing = Routing;

                        return this.renderInput(copyContext);
                    }.bind(this));
            },
            /**
             * Render this field
             *
             * @returns {Object}
             */
            render: function () {
                this.setEditable(!this.locked);
                this.setValid(true);
                this.elements = {};
                var promises  = [];
                
                $.when.apply($, promises)
                    .then(this.getTemplateContext.bind(this))
                    .then(function (templateContext) {
                        this.$el.html(this.fieldTemplate(templateContext));
                        // console.log(templateContext);
                        // this.$el.append(this.renderInput(templateContext));

                        this.renderElements();
                        this.postRender();
                        this.delegateEvents();
                    }.bind(this));

                return this;
            },          
            /**
             * Render elements of this field in different available positions
             */
            renderElements: function () {
                _.each(this.elements, function (elements, position) {
                    var $container = 'field-input' === position ?
                        this.$('.original-field .field-input') :
                        this.$('.' + position + '-elements-container');

                    $container.empty();

                    _.each(elements, function (element) {
                        if (typeof element.render === 'function') {
                            $container.append(element.render().$el);
                        } else {
                            $container.append(element);
                        }
                    }.bind(this));

                }.bind(this));
            },       
            /**
             * Is called after rendering the input
             */
            postRender: function () {},
                   
            updateModel: function () {
                if (!this.isReady()) {
                    Dialog.alert(_.__(
                        'pim_enrich.entity.product.info.already_in_upload',
                        {'locale': this.context.locale, 'scope': this.context.scope}
                    ));
                }

                var input = this.$('input[type="file"]').get(0);
                
                if (!input || 0 === input.files.length) {
                    return;
                }

                var formData = new FormData();
                formData.append('file', input.files[0]);

                this.setReady(false);
                this.uploadContext = {
                    'locale': this.context.locale,
                };


                $.ajax({
                    url: Routing.generate('pim_enrich_media_rest_post'),
                    type: 'POST',
                    data: formData,
                    contentType: false,
                    cache: false,
                    processData: false,
                    xhr: function () {
                        var myXhr = $.ajaxSettings.xhr();
                        if (myXhr.upload) {
                            myXhr.upload.addEventListener('progress', this.handleProcess.bind(this), false);
                        }

                        return myXhr;
                    }.bind(this)
                })
                .done(function (data) {
                    if(data) {
                        this.setUploadContextValue(data);
                        this.render();
                    }
                }.bind(this))
                .fail(function (xhr) {
                    var message = xhr.responseJSON && xhr.responseJSON.message ?
                        xhr.responseJSON.message :
                        _.__('pim_enrich.entity.product.error.upload');
                    messenger.enqueueMessage('error', message);
                })
                .always(function () {
                    this.$('> .akeneo-media-uploader-field .progress').css({opacity: 0});
                    this.setReady(true);
                    this.uploadContext = {};
                }.bind(this));
            },
            clearField: function () {
                this.setCurrentValue({
                    filePath: null,
                    originalFilename: null
                });

                this.render();
            },
            /**
             * Set as valid
             *
             * @param {boolean} valid
             */
            setValid: function (valid) {
                this.valid = valid;
            },

            /**
             * Return whether is valid
             *
             * @returns {boolean}
             */
            isValid: function () {
                return this.valid;
            },

            /**
             * Set the focus on the input of this field
             */
            setFocus: function () {
                this.$('input:first').focus();
            },

            /**
             * Set this field as editable
             *
             * @param {boolean} editable
             */
            setEditable: function (editable) {
                this.editable = editable;
            },

            /**
             * Set this field as locked
             *
             * @param {boolean} locked
             */
            setLocked: function (locked) {
                this.locked = locked;
            },

            /**
             * Return whether this field is editable
             *
             * @returns {boolean}
             */
            isEditable: function () {
                return this.editable;
            },

            /**
             * Set this field as ready
             *
             * @param {boolean} ready
             */
            setReady: function (ready) {
                this.ready = ready;
            },

            /**
             * Return whether this field is ready
             *
             * @returns {boolean}
             */
            isReady: function () {
                return this.ready;
            },

            /**
             * Get the current edit mode (can be 'edit' or 'view')
             *
             * @returns {string}
             */
            getEditMode: function () {
                if (this.editable) {
                    return 'edit';
                } else {
                    return 'view';
                }
            },

            /**
             * Return whether this field can be seen
             *
             * @returns {boolean}
             */
            canBeSeen: function () {
                return true;
            },

            getCurrentValue: function () {
                const value = propertyAccessor.accessProperty(
                    this.getFormData(),
                    this.fieldName
                );

                if(value && typeof(value.data) === 'undefined' && (value.length !== 0) ) {
                    return { 'data': value };
                }

                return null === value || (typeof(value.data) === 'object' && value.data === 0) ? undefined : value;
            },
            /**
             * Set current model value for this field
             *
             * @param {*} value
             */
            setCurrentValue: function (value) {
                const data = this.getFormData();
                if(value) {
                    value = { 'data' : value };
                }
                propertyAccessor.updateProperty(data, this.fieldName, value);

                this.setData(data);
            },

            /**
             * Get the label of this field (default is code surrounded by brackets)
             *
             * @returns {string}
             */
            getLabel: function () {
                return _.__('File');
            },

            handleProcess: function (e) {
                if (this.uploadContext.locale === this.context.locale &&
                    this.uploadContext.scope === this.context.scope
                ) {
                    this.$('> .akeneo-media-uploader-field .progress').css({opacity: 1});
                    this.$('> .akeneo-media-uploader-field .progress .bar').css({
                        width: ((e.loaded / e.total) * 100) + '%'
                    });
                }
            },
            previewImage: function () {
                var mediaUrl = MediaUrlGenerator.getMediaShowUrl(this.getCurrentValue().data.filePath, 'preview');
                if (mediaUrl) {
                    $.slimbox(mediaUrl, '', {overlayOpacity: 0.3});
                }
            },
            editimage: function (event) {
                var mediaUrl = MediaUrlGenerator.getMediaShowUrl(this.getCurrentValue().data.filePath, 'preview');
                // console.log(mediaUrl);
                var code  = this.getFormData().code;
                
                event.preventDefault();
                // console.log(router);
                
                // return false;
                router.redirectToRoute('webkul_edit_media',{'code':code, 'url': mediaUrl});
    
            },

            setUploadContextValue: function (value) {
                this.setCurrentValue(value);
            },
            /**
             * Recursively search for the first tab ancestor if any, and returns its code. Sorry.
             *
             * @returns {String}
             */
            getTabCode() {
                let parent = this.getParent();
                while (!(parent instanceof Tab)) {
                    parent = parent.getParent();
                    if (null === parent) {
                        return null;
                    }
                }

                return parent.code;
            } 

        });
    }
);
