<template>
  <div class="tw:h-full tw:flex tw-items-stretchc" ref="appAppbarMenu">
    <template v-for="item in pageNavigation.appBarItems" :key="item.route">
      <v-tab
        :key="locale"
        v-if="item.slotType !== 'inline'"
        :disabled="activeRouteName === item.route || !item.route"
        :active="activeRouteName === item.route"
        :value="item.route || ''"
        color="primary"
        class="nav-link tw:h-full tw-flex tw-items-center tw-justify-center"
        link
        @click="navigate(item)"
        :prepend-icon="item.icon"
        :text="item.title"
      />
      <template v-else>
        <template v-if="item.icon || item.title">
          <v-tab
            class="tw:h-full tw-flex tw-items-stretch"
            :color="floatingWindow.visible ? 'primary' : 'none'"
            @click="openFloatingWindow(item)"
            ><v-icon>{{ item.icon || "mdi-window-restore" }}</v-icon
            >{{ item.title }}</v-tab
          >
        </template>
        <div v-else class="tw:h-full tw-flex tw-items-stretch">
          <WidgetsLayoutLoader
            v-if="compositions[item.compositionId]"
            :widgets-layout="compositions[item.compositionId].widgetsLayout"
            slot-type="inline"
            :slot-layout="compositions[item.compositionId].slotLayout"
            :max-height="availableComponentHeight"
          />
        </div>
      </template>
    </template>

    <!-- Floating Window -->
    <teleport to="body">
      <div
        v-if="floatingWindow.visible"
        :style="{
          position: 'fixed',
          left: floatingWindow.x + 'px',
          top: floatingWindow.y + 'px',
          zIndex: 9999,
          cursor: isDragging ? 'grabbing' : 'grab',
        }"
        @mousedown="startDrag"
        class="tw:select-none"
      >
        <v-card min-width="400" max-width="800" elevation="8">
          <v-card-title
            class="d-flex justify-space-between align-center bg-primary"
          >
            <span>{{ floatingWindow.item?.title || "Widget" }}</span>
            <v-btn
              icon="mdi-close"
              size="small"
              variant="text"
              @click.stop="closeFloatingWindow"
            ></v-btn>
          </v-card-title>
          <v-card-text class="pa-4">
            <WidgetsLayoutLoader
              v-if="
                floatingWindow.item &&
                compositions[floatingWindow.item.compositionId]
              "
              :max-height="800"
              :widgets-layout="
                compositions[floatingWindow.item.compositionId].widgetsLayout
              "
              slot-type="inline"
              :slot-layout="
                compositions[floatingWindow.item.compositionId].slotLayout
              "
            />
          </v-card-text>
        </v-card>
      </div>
    </teleport>
  </div>
</template>

<script setup lang="ts">
import { computed, useTemplateRef, reactive, ref } from "vue"
import { useRouter } from "vue-router"
import useRouteState from "@racletteOrchestrator/composables/useRouteState"
import usePageNavigation, {
  type NavigationItem,
} from "@racletteOrchestrator/composables/usePageNavigation"
import WidgetsLayoutLoader from "../composition/WidgetsLayoutLoader.vue"
import { DEFAULT_SLOT_NAME } from "@racletteOrchestrator/router/routeParserHelper"
import useStateSubscriber from "@racletteOrchestrator/composables/useStateSubscriber"

const appAppbarMenuRef = useTemplateRef("appAppbarMenu")
const availableComponentHeight = computed(
  () => appAppbarMenuRef?.value?.offsetHeight || 48,
)
const { state: pageNavigation } = usePageNavigation()
const { state: compositions } = useStateSubscriber("compositions")
const router = useRouter()
const { getCompositionLinkForSlotName } = useRouteState()
const currentPageRoute = getCompositionLinkForSlotName(DEFAULT_SLOT_NAME)

const activeRouteName = computed(() => {
  const currentRoute = router.currentRoute.value
  const pageCompositionLinkValue = currentPageRoute?.value?.slotValue

  if (currentRoute.name === "app.space.page") {
    return pageCompositionLinkValue || currentRoute.params.pageId
  }

  return pageCompositionLinkValue || currentRoute.name
})

// Floating window state
const floatingWindow = reactive({
  visible: false,
  x: 100,
  y: 100,
  item: null as NavigationItem | null,
})

const isDragging = ref(false)
const dragOffset = reactive({ x: 0, y: 0 })

const openFloatingWindow = (item: NavigationItem) => {
  if (floatingWindow.item) return closeFloatingWindow()
  floatingWindow.item = item
  floatingWindow.visible = true
  // Center the window on screen
  floatingWindow.x = (window.innerWidth - 400) / 2
  floatingWindow.y = (window.innerHeight - 300) / 2
}

const closeFloatingWindow = () => {
  floatingWindow.visible = false
  floatingWindow.item = null
}

const startDrag = (e: MouseEvent) => {
  // Don't drag if clicking on close button or other interactive elements
  if ((e.target as HTMLElement).closest(".v-btn")) {
    return
  }

  isDragging.value = true
  dragOffset.x = e.clientX - floatingWindow.x
  dragOffset.y = e.clientY - floatingWindow.y

  let rafPending = false
  let lastEvent: MouseEvent

  const onMouseMove = (e: MouseEvent) => {
    lastEvent = e
    if (!rafPending) {
      rafPending = true
      requestAnimationFrame(() => {
        rafPending = false
        if (isDragging.value) {
          floatingWindow.x = lastEvent.clientX - dragOffset.x
          floatingWindow.y = lastEvent.clientY - dragOffset.y
        }
      })
    }
  }

  const onMouseUp = () => {
    isDragging.value = false
    document.removeEventListener("mousemove", onMouseMove)
    document.removeEventListener("mouseup", onMouseUp)
  }

  document.addEventListener("mousemove", onMouseMove)
  document.addEventListener("mouseup", onMouseUp)
}

const navigate = (item: NavigationItem) => {
  item.navigateTo()
}
</script>
