import { describe, expect, it } from 'vitest';
import { calculateDateConfidence } from '../helpers/date-confidence.helper.js';
describe('calculateDateConfidence', () => {
    describe('client-aware flag', () => {
        it('returns 1.0 for client same-business on same day', () => {
            const date = new Date('2024-01-15');
            const result = calculateDateConfidence(date, date, true);
            expect(result).toBe(1.0);
        });
        it('returns 1.0 for client same-business 30 days apart', () => {
            const date1 = new Date('2024-01-01');
            const date2 = new Date('2024-01-31');
            const result = calculateDateConfidence(date1, date2, true);
            expect(result).toBe(1.0);
        });
        it('returns 1.0 for client same-business 365 days apart', () => {
            const date1 = new Date('2023-01-01');
            const date2 = new Date('2024-01-01');
            const result = calculateDateConfidence(date1, date2, true);
            expect(result).toBe(1.0);
        });
        it('uses standard degradation when not a client match', () => {
            const date1 = new Date('2024-01-01');
            const date2 = new Date('2024-01-31');
            const result = calculateDateConfidence(date1, date2, false);
            expect(result).toBe(0.0);
        });
    });
    describe('same day', () => {
        it('should return 1.0 for identical dates', () => {
            const date = new Date('2024-01-15T10:30:00Z');
            const result = calculateDateConfidence(date, date);
            expect(result).toBe(1.0);
        });
        it('should return 1.0 for same day with different times', () => {
            const date1 = new Date('2024-01-15T08:00:00Z');
            const date2 = new Date('2024-01-15T18:30:00Z');
            const result = calculateDateConfidence(date1, date2);
            expect(result).toBe(1.0);
        });
        it('should return 1.0 for same day at different hours', () => {
            const date1 = new Date('2024-01-15T00:00:00');
            const date2 = new Date('2024-01-15T23:59:59');
            const result = calculateDateConfidence(date1, date2);
            expect(result).toBe(1.0);
        });
    });
    describe('specific day differences', () => {
        it('should return ~0.97 for 1 day difference', () => {
            const date1 = new Date('2024-01-15');
            const date2 = new Date('2024-01-16');
            const result = calculateDateConfidence(date1, date2);
            expect(result).toBeCloseTo(0.97, 2);
            expect(result).toBe(0.97);
        });
        it('should return ~0.77 for 7 days difference', () => {
            const date1 = new Date('2024-01-15');
            const date2 = new Date('2024-01-22');
            const result = calculateDateConfidence(date1, date2);
            expect(result).toBeCloseTo(0.77, 2);
            expect(result).toBe(0.77);
        });
        it('should return 0.5 for 15 days difference', () => {
            const date1 = new Date('2024-01-15');
            const date2 = new Date('2024-01-30');
            const result = calculateDateConfidence(date1, date2);
            expect(result).toBe(0.5);
        });
        it('should return ~0.03 for 29 days difference', () => {
            const date1 = new Date('2024-01-01');
            const date2 = new Date('2024-01-30');
            const result = calculateDateConfidence(date1, date2);
            expect(result).toBeCloseTo(0.03, 2);
            expect(result).toBe(0.03);
        });
        it('should return 0.0 for exactly 30 days difference', () => {
            const date1 = new Date('2024-01-01');
            const date2 = new Date('2024-01-31');
            const result = calculateDateConfidence(date1, date2);
            expect(result).toBe(0.0);
        });
        it('should return 0.0 for 100 days difference', () => {
            const date1 = new Date('2024-01-01');
            const date2 = new Date('2024-04-10');
            const result = calculateDateConfidence(date1, date2);
            expect(result).toBe(0.0);
        });
        it('should return 0.0 for 365 days difference', () => {
            const date1 = new Date('2024-01-01');
            const date2 = new Date('2025-01-01');
            const result = calculateDateConfidence(date1, date2);
            expect(result).toBe(0.0);
        });
    });
    describe('order independence', () => {
        it('should return same result regardless of parameter order', () => {
            const date1 = new Date('2024-01-15');
            const date2 = new Date('2024-01-25');
            const result1 = calculateDateConfidence(date1, date2);
            const result2 = calculateDateConfidence(date2, date1);
            expect(result1).toBe(result2);
        });
        it('should work with date2 before date1', () => {
            const date1 = new Date('2024-01-30');
            const date2 = new Date('2024-01-15');
            const result = calculateDateConfidence(date1, date2);
            expect(result).toBe(0.5);
        });
        it('should handle various orderings with same result', () => {
            const date1 = new Date('2024-01-01');
            const date2 = new Date('2024-01-08');
            expect(calculateDateConfidence(date1, date2)).toBe(calculateDateConfidence(date2, date1));
        });
    });
    describe('linear degradation formula', () => {
        it('should follow linear formula: 1.0 - (days_diff / 30)', () => {
            const testCases = [
                { days: 0, expected: 1.0 },
                { days: 3, expected: 0.9 },
                { days: 6, expected: 0.8 },
                { days: 9, expected: 0.7 },
                { days: 12, expected: 0.6 },
                { days: 15, expected: 0.5 },
                { days: 18, expected: 0.4 },
                { days: 21, expected: 0.3 },
                { days: 24, expected: 0.2 },
                { days: 27, expected: 0.1 },
                { days: 30, expected: 0.0 },
            ];
            testCases.forEach(({ days, expected }) => {
                const date1 = new Date('2024-01-01');
                const date2 = new Date(date1);
                date2.setDate(date1.getDate() + days);
                const result = calculateDateConfidence(date1, date2);
                expect(result).toBe(expected);
            });
        });
        it('should verify degradation is proportional', () => {
            const date1 = new Date('2024-01-01');
            const result5Days = calculateDateConfidence(date1, new Date('2024-01-06'));
            const result10Days = calculateDateConfidence(date1, new Date('2024-01-11'));
            const result20Days = calculateDateConfidence(date1, new Date('2024-01-21'));
            // Verify the relationship: each 5 days reduces confidence by ~0.17
            expect(result5Days - result10Days).toBeCloseTo(0.16, 1);
            expect(result10Days - result20Days).toBeCloseTo(0.33, 1);
        });
    });
    describe('different time zones', () => {
        it('should handle dates with different time zones correctly', () => {
            // Same calendar day in different time zones
            const date1 = new Date('2024-01-15T23:00:00-05:00'); // Eastern time
            const date2 = new Date('2024-01-15T20:00:00-08:00'); // Pacific time
            const result = calculateDateConfidence(date1, date2);
            expect(result).toBe(1.0);
        });
        it('should calculate difference based on UTC calendar dates', () => {
            const date1 = new Date('2024-01-15T02:00:00+02:00');
            const date2 = new Date('2024-01-16T02:00:00+02:00');
            const result = calculateDateConfidence(date1, date2);
            expect(result).toBe(0.97);
        });
    });
    describe('leap years', () => {
        it('should handle leap year dates correctly', () => {
            const date1 = new Date('2024-02-28');
            const date2 = new Date('2024-02-29'); // Leap day
            const result = calculateDateConfidence(date1, date2);
            expect(result).toBe(0.97);
        });
        it('should calculate across leap day correctly', () => {
            const date1 = new Date('2024-02-15');
            const date2 = new Date('2024-03-16'); // 30 days later (leap year)
            const result = calculateDateConfidence(date1, date2);
            expect(result).toBe(0.0);
        });
        it('should handle non-leap year February', () => {
            const date1 = new Date('2023-02-01');
            const date2 = new Date('2023-03-03'); // 30 days later (non-leap year)
            const result = calculateDateConfidence(date1, date2);
            expect(result).toBe(0.0);
        });
    });
    describe('month boundaries', () => {
        it('should handle dates across month boundaries', () => {
            const date1 = new Date('2024-01-31');
            const date2 = new Date('2024-02-15');
            const result = calculateDateConfidence(date1, date2);
            expect(result).toBe(0.5);
        });
        it('should handle dates across year boundaries', () => {
            const date1 = new Date('2023-12-25');
            const date2 = new Date('2024-01-09');
            const result = calculateDateConfidence(date1, date2);
            expect(result).toBe(0.5);
        });
    });
    describe('edge cases', () => {
        it('should handle very old dates', () => {
            const date1 = new Date('1990-01-01');
            const date2 = new Date('1990-01-16');
            const result = calculateDateConfidence(date1, date2);
            expect(result).toBe(0.5);
        });
        it('should handle future dates', () => {
            const date1 = new Date('2030-06-15');
            const date2 = new Date('2030-06-30');
            const result = calculateDateConfidence(date1, date2);
            expect(result).toBe(0.5);
        });
        it('should handle dates at different times of day', () => {
            const date1 = new Date('2024-01-15T10:00:00');
            const date2 = new Date('2024-01-22T14:00:00');
            const result = calculateDateConfidence(date1, date2);
            expect(result).toBe(0.77);
        });
    });
    describe('precision and rounding', () => {
        it('should round to exactly 2 decimal places', () => {
            const date1 = new Date('2024-01-01');
            const date2 = new Date('2024-01-02');
            const result = calculateDateConfidence(date1, date2);
            // Check that result has at most 2 decimal places
            expect(result.toString().split('.')[1]?.length || 0).toBeLessThanOrEqual(2);
        });
        it('should return values between 0.0 and 1.0', () => {
            const testDates = [
                [new Date('2024-01-01'), new Date('2024-01-01')], // 0 days
                [new Date('2024-01-01'), new Date('2024-01-11')], // 10 days
                [new Date('2024-01-01'), new Date('2024-01-21')], // 20 days
                [new Date('2024-01-01'), new Date('2024-02-01')], // 31 days
            ];
            testDates.forEach(([d1, d2]) => {
                const result = calculateDateConfidence(d1, d2);
                expect(result).toBeGreaterThanOrEqual(0.0);
                expect(result).toBeLessThanOrEqual(1.0);
            });
        });
        it('should handle fractional day calculations correctly', () => {
            // 2 days difference
            const date1 = new Date('2024-01-01');
            const date2 = new Date('2024-01-03');
            const result = calculateDateConfidence(date1, date2);
            // 1 - (2/30) = 1 - 0.0667 = 0.9333, rounded to 0.93
            expect(result).toBe(0.93);
        });
    });
    describe('return value validation', () => {
        it('should only return 0.0, 1.0, or values rounded to 2 decimals', () => {
            const results = [
                calculateDateConfidence(new Date('2024-01-01'), new Date('2024-01-01')), // 1.0
                calculateDateConfidence(new Date('2024-01-01'), new Date('2024-01-02')), // 0.97
                calculateDateConfidence(new Date('2024-01-01'), new Date('2024-01-16')), // 0.5
                calculateDateConfidence(new Date('2024-01-01'), new Date('2024-02-01')), // 0.0
            ];
            results.forEach(result => {
                const decimalPlaces = result.toString().split('.')[1]?.length || 0;
                expect(decimalPlaces).toBeLessThanOrEqual(2);
            });
        });
        it('should maintain consistency across multiple calls', () => {
            const date1 = new Date('2024-01-15');
            const date2 = new Date('2024-01-25');
            const result1 = calculateDateConfidence(date1, date2);
            const result2 = calculateDateConfidence(date1, date2);
            const result3 = calculateDateConfidence(date1, date2);
            expect(result1).toBe(result2);
            expect(result2).toBe(result3);
        });
    });
});
//# sourceMappingURL=date-confidence.test.js.map