/**
 * Tests for Format Utilities
 * FE-TEST-004: Test all format utility functions
 */

import { describe, it, expect } from 'vitest';
import {
  formatFileSize,
  formatNumber,
  formatCurrency,
  formatPercentage,
  truncate,
  capitalize,
  capitalizeWords,
  slugify,
  initials,
  formatUsername,
  formatEmail,
  formatPhoneNumber,
  formatBytes,
  formatDuration,
  formatTimeAgo,
  formatList,
  formatPlural,
} from './format';

describe('format utilities', () => {
  describe('formatFileSize', () => {
    it('should format bytes', () => {
      expect(formatFileSize(0)).toBe('0 Bytes');
      expect(formatFileSize(500)).toBe('500 Bytes');
    });

    it('should format KB', () => {
      expect(formatFileSize(1024)).toBe('1 KB');
      expect(formatFileSize(2048)).toBe('2 KB');
    });

    it('should format MB', () => {
      expect(formatFileSize(1048576)).toBe('1 MB');
    });

    it('should format GB', () => {
      expect(formatFileSize(1073741824)).toBe('1 GB');
    });
  });

  describe('formatNumber', () => {
    it('should format numbers less than 1000', () => {
      expect(formatNumber(500)).toBe('500');
      expect(formatNumber(999)).toBe('999');
    });

    it('should format thousands', () => {
      expect(formatNumber(1500)).toBe('1.5K');
      expect(formatNumber(9999)).toBe('10.0K');
    });

    it('should format millions', () => {
      expect(formatNumber(1500000)).toBe('1.5M');
    });

    it('should format billions', () => {
      expect(formatNumber(1500000000)).toBe('1.5B');
    });
  });

  describe('formatCurrency', () => {
    it('should format EUR by default', () => {
      const result = formatCurrency(1234.56);
      expect(result).toContain('1');
      expect(result).toContain('234');
    });

    it('should format USD', () => {
      const result = formatCurrency(1234.56, 'USD');
      expect(result).toBeTruthy();
      expect(typeof result).toBe('string');
    });
  });

  describe('formatPercentage', () => {
    it('should format percentage with default decimals', () => {
      expect(formatPercentage(0.5)).toBe('50.0%');
      expect(formatPercentage(0.123)).toBe('12.3%');
    });

    it('should format percentage with custom decimals', () => {
      expect(formatPercentage(0.5, 2)).toBe('50.00%');
      expect(formatPercentage(0.123, 0)).toBe('12%');
    });
  });

  describe('truncate', () => {
    it('should truncate long text', () => {
      expect(truncate('Hello World', 5)).toBe('He...');
    });

    it('should not truncate short text', () => {
      expect(truncate('Hello', 10)).toBe('Hello');
    });

    it('should use custom suffix', () => {
      expect(truncate('Hello World', 5, '…')).toBe('Hell…');
    });
  });

  describe('capitalize', () => {
    it('should capitalize first letter', () => {
      expect(capitalize('hello')).toBe('Hello');
      expect(capitalize('WORLD')).toBe('World');
    });
  });

  describe('capitalizeWords', () => {
    it('should capitalize each word', () => {
      expect(capitalizeWords('hello world')).toBe('Hello World');
      expect(capitalizeWords('john doe')).toBe('John Doe');
    });
  });

  describe('slugify', () => {
    it('should create slug from text', () => {
      expect(slugify('Hello World')).toBe('hello-world');
      expect(slugify('Test 123')).toBe('test-123');
    });

    it('should remove special characters', () => {
      expect(slugify('Hello@World!')).toBe('helloworld');
    });

    it('should handle multiple spaces', () => {
      expect(slugify('Hello   World')).toBe('hello-world');
    });
  });

  describe('initials', () => {
    it('should extract initials', () => {
      expect(initials('John Doe')).toBe('JD');
      expect(initials('John')).toBe('J');
    });

    it('should handle single word', () => {
      expect(initials('John')).toBe('J');
    });

    it('should handle multiple words', () => {
      expect(initials('John Michael Doe')).toBe('JM');
    });
  });

  describe('formatUsername', () => {
    it('should add @ prefix', () => {
      expect(formatUsername('john')).toBe('@john');
    });
  });

  describe('formatEmail', () => {
    it('should mask email', () => {
      expect(formatEmail('john.doe@example.com')).toBe('joh***@example.com');
    });

    it('should handle short local part', () => {
      expect(formatEmail('ab@example.com')).toBe('ab@example.com');
    });
  });

  describe('formatPhoneNumber', () => {
    it('should format French phone number', () => {
      expect(formatPhoneNumber('0612345678')).toBe('06 12 34 56 78');
    });

    it('should handle already formatted numbers', () => {
      expect(formatPhoneNumber('06 12 34 56 78')).toBe('06 12 34 56 78');
    });
  });

  describe('formatBytes', () => {
    it('should format bytes with default decimals', () => {
      expect(formatBytes(0)).toBe('0 Bytes');
      expect(formatBytes(1024)).toBe('1 KB');
    });

    it('should format with custom decimals', () => {
      // parseFloat removes trailing zeros, so 1.000 becomes 1
      expect(formatBytes(1024, 3)).toBe('1 KB');
      // Test with a value that actually shows decimals
      expect(formatBytes(1536, 3)).toBe('1.5 KB');
    });
  });

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

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

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

  describe('formatTimeAgo', () => {
    it('should format recent time', () => {
      const now = new Date();
      const result = formatTimeAgo(now);
      expect(result).toBe("À l'instant");
    });

    it('should format minutes ago', () => {
      const past = new Date(Date.now() - 30 * 60 * 1000);
      const result = formatTimeAgo(past);
      expect(result).toContain('min');
    });
  });

  describe('formatList', () => {
    it('should format empty list', () => {
      expect(formatList([])).toBe('');
    });

    it('should format single item', () => {
      expect(formatList(['apple'])).toBe('apple');
    });

    it('should format two items', () => {
      expect(formatList(['apple', 'banana'])).toBe('apple et banana');
    });

    it('should format multiple items', () => {
      expect(formatList(['apple', 'banana', 'cherry'])).toBe(
        'apple, banana et cherry',
      );
    });

    it('should use custom conjunction', () => {
      expect(formatList(['apple', 'banana'], 'ou')).toBe('apple ou banana');
    });
  });

  describe('formatPlural', () => {
    it('should format singular', () => {
      expect(formatPlural(1, 'item')).toBe('1 item');
    });

    it('should format plural', () => {
      expect(formatPlural(2, 'item')).toBe('2 items');
    });

    it('should use custom plural', () => {
      expect(formatPlural(2, 'child', 'children')).toBe('2 children');
    });
  });
});
