<script setup>
import { Icon } from "@iconify/vue";
import { format as formatDate, isValid, parse as parseDate } from "date-fns";
import { computed, ref, watch } from "vue";
import { cn } from "../../../utils/cn";
import { InputGroupButton } from "../input-group";
defineOptions({ name: "UiDateRangePickerInput", inheritAttrs: false });
const props = defineProps({
  startValue: { type: Date, required: false },
  endValue: { type: Date, required: false },
  format: { type: String, required: true },
  startPlaceholder: { type: String, required: false },
  endPlaceholder: { type: String, required: false },
  rangeSeparatorIcon: { type: String, required: false },
  prefixIcon: { type: String, required: false },
  clearIcon: { type: String, required: false, default: "fluent:dismiss-20-regular" },
  clearable: { type: Boolean, required: false, default: true },
  disabled: { type: Boolean, required: false },
  readonly: { type: Boolean, required: false },
  open: { type: Boolean, required: false },
  size: { type: String, required: false, default: "md" },
  class: { type: [Boolean, null, String, Object, Array], required: false, skipCheck: true }
});
const sizeClass = computed(() => ({
  sm: "h-7 text-xs",
  md: "h-9 text-sm",
  lg: "h-10 text-base"
})[props.size]);
const emits = defineEmits(["update:startValue", "update:endValue", "focus", "blur", "clear"]);
const startDraft = ref("");
const endDraft = ref("");
const focusedSide = ref(null);
function syncStart() {
  startDraft.value = props.startValue ? formatDate(props.startValue, props.format) : "";
}
function syncEnd() {
  endDraft.value = props.endValue ? formatDate(props.endValue, props.format) : "";
}
watch(
  () => [props.startValue, props.format],
  () => {
    if (focusedSide.value !== "start") syncStart();
  },
  { immediate: true }
);
watch(
  () => [props.endValue, props.format],
  () => {
    if (focusedSide.value !== "end") syncEnd();
  },
  { immediate: true }
);
function commit(side) {
  const draft = side === "start" ? startDraft : endDraft;
  const current = side === "start" ? props.startValue : props.endValue;
  const sync = side === "start" ? syncStart : syncEnd;
  const text = draft.value.trim();
  if (!text) {
    if (current !== void 0) {
      if (side === "start") emits("update:startValue", void 0);
      else emits("update:endValue", void 0);
    }
    return;
  }
  const parsed = parseDate(text, props.format, current ?? /* @__PURE__ */ new Date());
  if (!isValid(parsed)) {
    sync();
    return;
  }
  if (side === "start") emits("update:startValue", parsed);
  else emits("update:endValue", parsed);
}
function onFocus(event, side) {
  focusedSide.value = side;
  emits("focus", event, side);
}
function onBlur(event, side) {
  focusedSide.value = null;
  commit(side);
  emits("blur", event, side);
}
function onClear() {
  startDraft.value = "";
  endDraft.value = "";
  emits("update:startValue", void 0);
  emits("update:endValue", void 0);
  emits("clear");
}
const showClear = computed(
  () => props.clearable && !props.disabled && !props.readonly && (props.startValue !== void 0 || props.endValue !== void 0)
);
const hasValue = computed(() => props.startValue !== void 0 || props.endValue !== void 0);
</script>

<template>
  <div
    v-bind="$attrs"
    data-slot="date-range-picker-input"
    :data-disabled="props.disabled ? 'true' : void 0"
    :data-value="hasValue ? 'true' : void 0"
    :data-state="props.open ? 'open' : void 0"
    :class="cn(
  'group/date-range-input',
  'border-zinc-200 relative flex w-full min-w-0 items-center rounded-md border bg-transparent transition-[color,box-shadow] outline-none',
  'data-[disabled=true]:bg-zinc-100',
  'has-[input:focus-visible]:border-(--primary)',
  'hover:border-zinc-300',
  sizeClass,
  props.class
)"
  >
    <Icon
      v-if="props.prefixIcon"
      :icon="props.prefixIcon"
      class="text-zinc-500 ml-3 mr-1 size-4 shrink-0"
    />
    <input
      v-model="startDraft"
      data-slot="input-group-control"
      data-side="start"
      :placeholder="props.startPlaceholder"
      :disabled="props.disabled"
      :readonly="props.readonly"
      :class="cn(
  'text-zinc-700 placeholder:text-zinc-300 min-w-0 flex-1 bg-transparent px-1 text-sm outline-none disabled:cursor-not-allowed text-center',
  !props.prefixIcon && 'pl-3'
)"
      @focus="(e) => onFocus(e, 'start')"
      @blur="(e) => onBlur(e, 'start')"
      @keydown.enter.prevent="commit('start')"
    >
    <Icon
      v-if="props.rangeSeparatorIcon"
      :icon="props.rangeSeparatorIcon"
      data-slot="date-range-picker-input-separator"
      class="text-zinc-400 mx-1 size-3.5 shrink-0"
    />
    <input
      v-model="endDraft"
      data-slot="input-group-control"
      data-side="end"
      :placeholder="props.endPlaceholder"
      :disabled="props.disabled"
      :readonly="props.readonly"
      :class="cn(
  'text-zinc-700 placeholder:text-zinc-300 min-w-0 flex-1 bg-transparent px-1 text-sm outline-none disabled:cursor-not-allowed text-center',
  !showClear && 'pr-3'
)"
      @focus="(e) => onFocus(e, 'end')"
      @blur="(e) => onBlur(e, 'end')"
      @keydown.enter.prevent="commit('end')"
    >
    <InputGroupButton
      v-if="showClear"
      size="icon-xs"
      data-slot="date-range-picker-clear"
      tabindex="-1"
      :class="cn(
  'mr-2 shrink-0 text-zinc-500 hover:text-zinc-700 transition-opacity',
  '[@media(hover:hover)]:opacity-0',
  'group-hover/date-range-input:opacity-100 focus-within:opacity-100'
)"
      @mousedown.prevent
      @click.stop="onClear"
    >
      <Icon :icon="props.clearIcon" />
    </InputGroupButton>
  </div>
</template>
