<script setup>
import { computed, ref, useAttrs } from "vue";
import { Button } from "@/Components/ui/button";
import { Calendar } from "@/Components/ui/calendar";
import { Popover, PopoverContent, PopoverTrigger } from "@/Components/ui/popover";
import { cn } from "@/lib/utils";
import { CalendarIcon } from "lucide-vue-next";
import { format } from "date-fns";
import { sl } from "date-fns/locale";
import { CalendarDate, parseDate } from "@internationalized/date";

defineOptions({ inheritAttrs: false });

const props = defineProps({
  modelValue: {
    type: [Date, String, null],
    default: null,
  },
  placeholder: {
    type: String,
    default: "Izberi datum",
  },
  format: {
    type: String,
    default: "dd.MM.yyyy",
  },
  disabled: {
    type: Boolean,
    default: false,
  },
  id: {
    type: String,
    default: undefined,
  },
  error: {
    type: [String, Array],
    default: undefined,
  },
});

const emit = defineEmits(["update:modelValue"]);

const attrs = useAttrs();
const forwardedAttrs = computed(() => {
  const { class: _class, id: _id, ...rest } = attrs;
  return rest;
});
const controlId = computed(() => attrs.id ?? props.id);

// Convert string/Date to CalendarDate
const toCalendarDate = (value) => {
  if (!value) return null;
  let dateObj;
  if (value instanceof Date) {
    dateObj = value;
  } else if (typeof value === "string") {
    // Handle YYYY-MM-DD format
    if (/^\d{4}-\d{2}-\d{2}$/.test(value)) {
      try {
        const [year, month, day] = value.split("-").map(Number);
        return new CalendarDate(year, month, day);
      } catch {
        dateObj = new Date(value);
      }
    } else {
      dateObj = new Date(value);
    }
  } else {
    return null;
  }

  if (dateObj && !isNaN(dateObj.getTime())) {
    return new CalendarDate(
      dateObj.getFullYear(),
      dateObj.getMonth() + 1,
      dateObj.getDate()
    );
  }
  return null;
};

// Convert CalendarDate to ISO string (YYYY-MM-DD)
const fromCalendarDate = (calendarDate) => {
  if (!calendarDate) return null;
  return `${String(calendarDate.year).padStart(4, "0")}-${String(
    calendarDate.month
  ).padStart(2, "0")}-${String(calendarDate.day).padStart(2, "0")}`;
};

const calendarDate = computed({
  get: () => toCalendarDate(props.modelValue),
  set: (value) => {
    const isoString = fromCalendarDate(value);
    emit("update:modelValue", isoString);
  },
});

// Format for display
const formattedDate = computed(() => {
  if (!calendarDate.value) return props.placeholder;
  try {
    const dateObj = new Date(
      calendarDate.value.year,
      calendarDate.value.month - 1,
      calendarDate.value.day
    );
    const formatMap = {
      "dd.MM.yyyy": "dd.MM.yyyy",
      "yyyy-MM-dd": "yyyy-MM-dd",
    };
    const dateFormat = formatMap[props.format] || "dd.MM.yyyy";
    return format(dateObj, dateFormat, { locale: sl });
  } catch {
    return props.placeholder;
  }
});

const open = ref(false);
</script>

<template>
  <Popover v-model:open="open">
    <PopoverTrigger as-child>
      <Button
        v-bind="forwardedAttrs"
        :id="controlId"
        variant="outline"
        :class="
          cn(
            'w-full justify-start text-left font-normal',
            !calendarDate && 'text-muted-foreground',
            error && 'border-red-500 focus:border-red-500 focus:ring-red-500',
            attrs.class
          )
        "
        :disabled="disabled"
      >
        <CalendarIcon class="mr-2 h-4 w-4" />
        {{ formattedDate }}
      </Button>
    </PopoverTrigger>
    <PopoverContent class="w-auto p-0" align="start">
      <Calendar locale="sl-SI" v-model="calendarDate" :disabled="disabled" />
    </PopoverContent>
  </Popover>
  <p v-if="error" class="mt-1 text-sm text-red-600">
    {{ Array.isArray(error) ? error[0] : error }}
  </p>
</template>
