import { onMounted, ref, watch, type Ref } from "vue";

/**
 * 选择器字段临时存储数据的组合式函数
 * 用于管理选择器组件的临时值、选择文本和交互逻辑
 * 
 * @template T - 值的类型
 * @param value - 当前值的响应式引用
 * @param updateValue - 更新值的回调函数
 * @param closePopup - 关闭弹窗的回调函数
 * @param emit - 事件发射器函数
 * @param defaultNewValue - 默认的新值
 * @param shouldUpdateValueImmediately - 是否立即更新值至绑定值
 * @param beforeConfirm - 确认前的回调函数，返回true时取消确认
 * @param popupShow - 弹窗显示状态的响应式引用
 */
export function usePickerFieldTempStorageData<T>(
  value: Ref<T>, 
  updateValue: (d: T) => void,
  closePopup: () => void,
  emit: (name: string, d?: any) => void,
  defaultNewValue: T,
  shouldUpdateValueImmediately: boolean,
  requireFormat: (value: T) => string,
  beforeConfirm?: ((value: T) => Promise<boolean>) | undefined,
  popupShow?: Ref<boolean>,
) {

  // 临时值的响应式引用，初始值为当前值或默认新值
  const tempValue = ref(value.value ?? defaultNewValue) as Ref<T>;
  const beforeConfirmValue = ref(value.value ?? defaultNewValue) as Ref<T>;
  // 显示的文本的响应式引用
  const selectText = ref('');

  /**
   * 取消选择。恢复临时值为当前值或默认新值
   */
  function onCancel() {
    closePopup();
    tempValue.value = beforeConfirmValue.value;
    updateValue(tempValue.value);
    emit('cancel');
  }

  /**
   * 确认选择的处理函数
   */
  async function onConfirm() {
    closePopup();
    // 如果有确认前回调且返回true，则取消确认
    if (beforeConfirm && await beforeConfirm(tempValue.value))
      return;
    updateValue(tempValue.value);
    emit('confirm', value.value);
  }

  watch(value, (v) => {
    tempValue.value = v;
    selectText.value = requireFormat(v);
  });
  watch(tempValue, (v) => {
    emit('tempValueChange', tempValue.value);
    if (shouldUpdateValueImmediately)
      updateValue(tempValue.value);
  });

  // 如果提供了弹窗显示状态引用，则监听其变化
  if (popupShow) {
    watch(popupShow, (v) => {
      if (v) {
        beforeConfirmValue.value = tempValue.value;
      }
    });
  }

  onMounted(() => {
    if (value.value)
      selectText.value = requireFormat(value.value);
    else
      selectText.value = '';
  });

  return {
    onCancel,
    onConfirm,
    selectText,
    tempValue,
  }
}