(function () {
    'use strict';

    var PRESETS = [
        'today',
        'yesterday',
        'last_7_days',
        'last_30_days',
        'this_month',
        'last_month',
        'custom',
    ];

    function pad(value) {
        return String(value).padStart(2, '0');
    }

    function dateText(date) {
        return (
            date.getFullYear() +
            '-' +
            pad(date.getMonth() + 1) +
            '-' +
            pad(date.getDate())
        );
    }

    function localDate(value) {
        if (value instanceof Date) {
            return new Date(
                value.getFullYear(),
                value.getMonth(),
                value.getDate()
            );
        }
        var match = String(value || '').match(/^(\d{4})-(\d{2})-(\d{2})$/);
        if (!match) return null;
        var date = new Date(
            Number(match[1]),
            Number(match[2]) - 1,
            Number(match[3])
        );
        return Number.isNaN(date.getTime()) ? null : date;
    }

    function addDays(date, count) {
        return new Date(
            date.getFullYear(),
            date.getMonth(),
            date.getDate() + count
        );
    }

    function createRange(preset, options) {
        var name = PRESETS.indexOf(preset) >= 0 ? preset : 'today';
        var opts = options || {};
        var now = localDate(opts.now || new Date());
        var start = now;
        var end = now;

        if (name === 'yesterday') start = end = addDays(now, -1);
        else if (name === 'last_7_days') start = addDays(now, -6);
        else if (name === 'last_30_days') start = addDays(now, -29);
        else if (name === 'this_month')
            start = new Date(now.getFullYear(), now.getMonth(), 1);
        else if (name === 'last_month') {
            start = new Date(now.getFullYear(), now.getMonth() - 1, 1);
            end = new Date(now.getFullYear(), now.getMonth(), 0);
        } else if (name === 'custom') {
            start = localDate(opts.start);
            end = localDate(opts.end);
            if (!start || !end || start.getTime() > end.getTime()) {
                throw new Error('Invalid custom date range');
            }
        }

        // UI 和 API 都使用包含首尾的自然日；在线时长等跨日指标由服务端按业务时区切日，前端不自行累计秒数。
        return Object.freeze({
            preset: name,
            startDate: dateText(start),
            endDate: dateText(end),
        });
    }

    window.HyGuild = window.HyGuild || {};
    window.HyGuild.dateRange = {
        presets: Object.freeze(PRESETS.slice()),
        create: createRange,
    };
})();
