import { Lunar, Solar } from 'lunar-javascript'
import { DateInfoT } from './types'

// The number of days the month panel displays
export const DATE_SHOW_COUNT = 42
export const now = new Date()
export const getMonthLength = (year, month) => new Date(year, month, 0).getDate()

// get the day info by timestamp
export function getDateInfoByTimestamp(timestamp?): DateInfoT {
  const d = timestamp ? new Date(timestamp) : new Date()
  const date = d.getDate()
  const month = d.getMonth() + 1
  const year = d.getFullYear()
  const week = d.getDay()
  const lunar = Lunar.fromDate(d)
  const solar = Solar.fromYmd(year, month, date)
  const isToday = now.getFullYear() === year && now.getMonth() + 1 === month && now.getDate() === date

  return {
    date,
    month,
    year,
    week,
    lunarYear: lunar.getYearInChinese(),
    lunarMonth: lunar.getMonthInChinese(),
    lunarDate: lunar.getDayInChinese(),
    festivals: solar.getFestivals().concat(lunar.getFestivals()),
    jieqi: lunar.getJieQi(),
    isToday
  }
}

// get month info by year-month
export function getMonthInfo(year: number, month: number) {
  const count = getMonthLength(year, month)
  const days = []
  for (let i = 1; i <= count; i++) {
    const timestamp = new Date(year, month - 1, i).getTime()
    days.push(getDateInfoByTimestamp(timestamp))
  }

  // prev month
  const firstDayWeek = new Date(`${year}/${month}/1`).getDay()
  let preYear = year
  let preMonth = month
  if (month === 1) {
    preMonth = 12
    preYear -= 1
  } else {
    preMonth -= 1
  }

  const preMonthCount = new Date(preYear, preMonth, 0).getDate()
  for (let i = preMonthCount; i > preMonthCount - firstDayWeek; i--) {
    const timestamp = new Date(`${preYear}/${preMonth}/${i}`).getTime()
    const info = getDateInfoByTimestamp(timestamp)
    info['isAdditional'] = true
    days.unshift(info)
  }

  // next month
  let nextYear = year
  let nextMonth = month
  if (month === 12) {
    nextMonth = 1
    nextYear += 1
  } else {
    nextMonth += 1
  }
  const fillCount = DATE_SHOW_COUNT - days.length
  for (let i = 1; i <= fillCount; i++) {
    const timestamp = new Date(`${nextYear}/${nextMonth}/${i}`).getTime()
    const info = getDateInfoByTimestamp(timestamp)
    info['isAdditional'] = true
    days.push(info)
  }
  return days
}

// get year info by year
export function getYearInfo(year: number) {
  const months = []
  for (let i = 1; i <= 12; i++) {
    const days = getMonthInfo(year, i)
    months.push(days)
  }
  return months
}

// fromat the data as 7 elements per line
export function formatDaysForWeek(days) {
  const res = []
  while (days.length) {
    res.push(days.splice(0, 7))
  }
  return res
}

export function getNearbyYears(year) {
  const count = 12
  if (!year) {
    return []
  }
  const years = [year]
  for (let i = 1; i <= count - 1; i++) {
    years.push(year + i)
  }
  return years
}

// quickly select months based on basetime parameter
export function quickMonthRange(amount = 1, basetime = '') {
  const { date, month, year } = getDateInfoByTimestamp(basetime)
  let targetYear = year
  let targetMonth = month + amount
  let targetDate = date

  if (targetMonth > 12) {
    // forward and not this year
    const yearIncremental = Math.floor(targetMonth / 13)
    targetMonth = targetMonth % 12 || 12
    targetYear += yearIncremental
  } else if (targetMonth <= 0) {
    // backward and not this year
    const yearIncremental = Math.ceil(targetMonth / 12) - 1
    targetMonth = 12 + (targetMonth % 12)
    targetYear += yearIncremental
  }

  const targetMonthLength = getMonthLength(targetYear, targetMonth)
  targetDate = date > targetMonthLength ? targetMonthLength : date

  return `${targetYear}-${targetMonth}-${targetDate}`
}

export const isEqualDate = (startDate, endDate) => {
  const start: any = new Date(startDate + ' 00:00:00')
  const end: any = new Date(endDate + ' 00:00:00')
  return start - end === 0
}
