// This file is used when a user tries to export the entire CryptDrive.
// Calendars will be exported using this format instead of plain text.
define([
    '/customize/pages.js',
], function (Pages) {
    var module = {};

    var getICSDate = function (str) {
        var date = new Date(str);

        var m = date.getUTCMonth() + 1;
        var d = date.getUTCDate();
        var h = date.getUTCHours();
        var min = date.getUTCMinutes();

        var year = date.getUTCFullYear().toString();
        var month = m < 10 ? "0" + m : m.toString();
        var day = d < 10 ? "0" + d : d.toString();
        var hours = h < 10 ? "0" + h : h.toString();
        var minutes = min < 10 ? "0" + min : min.toString();

        return year + month + day + "T" + hours + minutes + "00Z";
    };


    var getDate = function (str, end) {
        var date = new Date(str);
        if (end) {
            date.setDate(date.getDate() + 1);
        }
        var m = date.getUTCMonth() + 1;
        var d = date.getUTCDate();

        var year = date.getUTCFullYear().toString();
        var month = m < 10 ? "0" + m : m.toString();
        var day = d < 10 ? "0" + d : d.toString();

        return year+month+day;
    };

    var MINUTE = 60;
    var HOUR = MINUTE * 60;
    var DAY = HOUR * 24;


    module.main = function (userDoc) {
        var content = userDoc.content;

        var ICS = [
            'BEGIN:VCALENDAR',
            'VERSION:2.0',
            'PRODID:-//CryptPad//CryptPad Calendar '+Pages.versionString+'//EN',
            'METHOD:PUBLISH',
        ];

        Object.keys(content).forEach(function (uid) {
            var data = content[uid];
            // DTSTAMP: now...
            // UID: uid
            var start, end;
            if (data.isAllDay && data.startDay && data.endDay) {
                start = "DTSTART;VALUE=DATE:" + getDate(data.startDay);
                end = "DTEND;VALUE=DATE:" + getDate(data.endDay, true);
            } else {
                start = "DTSTART:"+getICSDate(data.start);
                end = "DTEND:"+getICSDate(data.end);
            }

            Array.prototype.push.apply(ICS, [
                'BEGIN:VEVENT',
                'DTSTAMP:'+getICSDate(+new Date()),
                'UID:'+uid,
                start,
                end,
                'SUMMARY:'+ data.title,
                'LOCATION:'+ data.location,
            ]);

            if (Array.isArray(data.reminders)) {
                data.reminders.forEach(function (valueMin) {
                    var time = valueMin * 60;
                    var days = Math.floor(time / DAY);
                    time -= days * DAY;
                    var hours = Math.floor(time / HOUR);
                    time -= hours * HOUR;
                    var minutes = Math.floor(time / MINUTE);
                    time -= minutes * MINUTE;
                    var seconds = time;

                    var str = "-P" + days + "D";
                    if (hours || minutes || seconds) {
                        str += "T" + hours + "H" + minutes + "M" + seconds + "S";
                    }
                    Array.prototype.push.apply(ICS, [
                        'BEGIN:VALARM',
                        'ACTION:DISPLAY',
                        'DESCRIPTION:This is an event reminder',
                        'TRIGGER:'+str,
                        'END:VALARM'
                    ]);
                });
            }

            if (Array.isArray(data.cp_hidden)) {
                Array.prototype.push.apply(ICS, data.cp_hidden);
            }

            ICS.push('END:VEVENT');
        });

        ICS.push('END:VCALENDAR');

        return new Blob([ ICS.join('\n') ], { type: 'text/calendar;charset=utf-8' });
    };

    module.import = function (content, id, cb) {
        require(['/lib/ical.min.js'], function () {
            var ICAL = window.ICAL;
            var res = {};

            var vcalendar;
            try {
                var jcalData = ICAL.parse(content);
                vcalendar = new ICAL.Component(jcalData);
            } catch (e) {
                console.error(e);
                return void cb(e);
            }

            //var method = vcalendar.getFirstPropertyValue('method');
            //if (method !== "PUBLISH") { return void cb('NOT_SUPPORTED'); }

            // Add all timezones in iCalendar object to TimezoneService
            // if they are not already registered.
            var timezones = vcalendar.getAllSubcomponents("vtimezone");
            timezones.forEach(function (timezone) {
                if (!(ICAL.TimezoneService.has(timezone.getFirstPropertyValue("tzid")))) {
                    ICAL.TimezoneService.register(timezone);
                }
            });

            var events = vcalendar.getAllSubcomponents('vevent');
            events.forEach(function (ev) {
                var uid = ev.getFirstPropertyValue('uid');
                if (!uid) { return; }

                // Get start and end time
                var isAllDay = false;
                var start = ev.getFirstPropertyValue('dtstart');
                var end = ev.getFirstPropertyValue('dtend');
                var duration = ev.getFirstPropertyValue('duration');
                if (!end && !duration) {
                    if (start.isDate) {
                        end = start.clone();
                        end.adjust(1); // Add one day
                    } else {
                        end = start.clone();
                    }
                } else if (!end) {
                    end = start.clone();
                    end.addDuration(duration);
                }
                if (start.isDate && end.isDate) {
                    isAllDay = true;
                    start = String(start);
                    end.adjust(-1); // Substract one day
                    end = String(end);
                } else {
                    start = +start.toJSDate();
                    end = +end.toJSDate();
                }

                // Store other properties
                var used = ['dtstart', 'dtend', 'uid', 'summary', 'location', 'dtstamp'];
                var hidden = [];
                ev.getAllProperties().forEach(function (p) {
                    if (used.indexOf(p.name) !== -1) { return; }
                    // This is an unused property
                    hidden.push(p.toICALString());
                });

                // Get reminders
                var reminders = [];
                ev.getAllSubcomponents('valarm').forEach(function (al) {
                    var action = al.getFirstPropertyValue('action');
                    if (action !== 'DISPLAY') {
                        // Email notification: keep it in "hidden" and create a cryptpad notification
                        hidden.push(al.toString());
                    }
                    var trigger = al.getFirstPropertyValue('trigger');
                    var minutes = trigger ? (-trigger.toSeconds() / 60) : 0;
                    if (reminders.indexOf(minutes) === -1) { reminders.push(minutes); }
                });

                // Create event
                res[uid] = {
                    calendarId: id,
                    id: uid,
                    category: 'time',
                    title: ev.getFirstPropertyValue('summary'),
                    location: ev.getFirstPropertyValue('location'),
                    isAllDay: isAllDay,
                    start: start,
                    end: end,
                    reminders: reminders,
                    cp_hidden: hidden
                };

                if (!hidden.length) { delete res[uid].cp_hidden; }
                if (!reminders.length) { delete res[uid].reminders; }

            });

            cb(null, res);
        });
    };

    return module;
});