import { formatDate } from '@daysnap/utils'
import type { CalendarDay } from './types'
type calendarGenerator = (firstDayOfMonth: Date, maxDate?: Date, minDate?: Date) => CalendarDay[]
export const calendarGenerator: calendarGenerator = (firstDayOfMonth, maxDate, minDate) => {
  if (minDate) {
    minDate = new Date(formatDate(minDate, 'yyyy/MM/dd'))
  }
  if (maxDate) {
    maxDate = new Date(formatDate(maxDate, 'yyyy/MM/dd'))
  }

  //一页要显示多少天，因为一个月最多31天，也就是最多一个月最多有六周，也就是现实6*7天,先把这个容器准备好
  const date: CalendarDay[] = new Array(6 * 7)
  //先算出来这月第一天是周几
  const year = firstDayOfMonth.getFullYear()
  const month = firstDayOfMonth.getMonth() + 1
  const firstDayOfWeek = firstDayOfMonth.getDay() || 7 //获取当月第一天是星期几
  const dayCountOfThisMonth = new Date(year, month, 0).getDate() //获取本月中天数
  const prevIndexOfThisMonth = firstDayOfWeek - 1 //把周几转换成index
  const NextIndexOfThisMonth = firstDayOfWeek + dayCountOfThisMonth - 2 //这个月的最后一天转换成index
  const dayCountOfPrevMonth = new Date(year, month - 1, 0).getDate() //获取上一月中天数
  const prevDateMonth = new Date(year, month - 1, 0) //创建一个上一个月的Date对象
  const nextDateMonth = new Date(year, month + 1, 0) //创建一个上一个月的Date对象
  // isGrey是用来判断他如果不是本月的日子就给个灰色
  for (let i = 0; i < 6 * 7; i++) {
    // 上月
    if (i < prevIndexOfThisMonth) {
      //firstDayOfWeek-1转换成index -1 转换成间隔几天 +i 算上当天是几号
      const value = dayCountOfPrevMonth - (firstDayOfWeek - 1 - 1) + i
      prevDateMonth.setDate(value)
      const dateTime = formatDate(prevDateMonth, 'yyyy/MM/dd')
      date[i] = {
        value,
        dateTime,
        isOtherDays: true,
        disable: false,
      }
    }
    //本月
    if (i >= prevIndexOfThisMonth && i <= NextIndexOfThisMonth) {
      const value = i - (firstDayOfWeek - 1) + 1
      firstDayOfMonth.setDate(value)
      const dateTime = formatDate(firstDayOfMonth, 'yyyy/MM/dd')
      date[i] = {
        value,
        dateTime,
        isOtherDays: false,
        disable: false,
      }
    }
    // 下月
    if (i > NextIndexOfThisMonth) {
      const value = i - firstDayOfWeek - dayCountOfThisMonth + 2
      nextDateMonth.setDate(value)
      const dateTime = formatDate(nextDateMonth, 'yyyy/MM/dd')
      date[i] = {
        value,
        dateTime,
        isOtherDays: true,
        disable: false,
      }
    }
  }
  date.forEach((i) => {
    if (maxDate) {
      i.disable = new Date(i.dateTime).getTime() > maxDate.getTime()
    }
    if (minDate) {
      i.disable = new Date(i.dateTime).getTime() < minDate.getTime()
    }
    if (maxDate && minDate) {
      i.disable =
        new Date(i.dateTime).getTime() > maxDate.getTime() ||
        new Date(i.dateTime).getTime() < minDate.getTime()
    }
  })
  return date
}
