var i18n = require('../common/i18n');
var moment = require('moment');

const ELAPSED_TIME_COMPONENTS = [
    'years', 'months', 'days',
    'hours', 'minutes', 'seconds', 'milliseconds'
];

function elapsed(date, options) {
    moment.locale(i18n.getLocale(options));
    var duration = moment.duration(moment(Date.now()).diff(date));

    if (!duration)
        return;

    if (options.hash.full)
        return duration.humanize();

    if (options.hash.serialized)
        return JSON.stringify(duration._data);

    var output = '';
    var dictionary = i18n.getDictionary(options);
    var delimiter = options.hash.exact ? '' : '\u202f';

    for (let i = 0; i < ELAPSED_TIME_COMPONENTS.length - 1 && (!output || options.hash.exact); i++) {
        let key = ELAPSED_TIME_COMPONENTS[i];
        let component = duration.get(key);

        if (component && !Number.isNaN(component)) {
            let suffix = dictionary.pick('date.elapsed_time_suffix.' + key);
            output += (output ? ' ' : '') + component + delimiter + suffix;
        }
    }

    return output ? ('+' + output) : '';
}

function age(birthDate, options) {
    var dictionary = i18n.getDictionary(options);
    var age = birthDate ? moment(Date.now()).diff(birthDate, 'years') : null;

    if (age === null)
        return null;

    if (age >= 0 && age < 1)
        return dictionary.pick('common.age.less_than_year_old');

    return dictionary.pluralize(age, dictionary.pick('common.age.years'));
}

function birth_date(date, options) {
    moment.locale(i18n.getLocale(options));
    return date === undefined || date === null ? null : moment(date).format('L');
}

function short_date(x) {
    if (x === null || x === undefined)
        return '';

    var d = x instanceof Date ? x : new Date(x);

    if (Number.isNaN(d.getTime()))
        return '';

    return [ d.getFullYear(), d.getMonth() + 1, d.getDate() ]
        .map(value => (value < 10 ? '0' : '') + value)
        .join('-');
}

function html_date(x) {
    if (x === null || x === undefined)
        return '';

    var d = x instanceof Date ? x : new Date(x);
    var zeroPad = value => (value < 10 ? '0' : '') + value;

    if (Number.isNaN(d.getTime()))
        return '\u2715';

    var date = [ d.getFullYear(), d.getMonth() + 1, d.getDate() ]
        .map(zeroPad).join('-');

    var time = [ d.getHours(), d.getMinutes(), d.getSeconds() ]
        .map(zeroPad).join(':');

    var tzOffset = { value: d.getTimezoneOffset() };
    tzOffset.absValue = Math.abs(tzOffset.value);
    tzOffset.hours = Math.floor(tzOffset.absValue/60);
    tzOffset.sign = tzOffset.value > 0 ? '-' : '+';

    var timeZone = [ tzOffset.hours, Math.floor(tzOffset.absValue - 60*tzOffset.hours) ]
        .map(zeroPad).join(':');

    return [
        `<span class="date">${date}</span>`,
        `<span class="time">${time}</span>`,
        `<span class="timezone">${tzOffset.sign}${timeZone}</span>`
    ].join(' ');
}

module.exports = {
    elapsed, age, birth_date, short_date, html_date
};
