<script setup>
import { CalendarDate, CalendarDateTime, getLocalTimeZone, Time, today } from "@internationalized/date";
import { Icon } from "@iconify/vue";
import { TimeField } from "reka-ui/namespaced";
import { computed } from "vue";
import { cn } from "../../../utils/cn";
import { RangeCalendar } from "../range-calendar";
defineOptions({ name: "UiDateRangePickerDateTimePanel" });
const props = defineProps({
  modelValue: { type: Object, required: false },
  isDateDisabled: { type: Function, required: false },
  granularity: { type: String, required: false, default: "second" },
  hourCycle: { type: Number, required: false, default: 24 },
  numberOfMonths: { type: Number, required: false, default: 2 },
  rangeSeparatorIcon: { type: String, required: false, default: "lucide:arrow-right" },
  class: { type: [Boolean, null, String, Object, Array], required: false, skipCheck: true }
});
const emits = defineEmits(["update:modelValue"]);
function toDate(value) {
  if (!value) return void 0;
  return new CalendarDate(value.year, value.month, "day" in value ? value.day : 1);
}
function toTime(value) {
  if (!value || !("hour" in value)) return void 0;
  return new Time(value.hour, value.minute, value.second);
}
const dateRange = computed(() => ({
  start: toDate(props.modelValue?.start),
  end: toDate(props.modelValue?.end)
}));
const startTime = computed(() => toTime(props.modelValue?.start));
const endTime = computed(() => toTime(props.modelValue?.end));
function mergeDateTime(date, time) {
  if (!date) return void 0;
  return new CalendarDateTime(
    date.year,
    date.month,
    "day" in date ? date.day : 1,
    time?.hour ?? 0,
    time?.minute ?? 0,
    time?.second ?? 0
  );
}
function setDateRange(value) {
  if (!value) {
    emits("update:modelValue", void 0);
    return;
  }
  emits("update:modelValue", {
    start: mergeDateTime(value.start, startTime.value),
    end: mergeDateTime(value.end, endTime.value)
  });
}
function setStartTime(value) {
  const time = value ?? void 0;
  const start = props.modelValue?.start ?? toDate(today(getLocalTimeZone()));
  if (!start) return;
  emits("update:modelValue", {
    start: mergeDateTime(start, time),
    end: props.modelValue?.end
  });
}
function setEndTime(value) {
  const time = value ?? void 0;
  const end = props.modelValue?.end ?? toDate(today(getLocalTimeZone()));
  if (!end) return;
  emits("update:modelValue", {
    start: props.modelValue?.start,
    end: mergeDateTime(end, time)
  });
}
</script>

<template>
  <div
    data-slot="date-range-picker-datetime-panel"
    :class="cn('flex flex-col', props.class)"
  >
    <RangeCalendar
      :model-value="dateRange"
      :default-placeholder="dateRange.start"
      :is-date-disabled="props.isDateDisabled"
      :number-of-months="props.numberOfMonths"
      @update:model-value="setDateRange"
    />
    <div class="border-zinc-200 flex items-center gap-2 border-t p-3">
      <Icon
        icon="lucide:clock"
        class="text-zinc-500 size-4 shrink-0"
      />
      <TimeField.Root
        v-slot="{ segments }"
        :model-value="startTime"
        :granularity="props.granularity"
        :hour-cycle="props.hourCycle"
        class="text-zinc-700 flex flex-1 items-center justify-center gap-1.5 px-4 text-sm outline-none"
        @update:model-value="setStartTime"
      >
        <template v-if="Array.isArray(segments)">
          <template
            v-for="(segment, index) in segments"
            :key="`s-${segment.part}-${index}`"
          >
            <TimeField.Input
              v-if="segment.part !== 'literal'"
              :part="segment.part"
              class="rounded-sm px-1 outline-none focus:bg-zinc-100 data-[placeholder]:text-zinc-400"
            >
              {{ segment.value }}
            </TimeField.Input>
            <span
              v-else
              class="text-zinc-400 select-none"
            >{{ segment.value }}</span>
          </template>
        </template>
      </TimeField.Root>
      <Icon
        :icon="props.rangeSeparatorIcon"
        class="text-zinc-400 size-3.5 shrink-0"
      />
      <TimeField.Root
        v-slot="{ segments }"
        :model-value="endTime"
        :granularity="props.granularity"
        :hour-cycle="props.hourCycle"
        class="text-zinc-700 flex flex-1 items-center justify-center gap-1.5 px-4 text-sm outline-none"
        @update:model-value="setEndTime"
      >
        <template v-if="Array.isArray(segments)">
          <template
            v-for="(segment, index) in segments"
            :key="`e-${segment.part}-${index}`"
          >
            <TimeField.Input
              v-if="segment.part !== 'literal'"
              :part="segment.part"
              class="rounded-sm px-1 outline-none focus:bg-zinc-100 data-[placeholder]:text-zinc-400"
            >
              {{ segment.value }}
            </TimeField.Input>
            <span
              v-else
              class="text-zinc-400 select-none"
            >{{ segment.value }}</span>
          </template>
        </template>
      </TimeField.Root>
    </div>
  </div>
</template>
