import { describe, expect, it } from 'vitest';
import { resolveYearRange, YEARS_AHEAD, YEARS_BACK } from './calendar-years';

const TODAY = new Date(2026, 7, 12); // 12/08/2026

describe('resolveYearRange', () => {
    it('couvre une plage autour de l’année courante quand rien n’est borné', () => {
        expect(resolveYearRange({ today: TODAY })).toEqual({
            fromYear: 2026 - YEARS_BACK,
            toYear: 2026 + YEARS_AHEAD,
        });
    });

    it('respecte les deux bornes de l’appelant', () => {
        expect(resolveYearRange({ fromDate: new Date(2026, 7, 25), toDate: new Date(2027, 7, 11), today: TODAY })).toEqual({
            fromYear: 2026,
            toYear: 2027,
        });
    });

    it('prolonge vers le futur quand seule la borne basse est posée', () => {
        // Cas du champ « À » : min = date de début choisie dans « De ».
        expect(resolveYearRange({ fromDate: new Date(2026, 7, 25), today: TODAY })).toEqual({
            fromYear: 2026,
            toYear: 2026 + YEARS_AHEAD,
        });
    });

    it('remonte dans le passé quand seule la borne haute est posée', () => {
        expect(resolveYearRange({ toDate: new Date(2027, 7, 11), today: TODAY })).toEqual({
            fromYear: 2026 - YEARS_BACK,
            toYear: 2027,
        });
    });

    it('couvre une expiration lointaine sans borne explicite', () => {
        // Régression : avec une fenêtre étroite, une licence expirant dans
        // 12 ans devenait inatteignable au calendrier, sans aucune erreur.
        const { toYear } = resolveYearRange({ today: TODAY });
        expect(toYear).toBeGreaterThanOrEqual(2026 + 12);
    });

    it('couvre une date de naissance adulte sans borne explicite', () => {
        const { fromYear } = resolveYearRange({ today: TODAY });
        expect(fromYear).toBeLessThanOrEqual(2026 - 80);
    });

    it('ne produit jamais de plage vide avec une borne basse lointaine', () => {
        const { fromYear, toYear } = resolveYearRange({ fromDate: new Date(2040, 0, 1), today: TODAY });
        expect(fromYear).toBe(2040);
        expect(toYear).toBeGreaterThanOrEqual(fromYear);
    });

    it('ne produit jamais de plage vide avec une borne haute dans le passé', () => {
        const { fromYear, toYear } = resolveYearRange({ toDate: new Date(2010, 0, 1), today: TODAY });
        expect(toYear).toBe(2010);
        expect(fromYear).toBeLessThanOrEqual(toYear);
    });

    it('remet une plage inversée dans l’ordre', () => {
        expect(resolveYearRange({ fromYear: 2030, toYear: 2020, today: TODAY })).toEqual({
            fromYear: 2020,
            toYear: 2030,
        });
    });

    it('donne la priorité aux années explicites sur les dates', () => {
        expect(resolveYearRange({ fromDate: new Date(2026, 0, 1), fromYear: 2024, toYear: 2028, today: TODAY })).toEqual({
            fromYear: 2024,
            toYear: 2028,
        });
    });
});
