;(function($, window, document, undefined) {
    'use strict';

    window.MediaManager = function() {
        return {
            keywords: '',
            files: [],
            selected: [],
            loading: false,
            init: function () {
                var dropArea = $('#drop-area');

                dropArea.on('dragenter, dragover', function (e) {
                    e.preventDefault();
                    e.stopPropagation();
                    dropArea.addClass('drop-area--highlighted');
                });

                dropArea.on('dragleave', function (e) {
                    e.preventDefault();
                    e.stopPropagation();
                    dropArea.removeClass('drop-area--highlighted');
                });

                dropArea.on('drop', $.proxy(function (e) {
                    if (e.originalEvent.dataTransfer && e.originalEvent.dataTransfer.files.length) {
                        e.preventDefault();
                        e.stopPropagation();
                        dropArea.removeClass('drop-area--highlighted');
                        window.MediaUpload(e.originalEvent.dataTransfer.files, $.proxy(function (url, isLast) {
                            if (isLast) {
                                this.reload();
                            }
                        }, this));
                    }
                }, this));

                this.load();
            },
            load: function () {
                this.loading = true;
                var loader = $.ajax({
                    url: '/admin/cms/media/api',
                    method: 'GET',
                    dataType: 'json'
                }).fail($.proxy(function (jqXHR, textStatus, errorThrown) {
                    window.Ignite.Core.flash(errorThrown, 'error');
                    this.loading = false;
                }, this)).done($.proxy(function (data) {
                    this.files = data;
                    this.loading = false;
                }, this));
            },
            reload: function () {
                this.load();
            },
            upload: function (files) {
                try {
                    window.MediaUpload(files, $.proxy(function (url, isLast) {
                        if (isLast) {
                            this.reload();
                        }
                    }, this));
                } catch (e) {
                    console.log(e);
                }
            },
            filteredFiles: function () {
                if (this.keywords === '') {
                    return this.files;
                }

                return this.files.filter($.proxy(function (file) {
                    return (file.name.toLowerCase().indexOf(this.keywords.toLowerCase(), 0) !== -1);
                }, this));
            },
            isImage: function (file) {
                return [
                    'png', 'jpg', 'jpeg', 'gif', 'bmp', 'svg', 'png'
                ].indexOf(file.extension) !== -1;
            },
            countSelected: function () {
                return this.selected.length === 1 ? 'file' : 'files';
            },
            isSelected: function (file) {
                return this.selected.indexOf(file.hash) !== -1;
            },
            toggleSelected: function (file, $event) {
                if (this.isSelected(file)) {
                    this.selected.splice(this.selected.indexOf(file.hash), 1);
                } else {
                    this.selected.push(file.hash);
                }
            },
            toggleSelectAll: function () {
                if (this.selected.length === 0) {
                    this.selected = $.map(this.filteredFiles(), function (file) {
                        return file.hash;
                    });
                } else {
                    this.selected = [];
                }
            },
            getSelectedFiles: function () {
                return this.files.filter($.proxy(function (file) {
                    return this.selected.indexOf(file.hash) !== -1;
                }, this));
            },
            open: function (url) {
                return window.open(url, '_blank');
            },
            download: function (files) {
                files = this.ensureArrayOfFiles(files);

                var formData = new FormData();
                formData.append('files', files.join(','));

                var downloader = $.ajax({
                    url: '/admin/cms/media/api/download',
                    method: 'POST',
                    dataType: 'json',
                    data: formData,
                    contentType: false,
                    processData: false,
                    headers: {
                        'X-CSRF-TOKEN': window.Laravel.csrfToken
                    },
                    beforeSend: function () {
                        $('#download-selected-label')
                            .html('Downloading <span class="fa-solid fa-refresh fa-spin fa-fw"></span>');
                    }
                }).fail(function (jqXHR, textStatus, errorThrown) {
                    window.Ignite.Core.flash(errorThrown, 'error');
                    $('#download-selected-label').html('Download');
                }).done($.proxy(function (data) {
                    $('#download-selected-label').html('Download');
                    this.downloadPrompt(data.url, data.filename);
                    this.selected = [];
                    window.Ignite.Core.flash('Your download is ready.', 'success');
                }, this));
            },
            downloadSelected: function () {
                this.download(this.selected);
            },
            downloadPrompt: function (url, filename) {
                var element = document.createElement('a');

                element.setAttribute('href', url);
                element.setAttribute('download', filename);

                element.style.display = 'none';
                document.body.appendChild(element);

                element.click();

                document.body.removeChild(element);
            },
            remove: function (files) {
                files = this.ensureArrayOfFiles(files);

                var formData = new FormData();
                formData.append('files', files.join(','));

                var remover = $.ajax({
                    url: '/admin/cms/media/api/delete',
                    method: 'POST',
                    data: formData,
                    contentType: false,
                    processData: false,
                    headers: {
                        'X-CSRF-TOKEN': window.Laravel.csrfToken
                    },
                    beforeSend: function () {
                        $('#delete-selected-label')
                            .html('Deleting <span class="fa-solid fa-refresh fa-spin fa-fw"></span>');
                    }
                }).fail(function (jqXHR, textStatus, errorThrown) {
                    window.Ignite.Core.flash(errorThrown, 'error');
                }).done($.proxy(function (data) {
                    $('#delete-selected-label').html('Delete');
                    window.Ignite.Core.flash(data.message, 'success');
                    this.selected = [];
                    this.reload();
                }, this));
            },
            removeFile: function (file) {
                if (window.confirm('Are you sure you want to delete this file?')) {
                    this.remove(file);
                }
            },
            removeSelected: function () {
                if (window.confirm('Are you sure you want to delete the selected ' + this.countSelected() + '?')) {
                    this.remove(this.selected.values());
                }
            },
            clipboard: function(value, $event) {
                var container = $('#media-modal').length ? $('#media-modal').get(0) : document.body;
                var textarea = document.createElement('textarea');

                container.appendChild(textarea);
                textarea.textContent = value;
                textarea.select();
                textarea.focus();

                var result = document.execCommand('copy');

                if (! result || result === 'unsuccessful') {
                    window.Ignite.Core.flash('Unable to copy to the clipboard!', 'error');
                } else {
                    window.Ignite.Core.flash('Copied to the clipboard!', 'success');
                }

                container.removeChild(textarea);
            },
            getEditor: function () {
                return $('.editor');
            },
            hasEditor: function () {
                return this.getEditor().length > 0;
            },
            insertSelectedIntoEditor: function () {
                this.guardAgainstNoEditor();

                var selectedFiles = this.getSelectedFiles();

                $.each(selectedFiles, $.proxy(function (idx, file) {
                    this.sendToEditor(file);
                }, this));

                this.hideEditorModal();
            },
            insertIntoEditor: function (file) {
                this.guardAgainstNoEditor();

                this.sendToEditor(file);

                this.hideEditorModal();
            },
            sendToEditor: function (file) {
                this.getEditor().summernote('focus');

                if (this.isImage(file)) {
                    this.getEditor().summernote('insertImage', file.url);
                } else {
                    this.getEditor().summernote('createLink', {
                        text: file.name,
                        url: file.url,
                        isNewWindow: true
                    });
                }
            },
            hideEditorModal: function () {
                // If we're in a modal, hide it now.
                var $media = $('#media-modal');
                if ($media.length) {
                    $media.modal('hide');
                }
            },
            guardAgainstNoEditor: function () {
                if (! this.hasEditor()) {
                    window.Ignite.Core.flash('No editor found.', 'error');
                    return;
                }
            },
            ensureArrayOfFiles: function (files) {
                if ('string' === $.type(files)) {
                    files = [files];
                }

                if (! $.isArray(files)) {
                    files = Array.from(files);
                }

                return files;
            }
        };
    };

} )(jQuery, window, document);