import { DateRange } from './date-range.vo';
import { ReportPeriod } from './report-period.enum';

describe('DateRange Value Object', () => {
  describe('create', () => {
    it('should create a date range', () => {
      const start = new Date(2024, 0, 1); // Jan 1, 2024
      const end = new Date(2024, 0, 31); // Jan 31, 2024
      const range = DateRange.create(start, end);

      expect(range.startDate).toEqual(start);
      expect(range.endDate).toEqual(end);
    });

    it('should throw error if start date is after end date', () => {
      const start = new Date(2024, 1, 1); // Feb 1, 2024
      const end = new Date(2024, 0, 31); // Jan 31, 2024

      expect(() => DateRange.create(start, end)).toThrow('开始日期不能大于结束日期');
    });
  });

  describe('static factory methods', () => {
    it('should create today range', () => {
      const range = DateRange.today();
      const now = new Date();

      expect(range.startDate.getDate()).toBe(now.getDate());
      expect(range.endDate.getDate()).toBe(now.getDate());
    });

    it('should create this week range', () => {
      const range = DateRange.thisWeek();

      expect(range.getDays()).toBe(7);
    });

    it('should create this month range', () => {
      const range = DateRange.thisMonth();
      const now = new Date();

      expect(range.startDate.getMonth()).toBe(now.getMonth());
      expect(range.startDate.getDate()).toBe(1);
    });

    it('should create this year range', () => {
      const range = DateRange.thisYear();
      const now = new Date();

      expect(range.startDate.getFullYear()).toBe(now.getFullYear());
      expect(range.startDate.getMonth()).toBe(0);
      expect(range.startDate.getDate()).toBe(1);
    });
  });

  describe('methods', () => {
    it('should calculate days correctly', () => {
      const start = new Date(2024, 0, 1, 0, 0, 0);
      const end = new Date(2024, 0, 10, 23, 59, 59);
      const range = DateRange.create(start, end);

      expect(range.getDays()).toBe(10);
    });

    it('should check if date is contained', () => {
      const start = new Date(2024, 0, 1);
      const end = new Date(2024, 0, 31);
      const range = DateRange.create(start, end);

      expect(range.contains(new Date(2024, 0, 15))).toBe(true);
      expect(range.contains(new Date(2024, 1, 1))).toBe(false);
    });

    it('should generate period key for daily', () => {
      const start = new Date(2024, 0, 15);
      const end = new Date(2024, 0, 15);
      const range = DateRange.create(start, end);

      expect(range.toPeriodKey(ReportPeriod.DAILY)).toBe('2024-01-15');
    });

    it('should generate period key for monthly', () => {
      const start = new Date(2024, 0, 1);
      const end = new Date(2024, 0, 31);
      const range = DateRange.create(start, end);

      expect(range.toPeriodKey(ReportPeriod.MONTHLY)).toBe('2024-01');
    });

    it('should generate period key for yearly', () => {
      const start = new Date(2024, 0, 1);
      const end = new Date(2024, 11, 31);
      const range = DateRange.create(start, end);

      expect(range.toPeriodKey(ReportPeriod.YEARLY)).toBe('2024');
    });
  });
});
