<template>
  <Touchable
    position="relative"
    center width="14.28%"
    :height="height"
    :backgroundColor="itemColor"
    :padding="[ 0,0,10,0]"
    touchable
    direction="column"
    @click="() => emit('click', props.date)"
    v-bind="calendarContext.itemProps.value"
  >
    <Text 
      v-if="!header"
      :color="textColor" 
      :fontSize="calendarContext.itemSizes.value.CalendarTopTextSize" 
      v-bind="topTextProps"
    >
      {{ topText || '&nbsp;' }}
    </Text>
    <Text 
      :color="textColor" 
      :fontSize="calendarContext.itemSizes.value.CalendarTextSize" 
      v-bind="textProps"
    >
      {{ text || '&nbsp;' }}
    </Text>
    <Text 
      v-if="!header"
      :lines="1"
      :color="textColor" 
      :fontSize="calendarContext.itemSizes.value.CalendarBottomTextSize" 
      v-bind="bottomTextProps"
    >
      {{ finalBottomText || '&nbsp;' }}
    </Text>
  </Touchable>
</template>

<script setup lang="ts">
import { computed, inject } from 'vue';
import { DateUtils } from '@imengyu/imengyu-utils';
import type { TextProps } from '../basic/Text.vue';
import type { CalendarContext } from './Calendar.vue';
import Text from '../basic/Text.vue';
import Touchable from '../feedback/Touchable.vue';

export interface CalendarItemProps {
  disabled?: boolean,
  header?: boolean,
  date: string,
  bottomText?: string,
  bottomTextProps?: TextProps,
  text?: string,
  textColor?: string,

  /**
   * 自定义日期文字的样式
   */
  textProps?: TextProps,
  topText?: string,
  topTextProps?: TextProps,

  height?: number|string,
}

const emit = defineEmits(['click']);
const props = withDefaults(defineProps<CalendarItemProps>(), {
});

const calendarContext = inject('calendarContext') as CalendarContext;

const state = computed(() => {
  //'normal'|'selected'|'selectedInRange'|'disabled',
  if (props.disabled || calendarContext.disabledDates.value?.includes(props.date)) 
    return 'disabled';

  switch (calendarContext.pickType.value) {
    case 'day': 
      if (calendarContext.pickValue.value === props.date)
        return 'selected';
      break; 
    case 'days':
      if ((calendarContext.pickValue.value as string[]).includes(props.date))
        return 'selected';
      break;
    case 'range': {
      const [
        start,
        end
      ] = calendarContext.pickValue.value as string[];
      
      if (start === props.date || end === props.date)
        return 'selected';
      if (start && end) {
        const startDate = DateUtils.parseDate(start);
        const endDate = DateUtils.parseDate(end);
        const currentDate = DateUtils.parseDate(props.date);
        if (currentDate >= startDate && currentDate <= endDate)
          return 'selectedInRange';
      }
      break;
    }
  }
  return 'normal';
});

const textColor = computed(() => {
  switch (state.value) {
    case 'normal':
      return props.textColor;
    case 'selected':
      return calendarContext.itemColors.value.CalendarTextColorSelected;
    case 'selectedInRange':
      return calendarContext.itemColors.value.CalendarTextColorSelectedInRange;
    case 'disabled':
      return calendarContext.itemColors.value.CalendarTextColorDisabled;
  }
})
const itemColor = computed(() => {
  switch (state.value) {
    case 'normal':
      return calendarContext.itemColors.value.CalendarItemColorNormal;
    case 'selected':
      return calendarContext.itemColors.value.CalendarItemColorSelected;
    case 'selectedInRange':
      return calendarContext.itemColors.value.CalendarItemColorSelectedInRange;
    case 'disabled':
      return calendarContext.itemColors.value.CalendarItemColorDisabled;
  }
})

const finalBottomText = computed(() => {
  const pickText = calendarContext.pickStateText.value;
  if (pickText && (state.value === 'selected' || state.value === 'selectedInRange')) {
    const index = calendarContext.pickValue.value instanceof Array ? (calendarContext.pickValue.value as string[]).indexOf(props.date) : 0;
    let text = '';
    if (pickText instanceof Array)
      text = (pickText as string[])[index];
    else
      text = pickText;
    if (text)
      return text;
  }
  if (props.bottomText)
    return props.bottomText;
  return '';
})

defineOptions({
  options: {
    virtualHost: true,
  }
})
</script>
