/**
 * Tests for pages/subscriptions.js — formatNextUpdate.
 *
 * Pure date-formatting helper used by the subscriptions page to label
 * "Next refresh in …". The 5-minute past threshold drives a timezone
 * correction branch that has caused user-visible bugs before; lock the
 * branch boundaries down here.
 */

let formatNextUpdate;

beforeAll(async () => {
    // subscriptions.js has a DOMContentLoaded listener that calls fetch().
    // The event has typically already fired in happy-dom by the time we
    // import, so the listener never runs — but stub fetch defensively in
    // case the test ordering changes.
    globalThis.fetch = vi.fn(() =>
        Promise.resolve({ ok: true, json: () => Promise.resolve({}) })
    );

    await import('@js/pages/subscriptions.js');
    formatNextUpdate = window.formatNextUpdate;
});

describe('formatNextUpdate', () => {
    it('returns "Invalid date" for non-parsable input', () => {
        expect(formatNextUpdate('not-a-date')).toBe('Invalid date');
        expect(formatNextUpdate('')).toBe('Invalid date');
        expect(formatNextUpdate(undefined)).toBe('Invalid date');
    });

    it('returns a locale string for a clearly-future date (no past-branch fixup)', () => {
        const tenYearsLater = new Date(Date.now() + 10 * 365 * 24 * 60 * 60 * 1000);
        const result = formatNextUpdate(tenYearsLater.toISOString());
        // Should be a non-empty formatted string, not the invalid sentinel.
        expect(result).not.toBe('Invalid date');
        expect(typeof result).toBe('string');
        expect(result.length).toBeGreaterThan(0);
    });

    it('returns a locale string for "near future" (within 5 min, no fixup)', () => {
        const twoMinutesFromNow = new Date(Date.now() + 2 * 60 * 1000);
        const result = formatNextUpdate(twoMinutesFromNow.toISOString());
        expect(result).not.toBe('Invalid date');
        expect(typeof result).toBe('string');
    });

    it('applies the timezone-offset correction when the date is >5 min in the past', () => {
        // The past-branch subtracts getTimezoneOffset()*60000 ms from the
        // parsed date, then formats. For timezones with non-zero offsets
        // the formatted output will differ from the un-corrected string;
        // for UTC environments both branches produce the same output, so
        // we just assert the value is not "Invalid date" and the function
        // executed the past branch without throwing.
        const oneHourAgo = new Date(Date.now() - 60 * 60 * 1000);
        const result = formatNextUpdate(oneHourAgo.toISOString());
        expect(result).not.toBe('Invalid date');
        expect(typeof result).toBe('string');
        expect(result.length).toBeGreaterThan(0);
    });

    it('treats a date exactly at the 5-minute past boundary as past-correctable', () => {
        // sixMinutesAgo is unambiguously past the threshold (>5min ago).
        const sixMinutesAgo = new Date(Date.now() - 6 * 60 * 1000);
        const result = formatNextUpdate(sixMinutesAgo.toISOString());
        expect(result).not.toBe('Invalid date');
    });
});
