<script>
import theme from "#build/b24ui/dashboard-sidebar";
</script>

<script setup>
import { ref, computed, toRef, useId, watch } from "vue";
import { defu } from "defu";
import { createReusableTemplate } from "@vueuse/core";
import { useAppConfig, useRuntimeHook, useRoute } from "#imports";
import { useComponentProps } from "../composables/useComponentProps";
import { useResizable } from "../composables/useResizable";
import { useLocale } from "../composables/useLocale";
import { useDashboard } from "../utils/dashboard";
import { tv } from "../utils/tv";
import B24DashboardResizeHandle from "./DashboardResizeHandle.vue";
import B24DashboardSidebarToggle from "./DashboardSidebarToggle.vue";
import B24Slideover from "./Slideover.vue";
import B24Modal from "./Modal.vue";
import B24Drawer from "./Drawer.vue";
defineOptions({ inheritAttrs: false });
const _props = defineProps({
  mode: { type: null, required: false, default: "slideover" },
  menu: { type: null, required: false },
  toggle: { type: [Boolean, Object], required: false, default: true },
  toggleSide: { type: String, required: false, default: "left" },
  autoClose: { type: Boolean, required: false, default: true },
  class: { type: null, required: false },
  b24ui: { type: Object, required: false },
  id: { type: String, required: false },
  side: { type: String, required: false, default: "left" },
  minSize: { type: Number, required: false, default: 200 },
  maxSize: { type: Number, required: false, default: 250 },
  defaultSize: { type: Number, required: false, default: 240 },
  resizable: { type: Boolean, required: false, default: false },
  collapsible: { type: Boolean, required: false, default: false },
  collapsedSize: { type: Number, required: false, default: 66 }
});
const slots = defineSlots();
const props = useComponentProps("dashboardSidebar", _props);
const open = defineModel("open", { type: Boolean, ...{ default: false } });
const collapsed = defineModel("collapsed", { type: Boolean, ...{ default: false } });
const route = useRoute();
const { t } = useLocale();
const appConfig = useAppConfig();
const dashboardContext = useDashboard({
  storageKey: "dashboard",
  unit: "px",
  sidebarOpen: ref(false),
  sidebarCollapsed: ref(false)
});
const id = `${dashboardContext.storageKey}-sidebar-${props.id || useId()}`;
const { el, size, collapse, isCollapsed, isDragging, onMouseDown, onTouchStart, onDoubleClick } = useResizable(id, toRef(() => ({ ...dashboardContext, ...props })), { collapsed });
const [DefineToggleTemplate, ReuseToggleTemplate] = createReusableTemplate();
const [DefineResizeHandleTemplate, ReuseResizeHandleTemplate] = createReusableTemplate();
useRuntimeHook("dashboard:sidebar:toggle", () => {
  open.value = !open.value;
});
useRuntimeHook("dashboard:sidebar:collapse", (value) => {
  isCollapsed.value = value;
});
watch(open, () => dashboardContext.sidebarOpen.value = open.value, { immediate: true });
watch(isCollapsed, () => dashboardContext.sidebarCollapsed.value = isCollapsed.value, { immediate: true });
watch(() => route.fullPath, () => {
  if (!props.autoClose) return;
  open.value = false;
});
const b24ui = computed(() => tv({ extend: tv(theme), ...appConfig.b24ui?.dashboardSidebar || {} })({
  side: props.side
}));
const Menu = computed(() => ({
  slideover: B24Slideover,
  modal: B24Modal,
  drawer: B24Drawer
})[props.mode]);
const menuProps = toRef(() => {
  const modeSettings = props.mode === "modal" ? { fullscreen: true, transition: false } : props.mode === "slideover" ? { side: "left", close: false } : {};
  if (props.mode === "modal") {
    modeSettings["b24ui"] = { content: "p-0 pt-0" };
  }
  const result = defu(
    props.menu,
    modeSettings
  );
  result["b24ui"] = {
    overlay: b24ui.value.overlay({ class: props.b24ui?.overlay }),
    content: b24ui.value.content({
      class: [modeSettings?.b24ui?.content, props.b24ui?.content]
    })
  };
  return result;
});
function toggleOpen() {
  open.value = !open.value;
}
</script>

<template>
  <DefineToggleTemplate>
    <slot name="toggle" :open="open" :toggle="toggleOpen" :b24ui="b24ui">
      <B24DashboardSidebarToggle
        v-if="props.toggle"
        v-bind="typeof props.toggle === 'object' ? props.toggle : {}"
        :side="props.toggleSide"
        data-slot="toggle"
        :class="b24ui.toggle({ class: props.b24ui?.toggle, toggleSide: props.toggleSide })"
      />
    </slot>
  </DefineToggleTemplate>

  <DefineResizeHandleTemplate>
    <slot name="resize-handle" :on-mouse-down="onMouseDown" :on-touch-start="onTouchStart" :on-double-click="onDoubleClick" :b24ui="b24ui">
      <B24DashboardResizeHandle
        v-if="props.resizable"
        :aria-controls="id"
        data-slot="handle"
        :class="b24ui.handle({ class: props.b24ui?.handle })"
        @mousedown="onMouseDown"
        @touchstart="onTouchStart"
        @dblclick="onDoubleClick"
      />
    </slot>
  </DefineResizeHandleTemplate>

  <ReuseResizeHandleTemplate v-if="props.side === 'right'" />

  <div
    :id="id"
    ref="el"
    v-bind="$attrs"
    :data-collapsed="isCollapsed"
    :data-dragging="isDragging"
    data-slot="root"
    :class="b24ui.root({ class: [props.b24ui?.root, props.class] })"
    :style="{ '--width': `${size || 0}${dashboardContext.unit}` }"
  >
    <div v-if="!!slots.header" data-slot="header" :class="b24ui.header({ class: props.b24ui?.header })">
      <slot name="header" :collapsed="isCollapsed" :collapse="collapse" />
    </div>

    <div data-slot="body" :class="b24ui.body({ class: props.b24ui?.body })">
      <slot :collapsed="isCollapsed" :collapse="collapse" />
    </div>

    <div v-if="!!slots.footer" data-slot="footer" :class="b24ui.footer({ class: props.b24ui?.footer })">
      <slot name="footer" :collapsed="isCollapsed" :collapse="collapse" />
    </div>
  </div>

  <ReuseResizeHandleTemplate v-if="props.side === 'left'" />

  <Menu
    v-model:open="open"
    :title="t('dashboardSidebar.title')"
    :description="t('dashboardSidebar.description')"
    v-bind="menuProps"
  >
    <template #content="contentData">
      <slot name="content" v-bind="contentData">
        <div v-if="!!slots.header || props.mode !== 'drawer'" data-slot="header" :class="b24ui.header({ class: props.b24ui?.header, menu: true })">
          <ReuseToggleTemplate v-if="props.mode !== 'drawer' && props.toggleSide === 'left'" />

          <slot name="header" :collapsed="false" :collapse="() => {
}" />

          <ReuseToggleTemplate v-if="props.mode !== 'drawer' && props.toggleSide === 'right'" />
        </div>

        <div data-slot="body" :class="b24ui.body({ class: props.b24ui?.body, menu: true })">
          <slot :collapsed="false" :collapse="() => {
}" />
        </div>

        <div v-if="!!slots.footer" data-slot="footer" :class="b24ui.footer({ class: props.b24ui?.footer, menu: true })">
          <slot name="footer" :collapsed="false" :collapse="() => {
}" />
        </div>
      </slot>
    </template>
  </Menu>
</template>
