var request = require('request');
var log4js = require('log4js');
var logger = log4js.getLogger();
var STRING = require('string');
var util = require('util');
var Elapsed = require('elapsed');
require('sugar-date');

function processICAL(ical) {
  'use strict';
  logger.info('+ processICAL');
  var workingBlock = [];
  var segments = {
    meetingStartID: 'DTSTART;TZID=Europe/London:',
    meetingStartAlt: 'DTSTART:',
    meetingEndID: 'DTEND;TZID=Europe/London:',
    meetingEndAlt: 'DTEND:',
    meetingDescID: 'DESCRIPTION:',
    summaryID: 'SUMMARY:',
    begin: 'BEGIN:VEVENT',
    end: 'END:VEVENT',
    beginAlarm: 'BEGIN:VALARM',
    recur: 'RRULE'
  };

  function processBlock(block) {
    var workBlock = {
      summary: '',
      dtstart: null,
      dtend: null,
      description: '',
      timeStart: null,
      timeEnd: null,
      duration: 0,
      combined: ''
    };
    var alarmFlag = false, ws, blockStep;
    for (var step = 0; step < block.length; step++) {
      blockStep = block[step];
      if (blockStep.indexOf(segments.summaryID) >= 0) {
        workBlock.summary = STRING(block[step].split(segments.summaryID)[1]).collapseWhitespace().s;
      }
      if (blockStep.indexOf(segments.meetingStartID) >= 0) {
        ws = STRING(block[step].split(segments.meetingStartID)[1]).collapseWhitespace().s;
        workBlock.dtstart = Date.create(ws);
      }
      if (blockStep.indexOf(segments.meetingEndID) >= 0) {
        ws = STRING(block[step].split(segments.meetingEndID)[1]).collapseWhitespace().s;
        workBlock.dtend = Date.create(ws);
      }
      if (blockStep.indexOf(segments.meetingStartAlt) >= 0) {
        ws = STRING(block[step].split(segments.meetingStartAlt)[1]).collapseWhitespace().s;
        workBlock.dtstart = Date.create(ws);
      }
      if (blockStep.indexOf(segments.meetingEndAlt) >= 0) {
        ws = STRING(block[step].split(segments.meetingEndAlt)[1]).collapseWhitespace().s;
        workBlock.dtend = Date.create(ws);
      }
      if (blockStep.indexOf(segments.meetingDescID) >= 0) {
        if (!alarmFlag) {
          workBlock.description = STRING(block[step].split(segments.meetingDescID)[1]).collapseWhitespace().s;
        }
      }
      if (blockStep.indexOf(segments.beginAlarm) >= 0) {
        alarmFlag = true;
      }
    }

    if (workBlock.dtstart !== null) {
      workBlock.timeStart = workBlock.dtstart.format('{24hr}:{mm}:{ss}');
      workBlock.combined = '<em>' + workBlock.timeStart + '</em> - ';
      workBlock.long = '<em>' + workBlock.dtstart.format('{Weekday}') +', ' + workBlock.timeStart + '</em> - ';
    }
    workBlock.combined = workBlock.combined + workBlock.summary;
    workBlock.longcombined = workBlock.long + workBlock.summary;
    if (workBlock.dtend !== null) {
      workBlock.timeEnd = workBlock.dtend.format('{24hr}:{mm}:{ss}');
    }
    if (workBlock.dtstart !== null && workBlock.dtend !== null) {
      var elapsedTime = new Elapsed(workBlock.dtstart, workBlock.dtend);
      workBlock.duration = elapsedTime.optimal;
      workBlock.combined = workBlock.combined + ', ' + elapsedTime.optimal;
      workBlock.longcombined = workBlock.longcombined + ', ' + elapsedTime.optimal;
    }

    return workBlock;
  }

  var lines = ical.split('\r\n'), l = lines.length, counter = 0;

  while (counter < l) {
    if (lines[counter].indexOf(segments.begin) < 0) {
      counter++;
    } else {
      var subcounter = 0, subBlock = [];
      while (subcounter < 75) {
        if (lines[counter + subcounter].indexOf(segments.end) < 0) {
          subBlock.push(lines[counter + subcounter]);
          subcounter++;
        }        else {
          break;
        }
      }
      counter = counter + subcounter;
      var b = processBlock(subBlock);
      if (b.dtstart !== null) {
        workingBlock.push(b);
      }

    }
  }
  logger.info('- processICAL');
  // If (workingBlock.dtstart == null) return {};

  return workingBlock;
}

module.exports = {
  calendars: ['https://calendar.google.com/calendar/ical/martind2000%40gmail.com/private-40cfebc9f7dcfa7fde6b9bf2f0092c93/basic.ics',
             'https://calendar.google.com/calendar/ical/mt5pgdhknvgoc8usfnrso9vkv0%40group.calendar.google.com/private-58876002af9f302a593acfa6fa792dcf/basic.ics',
             'https://www.tripit.com/feed/ical/private/DB96E4BB-94A9BD8F9CC1CF51C6CC0D920840F4F5/tripit.ics',
             'https://calendar.google.com/calendar/ical/en.uk%23holiday%40group.v.calendar.google.com/public/basic.ics',
              'https://calendar.google.com/calendar/ical/i8dglj12p5nuv20sbjmun5s588%40group.calendar.google.com/private-c8adccb41e56d6a2f285078aaed313f5/basic.ics'],
  jsonBlock: [],
  getTodaysSimple: function() {
    'use strict';
    logger.info('+ getTodaysSimple');
    var today = {
      entries: []
    };

    for (var t = 0; t < this.jsonBlock.length; t++) {
      if (this.jsonBlock[t].dtstart.isToday()) {

        today.entries.push(this.jsonBlock[t]);
      }
    }
    logger.info('- getTodaysSimple');
    return today;
  },
  getTomorrow: function() {
      'use strict';
      logger.info('+ getTomorrow');
      var today = {
        entries: []
      };

      for (var t = 0; t < this.jsonBlock.length; t++) {
        if (this.jsonBlock[t].dtstart.isTomorrow()) {

          today.entries.push(this.jsonBlock[t]);
        }
      }
      logger.info('- getTomorrow');
      return today;
    },
  getWeek: function() {
        'use strict';
        logger.info('+ getWeek');
        var today = {
          entries: []
        };
  var now, twoDays, sevenDays;

    now = Date.create('today');
    logger.debug(now);
    twoDays = Date.create(now).addDays(2).beginningOfDay();
    logger.debug(twoDays);
    sevenDays = Date.create(twoDays).addDays(5).beginningOfDay();

    logger.debug(now, twoDays, sevenDays);

        for (var t = 0; t < this.jsonBlock.length; t++) {
          if (this.jsonBlock[t].dtstart.isBetween(twoDays, sevenDays)) {

            today.entries.push(this.jsonBlock[t]);
          }
        }
        logger.info('- getWeek');
        return today;
      },
  getTodaysMeetings: function() {
    'use strict';
    logger.info('+ getTodaysMeetings');
    var today = {
      previous: [], upcoming: [], current: {}
    };
    var now = new Date();

    for (var t = 0; t < this.jsonBlock.length; t++) {
      if (this.jsonBlock[t].dtstart.isToday()) {

        if (this.jsonBlock[t].dtstart.isAfter(now)) {
          today.upcoming.push(this.jsonBlock[t]);
        }        else {
          today.previous.push(this.jsonBlock[t]);
        }

        if (now.isBetween(this.jsonBlock[t].dtstart, this.jsonBlock[t].dtend)) {
          today.current = this.jsonBlock[t];
        }
      }
    }
    //     logger.debug(today);
    logger.info('- getTodaysMeetings');
    return today;
  }, getSimpleCalV2: function(url, cb) {
    'use strict';
    var self = this;

    // Var calJson = [];
    try {
      request(url, function(err, res, body) {
        if (err) {
          logger.error('Get remote Calendar Request failed');
          // Callback.call(null, new Error('Request failed'));
          return;
        }

        self.jsonBlock = processICAL(body);

        // logger.debug(self.jsonBlock);
        var st = self.getTodaysSimple();

        if (typeof cb === 'function') {
          cb(st);
        }
      }, function(error, response, body) {
        if (response.statusCode !== 200) {
          logger.error(response.statusCode);
          logger.error(body);
        }
      });
    } catch (e) {
      console.log(e);
    }

  }, getSimpleCalV3: function(url) {
    'use strict';
    var self = this;

    return new Promise(function(resolve, reject) {
      try {
        request(url, function(err, res, body) {
          if (err) {
            //  logger.error(err);
            return reject(err);
            // Throw err;
          }

          self.jsonBlock = processICAL(body);

          // logger.debug(self.jsonBlock);
          var st = self.getTodaysSimple();

          return resolve(st);
        }, function(error, response, body) {
          if (response.statusCode !== 200) {
            logger.error(response.statusCode);
            logger.error(body);
            return reject(error);
          }
        });
      } catch (e) {
        console.log(e);
        return reject(e);
      }

    });

    // Var calJson = [];

  }, getAdvancedCalV3: function(url) {
      'use strict';
      var self = this;

      return new Promise(function(resolve, reject) {
        try {
          request(url, function(err, res, body) {
            if (err) {
              //  logger.error(err);
              return reject(err);
              // Throw err;
            }

            self.jsonBlock = processICAL(body);

            // logger.debug(self.jsonBlock);
            var st = self.getTodaysSimple().entries;
            var tom = self.getTomorrow().entries;
            var week = self.getWeek().entries;


            var obj = {today:st, tomorrow:tom, week:week};

            logger.debug(obj);
            return resolve(obj);
          }, function(error, response, body) {
            if (response.statusCode !== 200) {
              logger.error(response.statusCode);
              logger.error(body);
              return reject(error);
            }
          });
        } catch (e) {
          console.log(e);
          return reject(e);
        }

      });

      // Var calJson = [];

    }



  /**
   * Created by Martin on 16/02/2016.
   */
};
