<script setup lang="ts">
import type { HTMLAttributes } from "vue";
import { computed, ref, watch } from "vue";
import { useEventListener, useMediaQuery } from "@vueuse/core";
import { TooltipProvider } from "reka-ui";
import { cn } from "@/lib/utils";
import {
  SIDEBAR_KEYBOARD_SHORTCUT,
  SIDEBAR_WIDTH,
  SIDEBAR_WIDTH_ICON,
  provideSidebarContext,
} from "./utils";

// NOTE: Boolean props default to `false` in Vue when absent (not `undefined`).
// Use withDefaults to ensure defaultOpen=true when not passed by parent.
const props = withDefaults(
  defineProps<{
    defaultOpen?: boolean;
    open?: boolean;
    class?: HTMLAttributes["class"];
  }>(),
  { defaultOpen: true },
);

const emits = defineEmits<{ "update:open": [open: boolean] }>();

const isMobile = useMediaQuery("(max-width: 768px)");
const openMobile = ref(false);

const open = ref(props.defaultOpen);

// Support controlled mode (AdminLayout doesn't use this, but the API stays intact)
watch(
  () => props.open,
  (v) => {
    if (v !== undefined) open.value = v;
  },
);

function setOpen(value: boolean) {
  open.value = value;
  emits("update:open", value);
}

function setOpenMobile(value: boolean) {
  openMobile.value = value;
}

function toggleSidebar() {
  return isMobile.value
    ? setOpenMobile(!openMobile.value)
    : setOpen(!open.value);
}

useEventListener("keydown", (event: KeyboardEvent) => {
  if (
    event.key === SIDEBAR_KEYBOARD_SHORTCUT &&
    (event.metaKey || event.ctrlKey)
  ) {
    event.preventDefault();
    toggleSidebar();
  }
});

const state = computed(() => (open.value ? "expanded" : "collapsed"));

provideSidebarContext({
  state,
  open,
  setOpen,
  isMobile,
  openMobile,
  setOpenMobile,
  toggleSidebar,
});
</script>

<template>
  <TooltipProvider :delay-duration="0">
    <div
      data-slot="sidebar-wrapper"
      v-bind="$attrs"
      :style="{
        '--sidebar-width': SIDEBAR_WIDTH,
        '--sidebar-width-icon': SIDEBAR_WIDTH_ICON,
      }"
      :class="
        cn(
          'group/sidebar-wrapper has-data-[variant=inset]:bg-sidebar flex min-h-svh w-full',
          props.class,
        )
      "
    >
      <slot />
    </div>
  </TooltipProvider>
</template>
