// ============================================
// NOTIFIER - Shared UI Utilities
// ============================================

// ----- DATE/TIME UTILITIES -----
const DateUtils = {
    getTimezone() {
        return window.__APP_CONFIG__?.timezone || 'UTC';
    },

    parseUtc(value) {
        if (value instanceof Date) return value;
        if (typeof value === 'number') return new Date(value);
        if (typeof value !== 'string') return new Date(NaN);

        const trimmed = value.trim();
        if (!trimmed) return new Date(NaN);

        const match = trimmed.match(/^(\d{4})-(\d{2})-(\d{2})(?:[ T](\d{2}):(\d{2})(?::(\d{2}))?)?$/);
        if (match) {
            const year = Number(match[1]);
            const month = Number(match[2]) - 1;
            const day = Number(match[3]);
            const hour = Number(match[4] || 0);
            const minute = Number(match[5] || 0);
            const second = Number(match[6] || 0);
            return new Date(Date.UTC(year, month, day, hour, minute, second));
        }

        return new Date(trimmed);
    },

    formatDate(dateStr, options = {}) {
        const date = this.parseUtc(dateStr);
        if (Number.isNaN(date.getTime())) return String(dateStr);
        const defaultOptions = {
            weekday: 'short',
            month: 'short',
            day: 'numeric',
            year: 'numeric'
        };
        return new Intl.DateTimeFormat('en-US', {
            timeZone: this.getTimezone(),
            ...defaultOptions,
            ...options
        }).format(date);
    },

    formatTime(dateStr) {
        const date = this.parseUtc(dateStr);
        if (Number.isNaN(date.getTime())) return String(dateStr);
        return new Intl.DateTimeFormat('en-US', {
            timeZone: this.getTimezone(),
            hour: '2-digit',
            minute: '2-digit'
        }).format(date);
    },

    formatDateTime(dateStr) {
        return `${this.formatDate(dateStr)} at ${this.formatTime(dateStr)}`;
    },

    formatRelative(dateStr) {
        const date = this.parseUtc(dateStr);
        if (Number.isNaN(date.getTime())) return String(dateStr);

        const diffMs = date.getTime() - Date.now();
        const absMs = Math.abs(diffMs);
        const minute = 1000 * 60;
        const hour = minute * 60;
        const day = hour * 24;

        if (diffMs >= 0) {
            if (diffMs < minute) return 'In 1 min';
            if (diffMs < hour) return `In ${Math.ceil(diffMs / minute)} min`;
            if (diffMs < day) return `In ${Math.ceil(diffMs / hour)} hours`;
            const days = Math.ceil(diffMs / day);
            if (days === 1) return 'Tomorrow';
            if (days < 7) return `In ${days} days`;
            if (days < 30) return `In ${Math.ceil(days / 7)} weeks`;
            return this.formatDate(dateStr);
        }

        if (absMs < minute) return 'Just now';
        if (absMs < hour) return `${Math.ceil(absMs / minute)} min ago`;
        if (absMs < day) return `${Math.ceil(absMs / hour)} hours ago`;

        const days = Math.ceil(absMs / day);
        return `${days} days ago`;
    },

    formatOffset(days, hours, minutes) {
        const parts = [];
        if (days > 0) parts.push(`${days}d`);
        if (hours > 0) parts.push(`${hours}h`);
        if (minutes > 0) parts.push(`${minutes}m`);
        return '+' + (parts.length ? parts.join(' ') : '0m');
    },

    // Calculate next 4 occurrences for preview
    calculateNextDates(recurrence, count = 4) {
        const dates = [];
        let current = new Date();

        for (let i = 0; i < count && i < 100; i++) {
            const next = this.getNextOccurrence(recurrence, current);
            if (!next) break;
            dates.push(next);
            current = new Date(next.getTime() + 60000); // +1 min to get next
        }

        return dates;
    },

    getNextOccurrence(recurrence, after = new Date()) {
        const [hours, minutes] = (recurrence.time_of_day || '09:00').split(':').map(Number);
        let date = new Date(after);
        date.setHours(hours, minutes, 0, 0);

        if (date <= after) {
            date.setDate(date.getDate() + 1);
        }

        switch (recurrence.type) {
            case 'daily':
                return date;

            case 'weekly':
                const weekdays = recurrence.weekdays || [1];
                for (let i = 0; i < 7; i++) {
                    const checkDate = new Date(date);
                    checkDate.setDate(checkDate.getDate() + i);
                    if (weekdays.includes(checkDate.getDay()) && checkDate > after) {
                        checkDate.setHours(hours, minutes, 0, 0);
                        return checkDate;
                    }
                }
                break;

            case 'monthly_date':
            case 'specific_months':
                const months = recurrence.months || [1,2,3,4,5,6,7,8,9,10,11,12];
                const day = recurrence.day_of_month || 1;

                for (let i = 0; i < 24; i++) {
                    const checkDate = new Date(date);
                    checkDate.setMonth(checkDate.getMonth() + i);
                    checkDate.setDate(Math.min(day, new Date(checkDate.getFullYear(), checkDate.getMonth() + 1, 0).getDate()));
                    checkDate.setHours(hours, minutes, 0, 0);

                    if (months.includes(checkDate.getMonth() + 1) && checkDate > after) {
                        return checkDate;
                    }
                }
                break;

            case 'monthly_weekday':
                const weekNumber = recurrence.week_number;
                const weekday = recurrence.weekday;

                for (let m = 0; m < 24; m++) {
                    const checkDate = new Date(date);
                    checkDate.setMonth(checkDate.getMonth() + m);
                    checkDate.setDate(1);

                    // Find the nth weekday of the month
                    let targetDate;
                    if (weekNumber === 'last') {
                        // Last occurrence of weekday in month
                        const lastDay = new Date(checkDate.getFullYear(), checkDate.getMonth() + 1, 0).getDate();
                        for (let d = lastDay; d >= 1; d--) {
                            const testDate = new Date(checkDate.getFullYear(), checkDate.getMonth(), d);
                            if (testDate.getDay() === weekday) {
                                targetDate = testDate;
                                break;
                            }
                        }
                    } else {
                        // Nth occurrence (1st, 2nd, 3rd, 4th)
                        let count = 0;
                        for (let d = 1; d <= 31; d++) {
                            const testDate = new Date(checkDate.getFullYear(), checkDate.getMonth(), d);
                            if (testDate.getMonth() !== checkDate.getMonth()) break;
                            if (testDate.getDay() === weekday) {
                                count++;
                                if (count === weekNumber) {
                                    targetDate = testDate;
                                    break;
                                }
                            }
                        }
                    }

                    if (targetDate) {
                        targetDate.setHours(hours, minutes, 0, 0);
                        if (targetDate > after) {
                            return targetDate;
                        }
                    }
                }
                break;
        }

        return null;
    }
};

// ----- NAVIGATION -----
const Nav = {
    goto(page) {
        window.location.href = page;
    }
};

// ----- RECURRENCE HELPERS -----
const Recurrence = {
    describe(recurrence) {
        if (!recurrence) return '';

        const time = recurrence.time_of_day || '09:00';

        switch (recurrence.type) {
            case 'daily':
                const interval = recurrence.interval_days || 1;
                return interval === 1 ? `Daily at ${time}` : `Every ${interval} days at ${time}`;

            case 'weekly':
                const days = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'];
                const weekdays = (recurrence.weekdays || []).map(d => days[d]).join(', ');
                return `Every ${weekdays} at ${time}`;

            case 'monthly_date':
                return `Monthly on day ${recurrence.day_of_month} at ${time}`;

            case 'specific_months':
                const months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];
                const selectedMonths = (recurrence.months || []).map(m => months[m - 1]).join(', ');
                return `${selectedMonths} on day ${recurrence.day_of_month} at ${time}`;

            default:
                return 'Custom schedule';
        }
    },

    getTypeLabel(type) {
        const labels = {
            'daily': 'Daily',
            'weekly': 'Weekly',
            'monthly_date': 'Monthly',
            'specific_months': 'Specific Months'
        };
        return labels[type] || type;
    }
};

// Export for use in other files
window.DateUtils = DateUtils;
window.Nav = Nav;
window.Recurrence = Recurrence;
