// SPDX-License-Identifier: GPL-3.0-or-later

import { describe, it, expect } from 'vitest';
import {
  formatBytes,
  formatRelativeTime,
  formatCredits,
  truncate,
  truncatePath,
  getStatusColor,
} from './utils';

describe('formatBytes', () => {
  it('returns 0 B for undefined', () => {
    expect(formatBytes(undefined)).toBe('0 B');
  });

  it('returns 0 B for zero', () => {
    expect(formatBytes(0)).toBe('0 B');
  });

  it('formats bytes correctly', () => {
    expect(formatBytes(500)).toBe('500 B');
    expect(formatBytes(1024)).toBe('1 KB');
    expect(formatBytes(1536)).toBe('1.5 KB');
    expect(formatBytes(1048576)).toBe('1 MB');
    expect(formatBytes(1073741824)).toBe('1 GB');
  });

  it('respects decimal places', () => {
    expect(formatBytes(1536, 0)).toBe('2 KB');
    expect(formatBytes(1536, 1)).toBe('1.5 KB');
    expect(formatBytes(1536, 3)).toBe('1.5 KB');
  });
});

describe('formatRelativeTime', () => {
  it('returns Never for undefined', () => {
    expect(formatRelativeTime(undefined)).toBe('Never');
  });

  it('returns Just now for recent times', () => {
    const now = new Date();
    expect(formatRelativeTime(now)).toBe('Just now');
  });

  it('returns minutes ago for times < 1 hour', () => {
    const fiveMinutesAgo = new Date(Date.now() - 5 * 60 * 1000);
    expect(formatRelativeTime(fiveMinutesAgo)).toBe('5 minutes ago');
  });

  it('handles singular forms', () => {
    const oneMinuteAgo = new Date(Date.now() - 1 * 60 * 1000);
    expect(formatRelativeTime(oneMinuteAgo)).toBe('1 minute ago');
  });

  it('returns hours ago for times < 1 day', () => {
    const twoHoursAgo = new Date(Date.now() - 2 * 60 * 60 * 1000);
    expect(formatRelativeTime(twoHoursAgo)).toBe('2 hours ago');
  });

  it('returns days ago for times < 1 week', () => {
    const threeDaysAgo = new Date(Date.now() - 3 * 24 * 60 * 60 * 1000);
    expect(formatRelativeTime(threeDaysAgo)).toBe('3 days ago');
  });
});

describe('formatCredits', () => {
  it('returns 0.00 for undefined', () => {
    expect(formatCredits(undefined)).toBe('0.00');
  });

  it('formats to 2 decimal places', () => {
    expect(formatCredits(1)).toBe('1.00');
    expect(formatCredits(10.5)).toBe('10.50');
    expect(formatCredits(0.125)).toBe('0.13'); // Standard rounding
  });
});

describe('truncate', () => {
  it('returns original if short enough', () => {
    expect(truncate('hello', 10)).toBe('hello');
  });

  it('truncates with ellipsis', () => {
    expect(truncate('hello world', 8)).toBe('hello...');
  });

  it('handles exact length', () => {
    expect(truncate('hello', 5)).toBe('hello');
  });
});

describe('truncatePath', () => {
  it('returns original if short enough', () => {
    expect(truncatePath('/home/user', 20)).toBe('/home/user');
  });

  it('truncates long paths from middle', () => {
    const path = '/home/user/documents/important/file.txt';
    const result = truncatePath(path, 20);
    expect(result).toContain('...');
    expect(result).toContain('file.txt');
  });
});

describe('getStatusColor', () => {
  it('returns green for active/completed states', () => {
    expect(getStatusColor('active')).toContain('green');
    expect(getStatusColor('completed')).toContain('green');
    expect(getStatusColor('success')).toContain('green');
    expect(getStatusColor('healthy')).toContain('green');
  });

  it('returns blue for pending/running states', () => {
    expect(getStatusColor('pending')).toContain('blue');
    expect(getStatusColor('running')).toContain('blue');
  });

  it('returns yellow for warning states', () => {
    expect(getStatusColor('warning')).toContain('yellow');
  });

  it('returns red for error/failed states', () => {
    expect(getStatusColor('error')).toContain('red');
    expect(getStatusColor('failed')).toContain('red');
    expect(getStatusColor('cancelled')).toContain('red');
  });

  it('returns slate for unknown states', () => {
    expect(getStatusColor('unknown')).toContain('slate');
  });

  it('is case insensitive', () => {
    expect(getStatusColor('ACTIVE')).toContain('green');
    expect(getStatusColor('Pending')).toContain('blue');
  });
});
