import { Injectable } from '@angular/core';
import { DateAdapter } from './date.adapter';
import { MONTH_NAMES } from './constants';

@Injectable()
export class NativeDateAdapter extends DateAdapter<Date> {
  getYear(date: Date): number {
    return date.getFullYear();
  }
  getMonth(date: Date): number {
    return date.getMonth();
  }
  getDate(date: Date): number {
    return date.getDate();
  }
  getYearName(date: Date): string {
    return this.getYear(date).toString();
  }
  getMonthName(date: Date): string {
    return MONTH_NAMES[this.getMonth(date)];
  }
  getDateName(date: Date): string {
    return this.getDate(date).toString();
  }
  addCalendarMonths(date: Date, months: number): Date {
    return this.createDate(this.getYear(date), this.getMonth(date) + months, this.getDate(date));
  }
  addCalendarDays(date: Date, days: number): Date {
    return this.createDate(this.getYear(date), this.getMonth(date), this.getDate(date) + days);
  }

  getFirstDateOfWeek(date: Date): Date {
    const clone = new Date(date);
    const day = clone.getDay();
    const diff = clone.getDate() - day + (day === 0 ? -6 : 1); // Start of Week = Monday
    return new Date(clone.setDate(diff));
  }

  getLastDateOfWeek(date: Date): Date {
    const clone = new Date(date);
    const day = clone.getDay();
    const diff = clone.getDate() - day + (day === 0 ? 0 : 7); // End of Week = Sunday
    return new Date(clone.setDate(diff));
  }

  getFirstDateOfMonth(date: Date) {
    return this.createDate(this.getYear(date), this.getMonth(date), 1);
  }

  getLastDateOfMonth(date: Date) {
    return this.createDate(this.getYear(date), this.getMonth(date) + 1, 0);
  }

  getDifferenceInDays(first: Date, second: Date) {
    return (first.getTime() - second.getTime()) / (1000 * 3600 * 24);
  }

  getDayOfWeek(date: Date) {
    return date.getDay();
  }

  createDate(year: number, month: number, date: number): Date {
    const result = new Date(year, month, date);
    // abbreviations for 19xx.
    if (year >= 0 && year < 100) {
      result.setFullYear(this.getYear(result) - 1900);
    }
    return result;
  }

  today(): Date {
    return new Date();
  }

  isValid(date: Date): boolean {
    return date instanceof Date && !isNaN(date.getDate());
  }
}
