import { getTodayDateRange, getDefaultDateRange } from './dateUtils';

describe('dateUtils - getTodayDateRange', () => {
  test('should return an object with startDate and endDate', () => {
    const result = getTodayDateRange();
    expect(result).toHaveProperty('startDate');
    expect(result).toHaveProperty('endDate');
  });

  test('should return Date objects', () => {
    const result = getTodayDateRange();
    expect(result.startDate instanceof Date).toBe(true);
    expect(result.endDate instanceof Date).toBe(true);
  });

  test('should return date range from today to tomorrow', () => {
    const result = getTodayDateRange();
    const today = new Date();
    const tomorrow = new Date(today);
    tomorrow.setDate(tomorrow.getDate() + 1);
    
    // Check startDate is today in UTC (matching local date)
    expect(result.startDate.getUTCFullYear()).toBe(today.getFullYear());
    expect(result.startDate.getUTCMonth()).toBe(today.getMonth());
    expect(result.startDate.getUTCDate()).toBe(today.getDate());
    
    // Check endDate is tomorrow in UTC (matching local date)
    expect(result.endDate.getUTCFullYear()).toBe(tomorrow.getFullYear());
    expect(result.endDate.getUTCMonth()).toBe(tomorrow.getMonth());
    expect(result.endDate.getUTCDate()).toBe(tomorrow.getDate());
  });

  test('should have startDate at 00:00:00 UTC', () => {
    const result = getTodayDateRange();
    expect(result.startDate.getUTCHours()).toBe(0);
    expect(result.startDate.getUTCMinutes()).toBe(0);
    expect(result.startDate.getUTCSeconds()).toBe(0);
    expect(result.startDate.getUTCMilliseconds()).toBe(0);
  });

  test('should have endDate at 23:59:59.999 UTC', () => {
    const result = getTodayDateRange();
    expect(result.endDate.getUTCHours()).toBe(23);
    expect(result.endDate.getUTCMinutes()).toBe(59);
    expect(result.endDate.getUTCSeconds()).toBe(59);
    expect(result.endDate.getUTCMilliseconds()).toBe(999);
  });

  test('should have startDate before endDate', () => {
    const result = getTodayDateRange();
    expect(result.startDate.getTime()).toBeLessThan(result.endDate.getTime());
  });

  test('should not have undefined values', () => {
    const result = getTodayDateRange();
    expect(result.startDate).toBeDefined();
    expect(result.endDate).toBeDefined();
  });

  test('should span exactly 2 days minus 1 millisecond (from today 00:00:00 to tomorrow 23:59:59.999)', () => {
    const result = getTodayDateRange();
    const timeDiff = result.endDate.getTime() - result.startDate.getTime();
    // From today 00:00:00 to tomorrow 23:59:59.999 = almost 48 hours (2 days)
    const expectedDiff = (48 * 60 * 60 * 1000) - 1; // 48 hours minus 1 millisecond
    expect(timeDiff).toBeGreaterThanOrEqual(expectedDiff);
    expect(timeDiff).toBeLessThan(49 * 60 * 60 * 1000); // Less than 49 hours
  });

  test('should consistently return tomorrow as endDate when called multiple times', () => {
    const result1 = getTodayDateRange();
    const result2 = getTodayDateRange();
    expect(result1.endDate.getDate()).toBe(result2.endDate.getDate());
  });
});

describe('dateUtils - getDefaultDateRange', () => {
  test('should return an object with startDate and endDate', () => {
    const result = getDefaultDateRange();
    expect(result).toHaveProperty('startDate');
    expect(result).toHaveProperty('endDate');
  });

  test('should return Date objects', () => {
    const result = getDefaultDateRange();
    expect(result.startDate instanceof Date).toBe(true);
    expect(result.endDate instanceof Date).toBe(true);
  });

  test('should return current month range', () => {
    const result = getDefaultDateRange();
    const today = new Date();
    const firstDay = new Date(today.getFullYear(), today.getMonth(), 1);
    
    expect(result.startDate.getUTCFullYear()).toBe(firstDay.getFullYear());
    expect(result.startDate.getUTCMonth()).toBe(firstDay.getMonth());
    expect(result.startDate.getUTCDate()).toBe(firstDay.getDate());
  });

  test('should have endDate as last day of month', () => {
    const result = getDefaultDateRange();
    const today = new Date();
    const lastDay = new Date(today.getFullYear(), today.getMonth() + 1, 0);
    
    expect(result.endDate.getUTCFullYear()).toBe(lastDay.getFullYear());
    expect(result.endDate.getUTCMonth()).toBe(lastDay.getMonth());
    expect(result.endDate.getUTCDate()).toBe(lastDay.getDate());
  });

  test('should have startDate before endDate', () => {
    const result = getDefaultDateRange();
    expect(result.startDate.getTime()).toBeLessThanOrEqual(result.endDate.getTime());
  });

  test('should not have undefined values', () => {
    const result = getDefaultDateRange();
    expect(result.startDate).toBeDefined();
    expect(result.endDate).toBeDefined();
  });

  test('should return valid range for current month', () => {
    const result = getDefaultDateRange();
    const daysInRange = Math.ceil((result.endDate - result.startDate) / (1000 * 60 * 60 * 24));
    
    // Should be at least 1 day and at most 31 days
    expect(daysInRange).toBeGreaterThanOrEqual(1);
    expect(daysInRange).toBeLessThanOrEqual(31);
  });

  test('should have startDate at 00:00:00 UTC', () => {
    const result = getDefaultDateRange();
    expect(result.startDate.getUTCHours()).toBe(0);
    expect(result.startDate.getUTCMinutes()).toBe(0);
    expect(result.startDate.getUTCSeconds()).toBe(0);
    expect(result.startDate.getUTCMilliseconds()).toBe(0);
  });

  test('should have endDate at 23:59:59.999 UTC', () => {
    const result = getDefaultDateRange();
    expect(result.endDate.getUTCHours()).toBe(23);
    expect(result.endDate.getUTCMinutes()).toBe(59);
    expect(result.endDate.getUTCSeconds()).toBe(59);
    expect(result.endDate.getUTCMilliseconds()).toBe(999);
  });
});
