/**
 * Tests for Date Utilities
 * FE-TEST-004: Test all date utility functions
 */

import { describe, it, expect, beforeEach, afterEach, vi } from 'vitest';
import {
  formatDate,
  formatRelativeTime,
  isToday,
  isYesterday,
  getTimeAgo,
  formatDuration,
  parseDuration,
} from './date';

describe('date utilities', () => {
  beforeEach(() => {
    // Mock Date.now() to have consistent tests
    vi.useFakeTimers();
    vi.setSystemTime(new Date('2024-01-15T12:00:00Z'));
  });

  afterEach(() => {
    vi.useRealTimers();
  });

  describe('formatDate', () => {
    it('should format date in short format', () => {
      const date = new Date('2024-01-15T10:00:00Z');
      const result = formatDate(date, 'short');
      expect(result).toBeTruthy();
      expect(typeof result).toBe('string');
    });

    it('should format date in long format', () => {
      const date = new Date('2024-01-15T10:00:00Z');
      const result = formatDate(date, 'long');
      expect(result).toBeTruthy();
      expect(typeof result).toBe('string');
    });

    it('should format date in relative format', () => {
      const date = new Date('2024-01-15T11:00:00Z');
      const result = formatDate(date, 'relative');
      expect(result).toBeTruthy();
      expect(typeof result).toBe('string');
    });

    it('should default to short format', () => {
      const date = new Date('2024-01-15T10:00:00Z');
      const result = formatDate(date);
      expect(result).toBeTruthy();
      expect(typeof result).toBe('string');
    });

    it('should handle string dates', () => {
      const result = formatDate('2024-01-15T10:00:00Z');
      expect(result).toBeTruthy();
      expect(typeof result).toBe('string');
    });

    it('should return "Invalid date" for invalid dates', () => {
      const result = formatDate('invalid-date');
      expect(result).toBe('Invalid date');
    });
  });

  describe('formatRelativeTime', () => {
    it('should return "À l\'instant" for very recent dates', () => {
      const date = new Date('2024-01-15T11:59:30Z');
      const result = formatRelativeTime(date);
      expect(result).toBe("À l'instant");
    });

    it('should format minutes ago', () => {
      const date = new Date('2024-01-15T11:45:00Z');
      const result = formatRelativeTime(date);
      expect(result).toContain('minute');
    });

    it('should format hours ago', () => {
      const date = new Date('2024-01-15T10:00:00Z');
      const result = formatRelativeTime(date);
      expect(result).toContain('heure');
    });

    it('should format days ago', () => {
      const date = new Date('2024-01-14T12:00:00Z');
      const result = formatRelativeTime(date);
      expect(result).toContain('jour');
    });

    it('should format weeks ago', () => {
      const date = new Date('2024-01-08T12:00:00Z');
      const result = formatRelativeTime(date);
      expect(result).toContain('semaine');
    });

    it('should format months ago', () => {
      const date = new Date('2023-12-15T12:00:00Z');
      const result = formatRelativeTime(date);
      expect(result).toContain('mois');
    });

    it('should format years ago', () => {
      const date = new Date('2023-01-15T12:00:00Z');
      const result = formatRelativeTime(date);
      expect(result).toContain('an');
    });
  });

  describe('isToday', () => {
    it('should return true for today', () => {
      const today = new Date('2024-01-15T12:00:00Z');
      expect(isToday(today)).toBe(true);
    });

    it('should return false for yesterday', () => {
      const yesterday = new Date('2024-01-14T12:00:00Z');
      expect(isToday(yesterday)).toBe(false);
    });

    it('should return false for tomorrow', () => {
      const tomorrow = new Date('2024-01-16T12:00:00Z');
      expect(isToday(tomorrow)).toBe(false);
    });

    it('should handle string dates', () => {
      expect(isToday('2024-01-15T12:00:00Z')).toBe(true);
      expect(isToday('2024-01-14T12:00:00Z')).toBe(false);
    });
  });

  describe('isYesterday', () => {
    it('should return true for yesterday', () => {
      const yesterday = new Date('2024-01-14T12:00:00Z');
      expect(isYesterday(yesterday)).toBe(true);
    });

    it('should return false for today', () => {
      const today = new Date('2024-01-15T12:00:00Z');
      expect(isYesterday(today)).toBe(false);
    });

    it('should return false for two days ago', () => {
      const twoDaysAgo = new Date('2024-01-13T12:00:00Z');
      expect(isYesterday(twoDaysAgo)).toBe(false);
    });

    it('should handle string dates', () => {
      expect(isYesterday('2024-01-14T12:00:00Z')).toBe(true);
      expect(isYesterday('2024-01-15T12:00:00Z')).toBe(false);
    });
  });

  describe('getTimeAgo', () => {
    it('should return time for today', () => {
      const today = new Date('2024-01-15T10:30:00Z');
      const result = getTimeAgo(today);
      expect(result).toBeTruthy();
      expect(typeof result).toBe('string');
    });

    it('should return "Hier" for yesterday', () => {
      const yesterday = new Date('2024-01-14T12:00:00Z');
      const result = getTimeAgo(yesterday);
      expect(result).toBe('Hier');
    });

    it('should return formatted date for older dates', () => {
      const oldDate = new Date('2024-01-10T12:00:00Z');
      const result = getTimeAgo(oldDate);
      expect(result).toBeTruthy();
      expect(typeof result).toBe('string');
    });
  });

  describe('formatDuration', () => {
    it('should format seconds only', () => {
      expect(formatDuration(45)).toBe('0:45');
    });

    it('should format minutes and seconds', () => {
      expect(formatDuration(125)).toBe('2:05');
    });

    it('should format hours, minutes and seconds', () => {
      expect(formatDuration(3665)).toBe('1:01:05');
    });

    it('should handle zero', () => {
      expect(formatDuration(0)).toBe('0:00');
    });

    it('should handle large durations', () => {
      expect(formatDuration(7200)).toBe('2:00:00');
    });
  });

  describe('parseDuration', () => {
    it('should parse MM:SS format', () => {
      expect(parseDuration('2:30')).toBe(150);
    });

    it('should parse HH:MM:SS format', () => {
      expect(parseDuration('1:30:45')).toBe(5445);
    });

    it('should return 0 for invalid format', () => {
      expect(parseDuration('invalid')).toBe(0);
    });

    it('should handle edge cases', () => {
      expect(parseDuration('0:00')).toBe(0);
      expect(parseDuration('0:05')).toBe(5);
    });
  });
});
