import { describe, it, expect } from 'vitest';
import {
  getDefaultDateRange,
  getDateRangeByPreset,
  buildCustomDateRange,
  isDateInRange,
  formatDateRange,
  datePresets,
} from '@/lib/utils/date';

describe('datePresets', () => {
  it('contains 5 presets', () => {
    expect(datePresets).toHaveLength(5);
  });

  it('includes the expected preset keys', () => {
    const keys = datePresets.map((p) => p.key);
    expect(keys).toEqual([
      'last7Days',
      'last30Days',
      'last90Days',
      'last12Months',
      'yearToDate',
    ]);
  });
});

describe('getDefaultDateRange', () => {
  it('returns a range labelled "Last 12 Months"', () => {
    const range = getDefaultDateRange();
    expect(range.label).toBe('Last 12 Months');
  });

  it('returns start before end', () => {
    const range = getDefaultDateRange();
    expect(range.start.getTime()).toBeLessThan(range.end.getTime());
  });
});

describe('getDateRangeByPreset', () => {
  it('builds a range for each known preset', () => {
    for (const preset of datePresets) {
      const range = getDateRangeByPreset(preset.key);
      expect(range.label).toBe(preset.label);
      expect(range.start.getTime()).toBeLessThan(range.end.getTime());
    }
  });

  it('throws for an unknown preset key', () => {
    // @ts-expect-error — intentionally passing invalid key
    expect(() => getDateRangeByPreset('unknown')).toThrow('Unknown date preset');
  });
});

describe('buildCustomDateRange', () => {
  it('creates a range with a formatted label', () => {
    const start = new Date(2025, 0, 1);
    const end = new Date(2025, 5, 30);
    const range = buildCustomDateRange(start, end);

    expect(range.start).toEqual(start);
    expect(range.end).toEqual(end);
    expect(range.label).toContain('Jan');
    expect(range.label).toContain('Jun');
  });

  it('throws when start >= end', () => {
    const d = new Date(2025, 0, 1);
    expect(() => buildCustomDateRange(d, d)).toThrow('Start date must be before end date');
  });
});

describe('isDateInRange', () => {
  const range = {
    start: new Date(2025, 0, 1),
    end: new Date(2025, 5, 30),
    label: 'test',
  };

  it('returns true for a date inside the range', () => {
    expect(isDateInRange(new Date(2025, 3, 15), range)).toBe(true);
  });

  it('returns true for the start boundary', () => {
    expect(isDateInRange(range.start, range)).toBe(true);
  });

  it('returns true for the end boundary', () => {
    expect(isDateInRange(range.end, range)).toBe(true);
  });

  it('returns false for a date before the range', () => {
    expect(isDateInRange(new Date(2024, 11, 31), range)).toBe(false);
  });

  it('returns false for a date after the range', () => {
    expect(isDateInRange(new Date(2025, 6, 1), range)).toBe(false);
  });
});

describe('formatDateRange', () => {
  it('formats a range as "Mon D, YYYY – Mon D, YYYY"', () => {
    const range = {
      start: new Date(2025, 0, 1),
      end: new Date(2025, 5, 30),
      label: 'test',
    };
    const formatted = formatDateRange(range);
    expect(formatted).toContain('Jan');
    expect(formatted).toContain('2025');
    expect(formatted).toContain('–');
    expect(formatted).toContain('Jun');
  });
});
