<template>
  <Popup
    :show="popupShow"
    @close="onCancel"
    :closeIcon="false"
    position="bottom"
    closeable
  >
    <ActionSheetTitle 
      v-bind="titleProps"
      :title="title"
      :confirmDisabled="confirmDisabled"
      border
      @cancel="onCancel"
      @confirm="onConfirm"
    />
    <Height :size="20" />
    <Calendar 
      v-if="popupShow"
      v-bind="props"
      v-model="tempValue"
      @selectTextChange="onSelectTextChange"
    />
    <slot name="footer">
      <Height :size="20" />
    </slot>
  </Popup>
  <Text 
    v-if="showSelectText"
    :size="30"
    :color="selectText ? 'text.content' : 'text.second'"
    :text="selectText || placeholder" 
    :maxWidth="300"
    v-bind="textProps"
  />
</template>

<script setup lang="ts">
import { computed, ref, toRef, watch } from 'vue';
import { useFieldChildValueInjector } from './FormContext';
import { usePickerFieldTempStorageData } from './PickerUtils';
import type { CalendarProps } from './Calendar.vue';
import Popup from '../dialog/Popup.vue';
import ActionSheetTitle, { type ActionSheetTitleProps } from '../dialog/ActionSheetTitle.vue';
import Calendar from './Calendar.vue';
import Height from '../layout/space/Height.vue';
import Text, { type TextProps } from '../basic/Text.vue';
import { usePickerFieldInstance, type PickerFieldInstance } from './Picker';

export interface CalendarFieldProps extends Omit<CalendarProps, 'modelValue'> {
  
  modelValue?: string|string[];
  /**
   * 标题
   */
  title?: string,
  /**
   * 标题属性
   */
  titleProps?: Omit<ActionSheetTitleProps, 'title'>,
  /**
   * 是否显示选择的文本。
   * @default true
   */
  showSelectText?: boolean,
  /**
   * 占位符
   */
  placeholder?: string,
  /**
   * 初始值
   */
  initalValue?: string[],
  /**
   * 是否在选择完成后立即更新值。
   * @default false
   */
  shouldUpdateValueImmediately?: boolean,
  /**
   * 显示的文本属性
   */
  textProps?: TextProps,
  /**
   * 是否在单选或者范围模式下，选择完成后直接关闭。
   * @default false
   */
  autoConfirm?: boolean,
  /**
   * 确认前的回调
   * @param value 选中的值
   * @returns 返回true可以阻止关闭弹窗
   */
  beforeConfirm?: (value: string|string[]|undefined) => Promise<boolean>,
}

const emit = defineEmits([ 'update:modelValue', 'cancel', 'confirm', 'selectTextChange', 'tempValueChange' ]);
const props = withDefaults(defineProps<CalendarFieldProps>(), {
  title: '请选择日期',
  placeholder: '请选择日期',
  titleProps: () => ({
    cancelText: '取消',
    confirmText: '确定',
  }),
  showSelectText: true,
  showFestival: true,
});

const confirmDisabled = computed(() => {
  switch (props.pickType) {
    default:
    case 'days':
    case 'day':
      return (tempValue.value?.length || 0) < 1;
    case 'range':
      return tempValue.value?.length !== 2;
  }
})

const popupShow = ref(false);

const {
  value,
  updateValue,
} = useFieldChildValueInjector(
  toRef(props, 'modelValue'), 
  (v) => emit('update:modelValue', v),
  undefined,
  () => {
    popupShow.value = true;
  },
  props.initalValue,
);

const {
  onSelectTextChange,
  onCancel,
  onConfirm,
  selectText,
  tempValue,
} = usePickerFieldTempStorageData(
  value,
  updateValue,
  () => popupShow.value = false,
  emit as any,
  [],
  props.shouldUpdateValueImmediately,
  props.beforeConfirm,
  popupShow,
);

watch(tempValue, (v) => {
  if (props.autoConfirm) {
    switch (props.pickType) {
      default:
      case 'day':
        if (v?.length)
          onConfirm();
        break;
      case 'range':
        if (v?.length === 2)
          onConfirm();
        break;
      case 'days':
        if ((v?.length || 0) >= (props.maxPickRangeDays || 100))
          onConfirm();
        break;
    }
  }
})

defineExpose<PickerFieldInstance>(usePickerFieldInstance(popupShow));
  
defineOptions({
  options: {
    styleIsolation: "shared",
    virtualHost: true,
  }
})
</script>