import React, { useState, useEffect, useRef } from 'react';
import { View, Text, TouchableOpacity, ScrollView } from 'react-native';
import Utils from '../utils/date';
import requestAniFrame from '../utils/raf';
import { useConfig } from '../configprovider';
import calendarStyles from './styles';

type CalendarRef = {
  scrollToDate: (date: string) => void;
};
type InputDate = string | string[];

interface Day {
  day: string | number;
  type: string;
}

interface MonthInfo {
  curData: string[] | string;
  title: string;
  monthData: Day[];
  cssHeight?: number;
  cssScrollHeight?: number;
}

interface CalendarState {
  currDate: InputDate;
  touchParams: any;
  transformY: number;
  scrollDistance: number;
  defaultData: InputDate;
  chooseData: any;
  dayPrefix: string;
  startData: InputDate;
  endData: InputDate;
  isRange: boolean;
  timer: number;
  monthsData: any[];
  avgHeight: number;
  propStartDate: string;
  propEndDate: string;
  currentIndex: number;
  unLoadPrev: boolean;
  monthsNum: number;
}

export interface CalendarItemProps {
  type?: string;
  isAutoBackFill?: boolean;
  poppable?: boolean;
  visible?: boolean;
  title?: string;
  defaultValue: InputDate;
  startDate?: InputDate;
  endDate?: InputDate;
  showToday?: boolean;
  startText?: string;
  endText?: string;
  confirmText?: string;
  showTitle?: boolean;
  showSubTitle?: boolean;
  toDateAnimation?: boolean;
  onBtn?: (() => string | JSX.Element) | undefined;
  onDay?: ((date: Day) => string | JSX.Element) | undefined;
  onTopInfo?: ((date: Day) => string | JSX.Element) | undefined;
  onBottomInfo?: ((date: Day) => string | JSX.Element) | undefined;
  onChoose?: (data: any) => void;
  onUpdate?: () => void;
  onSelected?: (data: string) => void;
}
const defaultProps = {
  type: 'one',
  isAutoBackFill: false,
  poppable: true,
  visible: false,
  title: '日历选择',
  defaultValue: '',
  startDate: Utils.getDay(0),
  endDate: Utils.getDay(365),
  showToday: true,
  startText: '开始',
  endText: '结束',
  confirmText: '确认',
  showTitle: true,
  showSubTitle: true,
  toDateAnimation: true,
  onBtn: undefined,
  onDay: undefined,
  onTopInfo: undefined,
  onBottomInfo: undefined,
  onChoose: (data: any) => {},
  onUpdate: () => {},
  onSelected: (data: string) => {},
} as CalendarItemProps;

export const CalendarItem = React.forwardRef<
  CalendarRef,
  Partial<CalendarItemProps>
>((props, ref) => {
  const {
    type,
    isAutoBackFill,
    poppable,
    title,
    defaultValue,
    showToday,
    startText,
    endText,
    confirmText,
    showTitle,
    showSubTitle,
    toDateAnimation,
    onBtn,
    onDay,
    onTopInfo,
    onBottomInfo,
    onChoose,
    onUpdate,
    onSelected,
  } = { ...defaultProps, ...props };

  const { locale, theme } = useConfig();

  const styles = calendarStyles(theme);

  const weeks = locale.calendaritem.weekdays;
  const [yearMonthTitle, setYearMonthTitle] = useState('');
  const [monthsData, setMonthsData] = useState<any[]>([]);
  const [translateY, setTranslateY] = useState(0);
  const [monthDefaultRange, setMonthDefaultRange] = useState<number[]>([]);

  const [state] = useState<CalendarState>({
    currDate: '',
    propStartDate: '',
    propEndDate: '',
    unLoadPrev: false,
    touchParams: {
      startY: 0,
      endY: 0,
      startTime: 0,
      endTime: 0,
      lastY: 0,
      lastTime: 0,
    },
    transformY: 0,
    scrollDistance: 0,
    defaultData: [],
    chooseData: [],
    monthsData: [],
    dayPrefix: 'calendar-month-day',
    startData: '',
    endData: '',
    isRange: props.type === 'range',
    timer: 0,
    currentIndex: 0,
    avgHeight: 0,
    monthsNum: 0,
  });

  const weeksPanel = useRef<View|null>(null);
  const monthsScroll = useRef<ScrollView|null>(null);
  const monthsPanel = useRef<View|null>(null);
  const viewArea = useRef<View|null>(null);
  const scrollTop = useRef<number>(0);
  let viewHeight = 0;

  //   const b = bem('calendar')

  //   const classes = classNames(
  //     {
  //       [`${b('')}-tile`]: !poppable,
  //       [`${b('')}-nofooter`]: !!isAutoBackFill,
  //     },
  //     b('')
  //   )

  //   const headerClasses = classNames({
  //     [`${b('')}-header`]: true,
  //     [`${b('')}-header-tile`]: !poppable,
  //   })

  //   const monthitemclasses = classNames({
  //     'calendar-month-item': true,
  //     [`${type === 'range' ? 'month-item-range' : ''}`]: true,
  //   })

  const splitDate = (date: string) => {
    return date.split('-');
  };

  const isStart = (currDate: string) => {
    return Utils.isEqual(state.currDate[0], currDate);
  };

  const isEnd = (currDate: string) => {
    return Utils.isEqual(state.currDate[1], currDate);
  };

  const isMultiple = (currDate: string) => {
    if (state.currDate.length > 0) {
      return (state.currDate as string[]).some((item: string) => {
        return Utils.isEqual(item, currDate);
      });
    }
    return false;
  };

  const getCurrDate = (day: Day, month: MonthInfo) => {
    return `${month.curData[0]}-${month.curData[1]}-${Utils.getNumTwoBit(
      +day.day
    )}`;
  };

  const getClass = (day: Day, month: MonthInfo) => {
    const currDate = getCurrDate(day, month);
    if (day.type === 'curr') {
      if (
        Utils.isEqual(state.currDate as string, currDate) ||
        (type === 'range' && (isStart(currDate) || isEnd(currDate))) ||
        (type === 'multiple' && isMultiple(currDate))
      ) {
        return 'active';
      }
      if (
        (state.propStartDate &&
          Utils.compareDate(currDate, state.propStartDate)) ||
        (state.propEndDate && Utils.compareDate(state.propEndDate, currDate))
      ) {
        return 'disabled';
      }
      if (
        type === 'range' &&
        Array.isArray(state.currDate) &&
        Object.values(state.currDate).length === 2 &&
        Utils.compareDate(state.currDate[0], currDate) &&
        Utils.compareDate(currDate, state.currDate[1])
      ) {
        return 'choose';
      }

      return null;
    }

    return 'disabled';
  };

  const isActive = (day: Day, month: MonthInfo) => {
    return (
      state.isRange &&
      day.type === 'curr' &&
      getClass(day, month) === 'active'
    );
  };

  const isCurrDay = (month: MonthInfo, day: string | number) => {
    const date = `${month.curData[0]}-${month.curData[1]}-${day}`;
    return Utils.isEqual(date, Utils.date2Str(new Date()));
  };

  const confirm = () => {
    const { type } = props;
    if (
      (type === 'range' && state.chooseData.length === 2) ||
      type !== 'range'
    ) {
      const chooseData = state.chooseData.slice(0);
      onChoose && onChoose(chooseData);
      if (poppable) {
        onUpdate && onUpdate();
      }
    }
  };

  const chooseDay = (day: Day, month: MonthInfo, isFirst?: boolean) => {
    if (getClass(day, month) !== 'disabled') {
      const { type } = props;
      const days = [...month.curData];
      days[2] =
        typeof day.day === 'number' ? Utils.getNumTwoBit(day.day) : day.day;
      days[3] = `${days[0]}-${days[1]}-${days[2]}`;
      days[4] = Utils.getWhatDay(+days[0], +days[1], +days[2]);
      if (type === 'multiple') {
        if (state.currDate.length > 0) {
          let hasIndex: any = '';
          (state.currDate as string[]).forEach((item: any, index: number) => {
            if (item === days[3]) {
              hasIndex = index;
            }
          });
          if (isFirst) {
            state.chooseData.push([...days]);
          } else if (hasIndex !== '') {
            (state.currDate as string[]).splice(hasIndex, 1);
            state.chooseData.splice(hasIndex, 1);
          } else {
            (state.currDate as string[]).push(days[3]);
            state.chooseData.push([...days]);
          }
        } else {
          state.currDate = [days[3]];
          state.chooseData = [[...days]];
        }
      } else if (type === 'range') {
        const curDataLength = Object.values(state.currDate).length;
        if (curDataLength === 2 || curDataLength === 0) {
          state.currDate = [days[3]];
        } else if (Utils.compareDate(state.currDate[0], days[3])) {
          Array.isArray(state.currDate) && state.currDate.push(days[3]);
        } else {
          Array.isArray(state.currDate) && state.currDate.unshift(days[3]);
        }

        if (state.chooseData.length === 2 || !state.chooseData.length) {
          state.chooseData = [[...days]];
        } else if (Utils.compareDate(state.chooseData[0][3], days[3])) {
          state.chooseData = [...state.chooseData, [...days]];
        } else {
          state.chooseData = [[...days], ...state.chooseData];
        }
      } else {
        state.currDate = days[3];
        state.chooseData = [...days];
      }

      if (!isFirst) {
        // 点击日期 触发
        onSelected && onSelected(state.chooseData);
        if (isAutoBackFill || !poppable) {
          confirm();
        }
      }

      setMonthsData(state.monthsData.slice());
    }
  };

  const isStartTip = (day: Day, month: MonthInfo) => {
    return isActive(day, month) && isStart(getCurrDate(day, month));
  };

  // 是否有结束提示
  const isEndTip = (day: Day, month: MonthInfo) => {
    if (state.currDate.length >= 2 && isEnd(getCurrDate(day, month))) {
      return isActive(day, month);
    }
    return false;
  };

  // 开始结束时间是否相等
  const rangeTip = () => {
    if (state.currDate.length >= 2) {
      return Utils.isEqual(state.currDate[0], state.currDate[1]);
    }
    return false;
  };

  // 获取当前月数据
  const getCurrData = (type: string) => {
    const monthData =
      type === 'prev'
        ? state.monthsData[0]
        : state.monthsData[state.monthsData.length - 1];
    let year = parseInt(monthData.curData[0]);
    let month = parseInt(monthData.curData[1].toString().replace(/^0/, ''));
    switch (type) {
      case 'prev':
        month === 1 && (year -= 1);
        month = month === 1 ? 12 : --month;
        break;
      case 'next':
        month === 12 && (year += 1);
        month = month === 12 ? 1 : ++month;
        break;
      default:
        break;
    }
    return [
      year,
      Utils.getNumTwoBit(month),
      Utils.getMonthDays(String(year), String(month)),
    ];
  };

  // 获取日期状态
  const getDaysStatus = (days: number, type: string, dateInfo: any) => {
    // 修复：当某个月的1号是周日时，月份下方会空出来一行
    const { year, month } = dateInfo;
    if (type === 'prev' && days >= 7) {
      days -= 7;
    }
    return Array.from(Array(days), (v, k) => {
      return {
        day: k + 1,
        type,
        year,
        month,
      };
    });
  };

  // 获取上一个月的最后一周天数，填充当月空白
  const getPreDaysStatus = (
    days: number,
    type: string,
    dateInfo: any,
    preCurrMonthDays: number
  ) => {
    // 修复：当某个月的1号是周日时，月份下方会空出来一行
    const { year, month } = dateInfo;
    if (type === 'prev' && days >= 7) {
      days -= 7;
    }
    const months = Array.from(Array(preCurrMonthDays), (v, k) => {
      return {
        day: k + 1,
        type,
        year,
        month,
      };
    });
    return months.slice(preCurrMonthDays - days);
  };

  // 获取月数据
  const getMonth = (curData: string[], type: string) => {
    const preMonthDays = Utils.getMonthPreDay(+curData[0], +curData[1]);

    let preMonth = +curData[1] - 1;
    let preYear = curData[0];
    if (preMonth <= 0) {
      preMonth = 12;
      preYear += 1;
    }

    const currMonthDays = Utils.getMonthDays(curData[0], curData[1]);
    const preCurrMonthDays = Utils.getMonthDays(`${preYear}`, `${preMonth}`);

    const title = {
      year: curData[0],
      month: curData[1],
    };
    const monthInfo: MonthInfo = {
      curData,
      title: locale.calendaritem.monthTitle(title.year, title.month),
      monthData: [
        ...(getPreDaysStatus(
          preMonthDays,
          'prev',
          { month: preMonth, year: preYear },
          preCurrMonthDays
        ) as Day[]),
        ...(getDaysStatus(currMonthDays, 'curr', title) as Day[]),
      ],
    };
    monthInfo.cssHeight = 39 + (monthInfo.monthData.length > 35 ? 384 : 320);
    let cssScrollHeight = 0;
    if (state.monthsData.length > 0) {
      cssScrollHeight =
        state.monthsData[state.monthsData.length - 1].cssScrollHeight +
        state.monthsData[state.monthsData.length - 1].cssHeight;
    }
    monthInfo.cssScrollHeight = cssScrollHeight;
    if (type === 'next') {
      if (
        !state.endData ||
        !Utils.compareDate(
          `${state.endData[0]}-${state.endData[1]}-${Utils.getMonthDays(
            state.endData[0],
            state.endData[1]
          )}`,
          `${curData[0]}-${curData[1]}-${curData[2]}`
        )
      ) {
        state.monthsData.push(monthInfo);
      }
    } else if (
      !state.startData ||
      !Utils.compareDate(
        `${curData[0]}-${curData[1]}-${curData[2]}`,
        `${state.startData[0]}-${state.startData[1]}-01`
      )
    ) {
      state.monthsData.unshift(monthInfo);
    }

    setMonthsData(state.monthsData);
  };

  const setDefaultRange = (monthsNum: number, current: number) => {
    let start = 0;
    let end = 0;
    if (monthsNum >= 3) {
      if (current > 0 && current < monthsNum) {
        start = current - 1;
        end = current + 3;
      } else if (current === 0) {
        start = current;
        end = current + 4;
      } else if (current === monthsNum) {
        start = current - 2;
        end = current + 2;
      }
    } else {
      start = 0;
      end = monthsNum + 2;
    }
    setMonthDefaultRange([start, end]);
    setTranslateY(state.monthsData[start].cssScrollHeight);
  };

  const mothsViewScroll = (e: any) => {
    if (state.monthsData.length <= 1) {
      return;
    }
    const { y } = e.nativeEvent.contentOffset;
    const currentScrollTop = y;
    let current = Math.floor(currentScrollTop / state.avgHeight);
    current = current < 0 ? 0 : current;

    scrollTop.current = currentScrollTop;

    if (current === 0) {
      if (currentScrollTop >= state.monthsData[current + 1].cssScrollHeight) {
        current += 1;
      }
    } else if (current > 0 && current < state.monthsNum - 1) {
      if (currentScrollTop >= state.monthsData[current + 1].cssScrollHeight) {
        current += 1;
      }
      if (currentScrollTop < state.monthsData[current].cssScrollHeight) {
        current -= 1;
      }
    } else {
      const viewPosition = Math.round(currentScrollTop + viewHeight);
      if (
        viewPosition <
          state.monthsData[current].cssScrollHeight +
            state.monthsData[current].cssHeight &&
        currentScrollTop > state.monthsData[current - 1].cssScrollHeight
      ) {
        current -= 1;
      }
      if (
        current + 1 <= state.monthsNum &&
        viewPosition >=
          state.monthsData[current + 1].cssScrollHeight +
            state.monthsData[current + 1].cssHeight
      ) {
        current += 1;
      }
      if (
        current >= 1 &&
        currentScrollTop < state.monthsData[current - 1].cssScrollHeight
      ) {
        current -= 1;
      }
    }

    if (state.currentIndex !== current) {
      state.currentIndex = current;
      setDefaultRange(state.monthsNum, current);
    }

    setYearMonthTitle(state.monthsData[current].title);
  };

  const initData = () => {
    // 初始化开始结束数据
    const propStartDate = props.startDate ? props.startDate : Utils.getDay(0);
    const propEndDate = props.endDate ? props.endDate : Utils.getDay(365);
    state.propStartDate = propStartDate as string;
    state.propEndDate = propEndDate as string;
    state.startData = splitDate(propStartDate as string);
    state.endData = splitDate(propEndDate as string);

    // 根据是否存在默认时间，初始化当前日期
    if (
      defaultValue ||
      (Array.isArray(defaultValue) && defaultValue.length > 0)
    ) {
      state.currDate =
        props.type !== 'one'
          ? ([...(props.defaultValue as string[])] as string[])
          : (props.defaultValue as string[]);
    }

    // 判断时间范围内存在多少个月
    const startDate = {
      year: Number(state.startData[0]),
      month: Number(state.startData[1]),
    };
    const endDate = {
      year: Number(state.endData[0]),
      month: Number(state.endData[1]),
    };
    let monthsNum = endDate.month - startDate.month;
    if (endDate.year - startDate.year > 0) {
      monthsNum += 12 * (endDate.year - startDate.year);
    }
    if (monthsNum <= 0) {
      monthsNum = 1;
    }
    // 设置月份数据
    getMonth(state.startData, 'next');

    let i = 1;
    do {
      getMonth(getCurrData('next') as string[], 'next');
    } while (i++ < monthsNum);
    state.monthsNum = monthsNum;

    // 日期转化为数组，限制初始日期。判断时间范围
    if (type === 'range' && Array.isArray(state.currDate)) {
      if (state.currDate.length > 0) {
        if (
          propStartDate &&
          Utils.compareDate(state.currDate[0], propStartDate as string)
        ) {
          state.currDate.splice(0, 1, propStartDate as string);
        }
        if (
          propEndDate &&
          Utils.compareDate(propEndDate as string, state.currDate[1])
        ) {
          state.currDate.splice(1, 1, propEndDate as string);
        }
        state.defaultData = [
          ...splitDate(state.currDate[0]),
          ...splitDate(state.currDate[1]),
        ];
      }
    } else if (props.type === 'multiple' && Array.isArray(state.currDate)) {
      if (state.currDate.length > 0) {
        const defaultArr = [] as string[];
        const obj: Record<string, unknown> = {};
        state.currDate.forEach((item: string) => {
          if (
            propStartDate &&
            !Utils.compareDate(item, propStartDate as string) &&
            propEndDate &&
            !Utils.compareDate(propEndDate as string, item)
          ) {
            if (!Object.hasOwnProperty.call(obj, item)) {
              defaultArr.push(item);
              obj[item] = item;
            }
          }
        });
        state.currDate = [...defaultArr];
        state.defaultData = [...splitDate(defaultArr[0])];
      }
    } else if (state.currDate) {
      if (
        propStartDate &&
        Utils.compareDate(state.currDate as string, propStartDate as string)
      ) {
        state.currDate = propStartDate;
      } else if (
        propEndDate &&
        !Utils.compareDate(state.currDate as string, propEndDate as string)
      ) {
        state.currDate = propEndDate;
      }
      state.defaultData = [...splitDate(state.currDate as string)];
    }

    // 设置默认可见区域
    let current = 0;
    let lastCurrent = 0;
    if (state.defaultData.length > 0) {
      state.monthsData.forEach((item, index) => {
        if (
          item.title ===
          locale.calendaritem.monthTitle(
            state.defaultData[0],
            state.defaultData[1]
          )
        ) {
          current = index;
        }
        if (props.type === 'range') {
          if (
            item.title ===
            locale.calendaritem.monthTitle(
              state.defaultData[3],
              state.defaultData[4]
            )
          ) {
            lastCurrent = index;
          }
        }
      });
    }

    setDefaultRange(monthsNum, current);
    state.currentIndex = current;
    setYearMonthTitle(state.monthsData[state.currentIndex].title);

    if (state.defaultData.length > 0) {
      // 设置当前选中日期
      if (type === 'range') {
        chooseDay(
          { day: state.defaultData[2], type: 'curr' },
          state.monthsData[state.currentIndex],
          true
        );
        chooseDay(
          { day: state.defaultData[5], type: 'curr' },
          state.monthsData[lastCurrent],
          true
        );
      } else if (type === 'multiple') {
        [...state.currDate].forEach((item: string) => {
          const dateArr = splitDate(item);
          let current = state.currentIndex;
          state.monthsData.forEach((item, index) => {
            if (
              item.title ===
              locale.calendaritem.monthTitle(dateArr[0], dateArr[1])
            ) {
              current = index;
            }
          });
          chooseDay(
            { day: dateArr[2], type: 'curr' },
            state.monthsData[current],
            true
          );
        });
      } else {
        chooseDay(
          { day: state.defaultData[2], type: 'curr' },
          state.monthsData[state.currentIndex],
          true
        );
      }
    }

    const lastItem = state.monthsData[state.monthsData.length - 1];
    const containerHeight = lastItem.cssHeight + lastItem.cssScrollHeight;

    requestAniFrame(() => {
      // 初始化 日历位置
      if (monthsScroll && monthsPanel && viewArea) {
        (monthsScroll.current as any)?.measure((x, y, width, height, pageX, pageY)=>{
            viewHeight = height;
            monthsPanel.current?.setNativeProps({ style: { height: containerHeight } })
            monthsScroll.current?.scrollTo({ y: state.monthsData[state.currentIndex].cssScrollHeight, animated: false })
        })
      }
    })

    state.avgHeight = Math.floor(containerHeight / (monthsNum + 1));
  };

  const resetRender = () => {
    state.chooseData.splice(0);
    state.monthsData.splice(0);
    initData();
  };

  // 暴露出的API
  const scrollToDate = (date: string) => {
    if (Utils.compareDate(date, state.propStartDate)) {
      date = state.propStartDate;
    } else if (!Utils.compareDate(date, state.propEndDate)) {
      date = state.propEndDate;
    }
    const dateArr = splitDate(date);
    state.monthsData.forEach((item, index) => {
      if (
        item.title === locale.calendaritem.monthTitle(dateArr[0], dateArr[1])
      ) {
        if (monthsScroll.current) {
          const distance = state.monthsData[index].cssScrollHeight - scrollTop.current;
          if (toDateAnimation) {
            let flag = 0;
            const interval = setInterval(() => {
              flag++;
                const offset = distance / 10;
                monthsScroll.current?.scrollTo({y: scrollTop.current + offset, animated: false})

              if (flag >= 10) {
                clearInterval(interval);
                monthsScroll.current?.scrollTo({y: state.monthsData[index].cssScrollHeight, animated: false})
              }
            }, 40);
          } else {
            monthsScroll.current?.scrollTo({y: state.monthsData[index].cssScrollHeight, animated: false})
          }
        }
      }
    });
  };

  useEffect(() => {
    initData();
  }, []);

  useEffect(() => {
    poppable && resetRender();
  }, [defaultValue]);

  React.useImperativeHandle(ref, () => ({
    scrollToDate,
  }));

  return (
    <View style={styles.calendar}>
      {/* header */}
      <View style={styles.calendarHeader}>
        {showTitle && (
          <Text style={styles.calendarTitle}>
            {title || locale.calendaritem.title}
          </Text>
        )}
        {onBtn && <View style={styles.calendarTopSlot}>{onBtn()}</View>}
        {showSubTitle && (
          <Text style={styles.calendarCurrMonth}>{yearMonthTitle}</Text>
        )}
        <View style={styles.calendarWeeks} ref={weeksPanel}>
          {weeks.map((item: string, index: number) => (
            <Text style={[styles.calendarWeekItem,
                (!index || weeks.length-1 === index) && styles.calendarWeekday
            ]} key={item}>
              {item}
            </Text>
          ))}
        </View>
      </View>
      {/* content */}
      <ScrollView
        style={styles.calendarContent}
        onScroll={mothsViewScroll}
        ref={monthsScroll}
      >
        <View style={styles.calendarMonthsPanel} ref={monthsPanel}>
          <View
            ref={viewArea}
            style={{
              transform: [
                {
                  translateY: translateY,
                },
              ],
            }}
          >
            {state.monthsData
              .slice(monthDefaultRange[0], monthDefaultRange[1])
              .map((month: any, key: number) => {
                console.log('month', month)
                return (
                  <View style={styles.calendarMonth} key={key}>
                    <Text style={styles.calendarMonthTitle}>{month.title}</Text>
                    <View style={styles.calendarMonthItem}>
                      {month.monthData.map((day: Day, i: number) => (
                        <TouchableOpacity
                          activeOpacity={1}
                          style={[
                            styles.calendarMonthDay,
                            styles[`calendarMonthDay__${getClass(day, month)}`],
                          ]}
                          onPress={() => {
                            chooseDay(day, month);
                          }}
                          key={i}
                        >
                          <Text style={[
                            styles.calendarDay,
                            (i%7 === 0 || i%7===6) && day.type ==='curr' && styles.calendarMonthConDay,
                            styles[`calendarDay__${getClass(day, month)}`],
                          ]}>
                            {onDay ? onDay(day) : day.day}
                          </Text>
                          {onTopInfo && (
                            <Text
                              style={[
                                styles.calendarCurrTips,
                                styles.calendarCurrTipsTop,
                              ]}
                            >
                              {onTopInfo(day)}
                            </Text>
                          )}
                          {onBottomInfo && (
                            <Text
                              style={[
                                styles.calendarCurrTips,
                                styles.calendarCurrTipsBottom,
                                styles[`calendarCurrTips__${getClass(day, month)}`],
                              ]}
                            >
                              {onBottomInfo(day)}
                            </Text>
                          )}
                          {!onBottomInfo &&
                            showToday &&
                            isCurrDay(month, day.day) && (
                              <Text style={[
                                    styles.calendarCurrTipCurr,
                                    styles[`calendarCurrTipCurr__${getClass(day, month)}`],
                                ]}>
                                {locale.calendaritem.today}
                              </Text>
                            )}
                          {isStartTip(day, month) && (
                            <Text
                              style={[
                                styles.calendarDayTip,
                                rangeTip() && styles.calendarCurrTipsTop,
                                styles[`calendarDayTip__${getClass(day, month)}`],
                              ]}
                            >
                              {startText || locale.calendaritem.start}
                            </Text>
                          )}
                          {isEndTip(day, month) && (
                            <Text style={[
                                styles.calendarDayTip,
                                styles[`calendarDayTip__${getClass(day, month)}`],
                            ]}>
                              {endText || locale.calendaritem.end}
                            </Text>
                          )}
                        </TouchableOpacity>
                      ))}
                    </View>
                  </View>
                );
              })}
          </View>
        </View>
      </ScrollView>
      {/* footer */}
      {poppable && !isAutoBackFill ? (
        <View style={styles.calendarFooter}>
          <TouchableOpacity
            style={styles.calendarConfirmBtn}
            onPress={confirm}
            activeOpacity={1}
          >
            <Text style={styles.calendarConfirmBtnText}>
              {confirmText || locale.confirm}
            </Text>
          </TouchableOpacity>
        </View>
      ) : (
        null
      )}
    </View>
  );
});

CalendarItem.defaultProps = defaultProps;
CalendarItem.displayName = 'NutCalendarItem';
