/**
 * Date and time utility functions for consistent formatting across the component library
 */
/**
 * Formats a timestamp for display in chat messages, notifications, etc.
 * Shows time only for today, date + time for other days.
 */
const formatTimestamp = (input, options = {}) => {
    const { alwaysShowDate = false, includeSeconds = false, use12Hour = false, locale } = options;
    const date = new Date(input);
    // Check if date is valid
    if (isNaN(date.getTime())) {
        return 'Invalid date';
    }
    // Check if date is today
    const now = new Date();
    const isToday = date.toDateString() === now.toDateString();
    const timeOptions = {
        hour: '2-digit',
        minute: '2-digit',
        ...(includeSeconds && { second: '2-digit' }),
        ...(use12Hour && { hour12: true }),
    };
    if (isToday && !alwaysShowDate) {
        // Show time only if today
        return date.toLocaleTimeString(locale ? [locale] : [], timeOptions);
    }
    else {
        // Show date and time if not today or if alwaysShowDate is true
        return date.toLocaleDateString(locale ? [locale] : [], {
            month: 'short',
            day: 'numeric',
            ...timeOptions,
        });
    }
};
/**
 * Formats a date using a custom format string
 * Supports common format tokens for flexible date display
 *
 * @param date - The date to format
 * @param formatString - Format string with tokens (e.g., 'DD MMM YYYY', 'DD/MM/YYYY')
 * @param locale - Optional locale for month names (default: 'en-US')
 *
 * Supported tokens:
 * - DD: Day with leading zero (01, 02, ..., 31)
 * - D: Day without leading zero (1, 2, ..., 31)
 * - MMM: Short month name (Jan, Feb, ..., Dec)
 * - MMMM: Full month name (January, February, ..., December)
 * - MM: Month with leading zero (01, 02, ..., 12)
 * - M: Month without leading zero (1, 2, ..., 12)
 * - YYYY: Full year (2023, 2024, etc.)
 * - YY: Two-digit year (23, 24, etc.)
 *
 * @example
 * formatDateCustom(new Date('2023-09-21'), 'DD MMM YYYY') // "21 Sept 2023"
 * formatDateCustom(new Date('2023-09-21'), 'DD/MM/YYYY') // "21/09/2023"
 * formatDateCustom(new Date('2023-09-21'), 'MM-DD-YYYY') // "09-21-2023"
 * formatDateCustom(new Date('2023-09-21'), 'D MMMM YYYY') // "21 September 2023"
 */
const formatDateCustom = (date, formatString, locale = 'en-US') => {
    if (!(date instanceof Date) || isNaN(date.getTime())) {
        return 'Invalid date';
    }
    const day = date.getDate();
    const month = date.getMonth() + 1;
    const year = date.getFullYear();
    // Get month names based on locale
    const shortMonths = Array.from({ length: 12 }, (_, i) => new Date(2000, i, 1).toLocaleDateString(locale, { month: 'short' }));
    const fullMonths = Array.from({ length: 12 }, (_, i) => new Date(2000, i, 1).toLocaleDateString(locale, { month: 'long' }));
    // Replace tokens in order of length (longest first to avoid conflicts)
    let result = formatString;
    // Year tokens
    result = result.replace(/YYYY/g, year.toString());
    result = result.replace(/YY/g, year.toString().slice(-2));
    // Month tokens (longest first) — use \x00-wrapped placeholders to prevent collisions
    result = result.replace(/MMMM/g, `\x00${fullMonths[month - 1]}\x00`);
    result = result.replace(/MMM/g, `\x00${shortMonths[month - 1]}\x00`);
    result = result.replace(/MM/g, month.toString().padStart(2, '0'));
    result = result.replace(/M/g, month.toString());
    // Day tokens (longest first)
    result = result.replace(/DD/g, day.toString().padStart(2, '0'));
    result = result.replace(/D/g, day.toString());
    // Strip placeholders
    result = result.replace(/\x00/g, '');
    return result;
};
/**
 * Get date range for this week (Monday to Sunday)
 */
const getThisWeek = () => {
    const now = new Date();
    const dayOfWeek = now.getDay();
    const mondayOffset = dayOfWeek === 0 ? -6 : 1 - dayOfWeek;
    const start = new Date(now);
    start.setDate(now.getDate() + mondayOffset);
    start.setHours(0, 0, 0, 0);
    const end = new Date(start);
    end.setDate(start.getDate() + 6);
    end.setHours(23, 59, 59, 999);
    return { start, end };
};
/**
 * Get date range for last week (Monday to Sunday)
 */
const getLastWeek = () => {
    const thisWeek = getThisWeek();
    const start = new Date(thisWeek.start);
    start.setDate(start.getDate() - 7);
    const end = new Date(thisWeek.start);
    end.setDate(end.getDate() - 1);
    end.setHours(23, 59, 59, 999);
    return { start, end };
};
/**
 * Get date range for this month
 */
const getThisMonth = () => {
    const now = new Date();
    const start = new Date(now.getFullYear(), now.getMonth(), 1);
    start.setHours(0, 0, 0, 0);
    const end = new Date(now.getFullYear(), now.getMonth() + 1, 0);
    end.setHours(23, 59, 59, 999);
    return { start, end };
};
/**
 * Get date range for last month
 */
const getLastMonth = () => {
    const now = new Date();
    const start = new Date(now.getFullYear(), now.getMonth() - 1, 1);
    start.setHours(0, 0, 0, 0);
    const end = new Date(now.getFullYear(), now.getMonth(), 0);
    end.setHours(23, 59, 59, 999);
    return { start, end };
};
// ---------------------------------------------------------------------------
// Generic date utilities (shared across components)
// ---------------------------------------------------------------------------
/**
 * Normalise a Date | string to a Date at local midnight.
 *
 * ISO date-only strings like "2026-01-15" are parsed as UTC by the native
 * Date constructor, which can shift the day backward in negative-UTC
 * timezones.  We detect the YYYY-MM-DD pattern and construct the Date with
 * local year/month/day to avoid an off-by-one.
 */
function toDate(input) {
    if (typeof input === "string") {
        const match = input.match(/^(\d{4})-(\d{2})-(\d{2})/);
        if (match) {
            return new Date(Number(match[1]), Number(match[2]) - 1, Number(match[3]));
        }
        const d = new Date(input);
        d.setHours(0, 0, 0, 0);
        return d;
    }
    const d = new Date(input);
    d.setHours(0, 0, 0, 0);
    return d;
}
/**
 * Add (or subtract) a number of calendar days to a date.
 */
function addDays(date, days) {
    const d = toDate(date);
    d.setDate(d.getDate() + days);
    return d;
}
/**
 * Check if two dates are the same calendar day.
 */
function isSameDay(a, b) {
    return (a.getFullYear() === b.getFullYear() &&
        a.getMonth() === b.getMonth() &&
        a.getDate() === b.getDate());
}
/**
 * Check if a date falls on a weekend (Saturday=6, Sunday=0).
 */
function isWeekend(date) {
    const day = date.getDay();
    return day === 0 || day === 6;
}
/**
 * Number of calendar days between two dates (inclusive).
 * e.g. Jan 1 → Jan 3 = 3 days.
 */
function getDaysBetween(a, b) {
    const start = toDate(a);
    const end = toDate(b);
    return Math.round((end.getTime() - start.getTime()) / 86400000) + 1;
}

export { addDays, formatDateCustom, formatTimestamp, getDaysBetween, getLastMonth, getLastWeek, getThisMonth, getThisWeek, isSameDay, isWeekend, toDate };
