// src/features/flyer/dateUtils.test.ts
import { describe, it, expect } from 'vitest';
import { formatShortDate, calculateDaysBetween, formatDateRange } from './dateUtils';

describe('formatShortDate', () => {
  it('should format a valid YYYY-MM-DD date string correctly', () => {
    expect(formatShortDate('2024-07-26')).toBe('Jul 26');
  });

  it('should handle single-digit days correctly', () => {
    expect(formatShortDate('2025-01-05')).toBe('Jan 5');
  });

  it('should handle dates at the end of the year', () => {
    expect(formatShortDate('2023-12-31')).toBe('Dec 31');
  });

  it('should return null for a null input', () => {
    expect(formatShortDate(null)).toBeNull();
  });

  it('should return null for an undefined input', () => {
    expect(formatShortDate(undefined)).toBeNull();
  });

  it('should return null for an empty string input', () => {
    expect(formatShortDate('')).toBeNull();
  });

  it('should return null for an invalid date string', () => {
    expect(formatShortDate('not-a-real-date')).toBeNull();
  });

  it('should return null for a malformed date string', () => {
    expect(formatShortDate('2024-13-01')).toBeNull(); // Invalid month
  });

  it('should correctly format a full ISO string with time and timezone', () => {
    expect(formatShortDate('2024-12-25T10:00:00Z')).toBe('Dec 25');
  });
});

describe('calculateDaysBetween', () => {
  it('should calculate the difference in days between two valid date strings', () => {
    expect(calculateDaysBetween('2023-01-01', '2023-01-05')).toBe(4);
  });

  it('should return a negative number if the end date is before the start date', () => {
    expect(calculateDaysBetween('2023-01-05', '2023-01-01')).toBe(-4);
  });

  it('should handle Date objects', () => {
    const start = new Date('2023-01-01');
    const end = new Date('2023-01-10');
    expect(calculateDaysBetween(start, end)).toBe(9);
  });

  it('should return null if either date is null or undefined', () => {
    expect(calculateDaysBetween(null, '2023-01-01')).toBeNull();
    expect(calculateDaysBetween('2023-01-01', undefined)).toBeNull();
  });

  it('should return null if either date is invalid', () => {
    expect(calculateDaysBetween('invalid', '2023-01-01')).toBeNull();
    expect(calculateDaysBetween('2023-01-01', 'invalid')).toBeNull();
  });
});

describe('formatDateRange', () => {
  it('should format a range with two different valid dates', () => {
    expect(formatDateRange('2023-01-01', '2023-01-05')).toBe('Jan 1 - Jan 5');
  });

  it('should format a range with the same start and end date as a single date', () => {
    expect(formatDateRange('2023-01-01', '2023-01-01')).toBe('Jan 1');
  });

  it('should return only the start date if end date is missing', () => {
    expect(formatDateRange('2023-01-01', null)).toBe('Jan 1');
    expect(formatDateRange('2023-01-01', undefined)).toBe('Jan 1');
  });

  it('should return only the end date if start date is missing', () => {
    expect(formatDateRange(null, '2023-01-05')).toBe('Jan 5');
    expect(formatDateRange(undefined, '2023-01-05')).toBe('Jan 5');
  });

  it('should return null if both dates are missing or invalid', () => {
    expect(formatDateRange(null, null)).toBeNull();
    expect(formatDateRange(undefined, undefined)).toBeNull();
    expect(formatDateRange('invalid', 'invalid')).toBeNull();
  });

  it('should handle one valid and one invalid date by showing only the valid one', () => {
    expect(formatDateRange('2023-01-01', 'invalid')).toBe('Jan 1');
    expect(formatDateRange('invalid', '2023-01-05')).toBe('Jan 5');
  });

  describe('verbose mode', () => {
    it('should format a range with two different valid dates verbosely', () => {
      expect(formatDateRange('2023-01-01', '2023-01-05', { verbose: true })).toBe(
        'Deals valid from January 1, 2023 to January 5, 2023',
      );
    });

    it('should format a range with the same start and end date verbosely', () => {
      expect(formatDateRange('2023-01-01', '2023-01-01', { verbose: true })).toBe(
        'Valid on January 1, 2023',
      );
    });

    it('should format only the start date verbosely', () => {
      expect(formatDateRange('2023-01-01', null, { verbose: true })).toBe(
        'Deals start January 1, 2023',
      );
    });

    it('should format only the end date verbosely', () => {
      expect(formatDateRange(null, '2023-01-05', { verbose: true })).toBe(
        'Deals end January 5, 2023',
      );
    });

    it('should handle one valid and one invalid date verbosely', () => {
      expect(formatDateRange('2023-01-01', 'invalid', { verbose: true })).toBe(
        'Deals start January 1, 2023',
      );
    });
  });
});
