import {
  msToMinPerKm,
  mToKm,
  formatDuration,
  formatHeartRate,
  getHeartRateZone,
  formatSpeed,
  formatElevation,
  formatPower,
  formatCadence,
  formatTemperature,
  formatDate,
  formatCalories,
  convertPace
} from './index';

describe('Data Format Library', () => {
  describe('msToMinPerKm', () => {
    it('should convert m/s to min/km correctly', () => {
      expect(msToMinPerKm(5)).toBe('3:20'); // 5 m/s = 3:20 min/km
      expect(msToMinPerKm(4)).toBe('4:10'); // 4 m/s = 4:10 min/km
      expect(msToMinPerKm(3)).toBe('5:33'); // 3 m/s = 5:33 min/km
    });

    it('should handle string input', () => {
      expect(msToMinPerKm('5')).toBe('3:20');
    });

    it('should handle invalid input', () => {
      expect(msToMinPerKm(0)).toBe('-');
      expect(msToMinPerKm(-1)).toBe('-');
      expect(msToMinPerKm('abc')).toBe('-');
    });
  });

  describe('mToKm', () => {
    it('should convert meters to km for values >= 1000', () => {
      expect(mToKm(1000)).toBe('1.0 km');
      expect(mToKm(1500)).toBe('1.5 km');
      expect(mToKm(2345)).toBe('2.3 km');
    });

    it('should keep meters for values < 1000', () => {
      expect(mToKm(500)).toBe('500 m');
      expect(mToKm(999)).toBe('999 m');
    });

    it('should handle string input', () => {
      expect(mToKm('1500')).toBe('1.5 km');
    });

    it('should handle invalid input', () => {
      expect(mToKm(0)).toBe('-');
      expect(mToKm(-100)).toBe('-');
      expect(mToKm('abc')).toBe('-');
    });
  });

  describe('formatDuration', () => {
    it('should format duration in hh:mm:ss format', () => {
      expect(formatDuration(3661)).toBe('1:01:01');
      expect(formatDuration(125)).toBe('2:05');
      expect(formatDuration(45)).toBe('0:45');
    });

    it('should format duration in mm:ss format', () => {
      expect(formatDuration(125, 'mm:ss')).toBe('2:05');
      expect(formatDuration(3661, 'mm:ss')).toBe('61:01');
    });

    it('should format duration in human readable format', () => {
      expect(formatDuration(3661, 'humanReadable')).toBe('1h 1m 1s');
      expect(formatDuration(125, 'humanReadable')).toBe('2m 5s');
      expect(formatDuration(45, 'humanReadable')).toBe('45s');
    });

    it('should handle invalid input', () => {
      expect(formatDuration(0)).toBe('-');
      expect(formatDuration(-1)).toBe('-');
      expect(formatDuration('abc')).toBe('-');
    });
  });

  describe('formatHeartRate', () => {
    it('should format heart rate with unit', () => {
      expect(formatHeartRate(150)).toBe('150 bpm');
      expect(formatHeartRate(72.5)).toBe('73 bpm');
    });

    it('should format heart rate without unit', () => {
      expect(formatHeartRate(150, false)).toBe('150');
    });

    it('should handle invalid input', () => {
      expect(formatHeartRate(0)).toBe('-');
      expect(formatHeartRate(-1)).toBe('-');
    });
  });

  describe('getHeartRateZone', () => {
    it('should calculate heart rate zones correctly', () => {
      const zone1 = getHeartRateZone(100, 200);
      expect(zone1.zone).toBe(1);
      expect(zone1.zoneName).toBe('Warm-up');
      expect(zone1.percentage).toBe(50);

      const zone3 = getHeartRateZone(150, 200);
      expect(zone3.zone).toBe(3);
      expect(zone3.zoneName).toBe('Cardio');
      expect(zone3.percentage).toBe(75);
    });

    it('should calculate max HR from age if not provided', () => {
      const zone = getHeartRateZone(150, undefined, 30); // Max HR = 190
      expect(zone.percentage).toBeCloseTo(78.95, 1);
      expect(zone.zone).toBe(3);
    });
  });

  describe('formatSpeed', () => {
    it('should format speed in km/h', () => {
      expect(formatSpeed(5)).toBe('18.0 km/h');
      expect(formatSpeed(10)).toBe('36.0 km/h');
    });

    it('should format speed in m/s', () => {
      expect(formatSpeed(5, 'ms')).toBe('5.0 m/s');
    });
  });

  describe('formatElevation', () => {
    it('should format elevation in meters', () => {
      expect(formatElevation(1500)).toBe('1500 m');
      expect(formatElevation(1234.56)).toBe('1235 m');
    });

    it('should format elevation in feet', () => {
      expect(formatElevation(100, 'ft')).toBe('328 ft');
    });
  });

  describe('formatPower', () => {
    it('should format power with unit', () => {
      expect(formatPower(250)).toBe('250 W');
      expect(formatPower(175.5)).toBe('176 W');
    });

    it('should format power without unit', () => {
      expect(formatPower(250, false)).toBe('250');
    });
  });

  describe('formatCadence', () => {
    it('should format running cadence', () => {
      expect(formatCadence(180)).toBe('180 spm');
    });

    it('should format cycling cadence', () => {
      expect(formatCadence(90, 'cycling')).toBe('90 rpm');
    });
  });

  describe('formatTemperature', () => {
    it('should format temperature in Celsius', () => {
      expect(formatTemperature(25)).toBe('25°C');
      expect(formatTemperature(25.7)).toBe('26°C');
    });

    it('should format temperature in Fahrenheit', () => {
      expect(formatTemperature(25, 'F')).toBe('77°F');
      expect(formatTemperature(0, 'F')).toBe('32°F');
    });
  });

  describe('formatCalories', () => {
    it('should format calories with unit', () => {
      expect(formatCalories(500)).toBe('500 cal');
      expect(formatCalories(1234.56)).toBe('1235 cal');
    });

    it('should format calories without unit', () => {
      expect(formatCalories(500, false)).toBe('500');
    });
  });

  describe('convertPace', () => {
    it('should convert between pace units', () => {
      // 5:00 min/km to min/mi (should be ~8:03)
      expect(convertPace(5, 'min/km', 'min/mi')).toBe('8:03');
      
      // 8:00 min/mi to min/km (should be ~4:58)
      expect(convertPace(8, 'min/mi', 'min/km')).toBe('4:58');
    });
  });
});