Com.Frog.Utils.require(
    '//package/widgets/58413FE62001B3FBB96D0FC164D6FB0D6C32DDFCA0893A38/assets/styles/main.css',
    '//package/widgets/58413FE62001B3FBB96D0FC164D6FB0D6C32DDFCA0893A38/assets/views/main.ejs',
    '//package/widgets/58413FE62001B3FBB96D0FC164D6FB0D6C32DDFCA0893A38/assets/views/row.ejs',
    '//package/widgets/58413FE62001B3FBB96D0FC164D6FB0D6C32DDFCA0893A38/widget.ejs'
).then(function() {
    Com.Frog.Controllers.Widget.extend('Widget.CalendarPlanner', {
    }, {
        prefs: {
            title: {
                type: 'text',
                defaultValue: 'My To Do List',
                label: 'Title',
                accordion: 'Terminology'
            },
            eventTitle: {
                type: 'text',
                defaultValue: 'Item Name',
                label: 'Item Title',
                accordion: 'Terminology'
            },
            eventDueDateTitle: {
                type: 'text',
                defaultValue: 'Due Date',
                label: 'Due Date Title',
                accordion: 'Terminology'
            },
            addLabel: {
                type: 'text',
                defaultValue: 'Add to To-Do List',
                label: 'Add event button',
                accordion: 'Terminology'
            },
            updateLabel: {
                type: 'text',
                defaultValue: 'Update item',
                label: 'Update item button',
                accordion: 'Terminology'
            },
            noteLabel: {
                type: 'text',
                defaultValue: 'Notes',
                label: 'Notes area',
                accordion: 'Terminology'
            },
            todoTab: {
                type: 'text',
                defaultValue: 'To Do',
                label: 'To Do Tab label',
                accordion: 'Terminology'
            },
            doneTab: {
                type: 'text',
                defaultValue: 'Done',
                label: 'Done Tab label',
                accordion: 'Terminology'
            },
            dateFormat: {
                type: 'radio',
                defaultValue: 'DD/MM/YYYY',
                label: 'Display dates as:',
                vertical: true,
                options: {
                    '01/03/2022': 'DD/MM/YYYY',
                    '01-03-2022': 'DD-MM-YYYY',
                    '03-01-2022': 'MM-DD-YYYY',
                    '1st Mar 2022': 'Do MMM YYYY',
                    'Monday, 1st March 2022': 'dddd, Do MMMM YYYY',
                    "Mon, 1st Mar '22": "ddd, Do MMM 'YY"
                },
                publish: [],
                accordion: 'Advanced'
            },
            howFarBack: {
                type: 'number',
                label: 'How far back should the To-Do list go?',
                defaultValue: 90,
                showUnits: 'Days',
                accordion: 'Advanced'
            },
            displayDelete: {
                type: 'boolean',
                label: 'Display Delete button (users can still delete from their calendars)',
                defaultValue: true
            }
        },
        calendarUUID: '',
        currentUser: '',
        todoChars: {todo:'\u200B ',done:'\uFEFF '},
        
        packageID: '58413FE62001B3FBB96D0FC164D6FB0D6C32DDFCA0893A38',

        init: function() {},

        'widget.live': function(el, ev, data) {
            this.element.html(
                this.view('main.ejs')
            );
            this.element.find('.event_date').val(moment().format('YYYY-MM-DD'));
            this.accessCheck();

            this.getCalendar(this.currentUser.uuid);
        },
        getCalendar: function(stuUUID) {
            var self = this;
            FrogOS.fdp({
                url: 'calendar/get',
                path: '/api/fdp/1/',
                data: {
                    user_uuid: stuUUID
                }
            }).done(function(response) {
                var data = response.response;
                $.each(data[stuUUID],function(index,calendar) {
                    if (calendar.type == 'personal') {
                        self.calendarUUID = calendar.id;
                        self.switchButtons();
                        self.listEvents();
                    }
                });
            }).fail(function(e) {
                // Report Error
                self.growlMsg('Error - Failed to get calendar.');
            });
        },
        
        listEvents: function() {
            var self = this;
            var currentList = self.element.find('.current_list');
            var doneList = self.element.find('.done_list');
            currentList.empty();
            doneList.empty();

            FrogOS.fdp({
                url: 'calendar/event/get',
                path: '/api/fdp/1/',
                data: {
                    calendar_uuids: [self.calendarUUID],
                    starttime: moment().unix()-(60*60*24*self.prefs.howFarBack.value)
                }
            }).done(function(response) {
                var data = response.response;
                $.each(data, function(index,event) {

                    if (event.title.indexOf(self.todoChars.todo) > -1 || event.title.indexOf(self.todoChars.done) > -1) {
                       
                        var checked = '';
                        if (event.title.indexOf(self.todoChars.done) > -1) {
                            checked = 'checked';
                        };
                        var item = {
                             uuid: event.uuid,
                             title: event.title.replace(self.todoChars.todo,'').replace(self.todoChars.done,''),
                             note: self.replaceURLWithHTMLLinks(event.description),
                             note_clean: event.description.replaceAll('"','|').replaceAll("'","`"),
                             dueDate: moment.unix(event.starttime).format(self.prefs.dateFormat.value),
                             checked: checked
                        };

                        if (checked == '') {
                            currentList.append(
                                self.view('row.ejs',item)
                            );
                        } else {
                            doneList.append(
                                self.view('row.ejs',item)
                            );
                        };         
                    }
                });

            }).fail(function(e) {
                // Report Error
                self.growlMsg('Error - Failed to get calender events.');
            });
        },
 
        addToCalendar: function() {
            var self = this;

            var event_date = self.element.find('.event_date').val();
            var dueDate = moment(event_date).unix();
            var endTime = moment(event_date).add(1, 'd').unix();
            var title = self.todoChars.todo+self.element.find('.event_title').val();
            var description = self.element.find('.event_notes').val();

            FrogOS.fdp({
                url: 'calendar/event/create',
                path: '/api/fdp/1/',
                type: 'POST',
                data: {
                    starttime: dueDate,
                    endtime: endTime,
                    title: title,
                    description: description,
                    target: self.calendarUUID,
                    allday: true
                }
            }).done(function(response) {
                self.resetForm();                
            }).fail(function(e) {
                self.growlMsg('Error - Failed to create item.');
            });
        },
        
        markDone: function(eventUuid,title,checked) {
            var self = this;            
            if (checked === true) {
                var newtitle = self.todoChars.done+title;
            } else {
                var newtitle = self.todoChars.todo+title;
            }

            FrogOS.fdp({
                url: 'calendar/event/update',
                path: '/api/fdp/1/',
                type: 'POST',
                data: {
                    uuid: eventUuid,
                    title: newtitle
                }
            }).done(function(response) {
                self.listEvents();
            }).fail(function(e) {
                self.growlMsg('Error - Failed to update item.');
            });
        },
                
        accessCheck: function() {
            var user = FrogOS ? FrogOS.getUser() : this.getUser();
            this.currentUser = user;
            if (['Staff', 'Admin', 'Super User'].includes(user.profile.name)) {
                return true;
            } else {
                return false;
            }
        },
        '.add click': function() {
            this.addToCalendar();
        },
        '.update click': function() {
            this.updateCalendar();
        }, 
        '.item_title click': function (event,target) {
            var itemUuid = event.data('itemuuid');
            this.element.find('.item_note.'+itemUuid).toggle();     
        },
        '.checked click': function (event,target) {
            var eventUuid = event[0].dataset.uuid;
            var eventTitle = event[0].dataset.title;
            var checked = event[0].checked;

            this.markDone(eventUuid,eventTitle,checked);
        },
        '.edit_link click': function (event,target) {   
            var itemUuid = event.data('itemuuid');
            var title = event.data('title');
            var note = event.data('note').replaceAll('|','"').replaceAll("`","'");
            var dueDate = event.data('duedate');

            this.element.find('.event_uuid').val(itemUuid);
            this.element.find('.event_title').val(title);
            this.element.find('.event_notes').val(note);
            this.element.find('.event_date').val(moment(dueDate, 'DD/MM/YYYY').format('YYYY-MM-DD'));
            this.switchButtons();
        },
        '.cancel click': function (event,target) {  
            this.resetForm();
        },
        '.update click': function (event,target) {  
            var self = this;
            var eventUuid = self.element.find('.event_uuid').val();
            var dueDate = moment(self.element.find('.event_date').val()).unix();
            var title = self.todoChars.todo+self.element.find('.event_title').val();
            var description = self.element.find('.event_notes').val();
            FrogOS.fdp({
                url: 'calendar/event/update',
                path: '/api/fdp/1/',
                type: 'POST',
                data: {
                    uuid: eventUuid,
                    title: title,
                    starttime: dueDate,
                    description: description
                }
            }).done(function(response) {
                self.resetForm();
            }).fail(function(e) {
                // Report Error
                self.growlMsg('Error - Failed to update item.');
            });
        },
        '.delete_check click': function (event,target) {  
            var itemUuid = event.data('itemuuid');
            this.element.find('.delete_link.'+itemUuid).show();
            this.element.find('.delete_check.'+itemUuid).hide();
            this.element.find('.delete_cancel.'+itemUuid).show();
            this.element.find('.edit_delete.'+itemUuid).css('width', '50%');
            this.element.find('.item_name.'+itemUuid).css('width', '40%');
        },
        '.delete_cancel click': function (event,target) {  
            var itemUuid = event.data('itemuuid');
            this.element.find('.delete_link.'+itemUuid).hide();
            this.element.find('.delete_check.'+itemUuid).show();
            this.element.find('.delete_cancel.'+itemUuid).hide();
            this.element.find('.edit_delete.'+itemUuid).css('width', '20%');
            this.element.find('.item_name.'+itemUuid).css('width', '75%');
        },
        '.delete_link click': function (event,target) {  
            var self = this;
            var itemUuid = event.data('itemuuid');
            
            $.ajax({
              type: 'POST',
              url: '/app/calendar/AjaxDeleteAppt',
              data: {
                  id: itemUuid, 
                  calendarId: self.calendarUUID
              }
            }).done(function(data){
                self.listEvents();
            });
        },
        waitForAjax: function() {
            var self = this;
            setTimeout(self.listEvents(), 3000);
        },
        
        '.list_tab_todo click': function (event,target) {
            this.element.find('.list_tab_todo').addClass('active');
            this.element.find('.list_tab_done').removeClass('active');
            this.element.find('.current_list').show();
            this.element.find('.done_list').hide();
        },
        '.list_tab_done click': function (event,target) {
            this.element.find('.list_tab_todo').removeClass('active');
            this.element.find('.list_tab_done').addClass('active');
            this.element.find('.current_list').hide();
            this.element.find('.done_list').show();
        },
        switchButtons: function() {
            var addButton = this.element.find('.add');
            var updateButton = this.element.find('.update');
            if (addButton.hasClass('visible')) {
                addButton.removeClass('visible');
                addButton.addClass('hide');
                updateButton.removeClass('hide');
                updateButton.addClass('visible');
            } else {
                addButton.addClass('visible');
                addButton.removeClass('hide');
                updateButton.addClass('hide');
                updateButton.removeClass('visible');
            }
        },
        resetForm: function() {
            if (this.element.find('.event_uuid').val() !== '') {
                this.switchButtons();
                this.element.find('.event_uuid').val('');
            }
            this.element.find('.event_title').val('');
            this.element.find('.event_notes').val('');
            this.listEvents();
        },
        
        replaceURLWithHTMLLinks: function(string) { // turn any https into links
            var exp = /(\b(https?|ftp|file):\/\/[-A-Z0-9+&@#\/%?=~_|!:,.;]*[-A-Z0-9+&@#\/%=~_|])/ig;
            return string.replace(exp,'<a target="_blank" class="note_link" href="$1">$1</a>'); 
        },
        
        'broadcast.selectedUser': function(el, ev, options) {
            this.currentUser = options.model.attr('uuid');
            this.getCalendar(this.currentUser);
            this.element.find('.who').empty();
            this.element.find('.who').prepend(
                options.model.attr('displayname')+"'s "+
                this.prefs.title.value
            );
            this.switchButtons();
        },
        
        growlMsg: function(string) {
            Frog.Controller.prototype.growl(string,'To-Do List','app-name',{time:5000, icon: 'externalapps/icon/'+self.packageID});
        },       
        
        'widget.edit': function(el, ev, data) {
            this.element.html(
                this.view('./widget.ejs')
            );
        },
        'widget.updated': function(el, ev, data) {}
    });
});
