import {
  AfterViewInit,
  ChangeDetectionStrategy,
  Component,
  forwardRef,
  inject,
} from '@angular/core';
import { CalendarBodyComponent } from './body/calendar-body/calendar-body.component';
import { SelectedRangeComponent } from './header/selected-range/selected-range.component';
import { SelectedMonthYearComponent } from './header/selected-month-year/selected-month-year.component';
import { MonthYearBodyComponent } from './body/month-year-body/month-year-body.component';
import { NG_VALUE_ACCESSOR } from '@angular/forms';
import { DatepickerViewState } from './datepicker-view.state';
import { RangeDatepicker } from './range-datepicker';

/**
 * A component that extends the RangeDatepicker to provide a fully featured date range
 * picker with additional view state management.
 *
 * This component handles changes to the date picker value and sets the default displayed
 * month and year accordingly.
 */
@Component({
  selector: 'ui-range-datepicker',
  templateUrl: 'range-datepicker.component.html',
  providers: [
    {
      provide: RangeDatepicker,
      useExisting: RangeDatepickerComponent,
    },
    {
      provide: NG_VALUE_ACCESSOR,
      useExisting: forwardRef(() => RangeDatepickerComponent),
      multi: true,
    },
    DatepickerViewState,
  ],
  standalone: true,
  changeDetection: ChangeDetectionStrategy.OnPush,
  imports: [
    SelectedMonthYearComponent,
    SelectedRangeComponent,
    CalendarBodyComponent,
    MonthYearBodyComponent,
  ],
  host: {
    '[class]': "['ui-range-datepicker']",
  },
})
export class RangeDatepickerComponent
  extends RangeDatepicker
  implements AfterViewInit
{
  /**
   * The view state for the Datepicker, injected via Angular's dependency injection.
   */
  viewState = inject(DatepickerViewState);

  /**
   * Lifecycle hook that is called after the component's view has been fully initialized.
   * Sets the default displayed date in the Datepicker view state based on the current value.
   *
   * @returns {void}
   */
  ngAfterViewInit(): void {
    this.viewState.displayedDate.set(this.setDefaultDisplayedMonthYear());
  }

  /**
   * Determines the default displayed month and year based on the current value.
   * If a date range is set, the start date is used;
   * otherwise, the current date is returned.
   *
   * @returns {Date} The default date to be displayed in the datepicker.
   */
  setDefaultDisplayedMonthYear(): Date {
    return this.value()?.[0] ?? new Date();
  }
}
