import { createComponentFactory, Spectator } from '@ngneat/spectator/jest';
import { SelectedMonthYearComponent } from './selected-month-year.component';
import { DatepickerViewState } from '../../datepicker-view.state';
import { format } from 'date-fns';

// Create a spy function to simulate the displayed date behavior
const displayedDateSpy = jest.fn();

// Include needed property "displayedView" as a function
const fakeViewState = {
  displayedDate: displayedDateSpy,
  displayedView: displayedDateSpy,
} as unknown as Partial<DatepickerViewState>;

const createComponent = createComponentFactory({
  component: SelectedMonthYearComponent,
  providers: [
    {
      provide: DatepickerViewState,
      useValue: fakeViewState,
    },
  ],
});

describe('SelectedMonthYearComponent', () => {
  let spectator: Spectator<SelectedMonthYearComponent>;

  beforeEach(() => {
    // Set a default displayed date: January 15, 2024
    displayedDateSpy.mockReturnValue(new Date(2024, 0, 15));
    spectator = createComponent();
  });

  it('should create the component', () => {
    expect(spectator.component).toBeTruthy();
  });

  it('should compute the correct month name', () => {
    const expectedMonth = format(new Date(2024, 0, 15), 'LLLL');
    expect(spectator.component.monthName()).toBe(expectedMonth);
  });

  it('should compute the correct year number', () => {
    const expectedYear = format(new Date(2024, 0, 15), 'yyyy');
    expect(spectator.component.yearNumber()).toBe(expectedYear);
  });

  it('should update computed properties when the displayed date changes', () => {
    const newDate = new Date(2025, 5, 10);
    // Update fake view state's displayedDate function to return newDate.
    displayedDateSpy.mockReturnValue(newDate);

    // Re-create the component so that computed properties are initialized with the new value.
    spectator = createComponent();
    spectator.detectChanges();

    const expectedMonth = format(newDate, 'LLLL');
    const expectedYear = format(newDate, 'yyyy');

    expect(spectator.component.monthName()).toBe(expectedMonth);
    expect(spectator.component.yearNumber()).toBe(expectedYear);
  });
});
