<template>
  <!-- 根據路由設定 meta.layout 動態切換佈局 -->
  <component
    :is="activeLayout"
    v-bind="layoutProps"
    v-model:breadcrumb-bar-visible="favoritesStore.breadcrumbBarVisible"
    v-model:favorites-bar-visible="favoritesStore.favoritesBarVisible"
    v-model:is-rail="menuStore.isRail"
    @action="handleLayoutAction"
    @logout="handleLogout"
    @remove-favorite="handleRemoveFavorite"
    @search="handleSearch"
    @select="handleSelect"
  >
    <template #breadcrumb-actions>
      <v-btn
        color="secondary"
        :disabled="isFavoriteActionDisabled"
        size="small"
        variant="outlined"
        @click="toggleFavorite"
      >
        <v-icon class="mr-1" size="14" :icon="favoriteActionIcon" />
        {{ favoriteActionLabel }}
      </v-btn>
      <v-btn class="ml-2" color="primary" size="small" variant="text" @click="goHome">
        <v-icon class="mr-1" size="14" :icon="mdiHome" />
        返回首頁
      </v-btn>
    </template>
    <!-- 如果是預設佈局，顯示分頁標籤 -->
    <template v-if="showTabs">
      <div class="d-flex flex-column h-100">
        <v-tabs
          v-model="activeTab"
          bg-color="background"
          color="primary"
          density="compact"
          show-arrows
          style="flex-shrink: 0"
        >
          <v-tab v-for="tab in tabs" :key="tab.path" border="sm" :to="tab.path" :value="tab.path">
            {{ tab.title }}
            <v-btn
              aria-label="關閉頁籤"
              class="pl-2"
              color="grey"
              density="compact"
              :disabled="tabs.length <= 1"
              icon
              size="x-small"
              variant="text"
              @click.prevent.stop="closeTab(tab.path)"
            >
              <v-icon :icon="mdiClose" />
            </v-btn>
          </v-tab>
        </v-tabs>

        <div class="flex-grow-1 overflow-auto" style="min-height: 0" tabindex="0">
          <router-view v-slot="{ Component }">
            <keep-alive>
              <component :is="Component" :key="route.fullPath" />
            </keep-alive>
          </router-view>
        </div>
      </div>
    </template>

    <!-- 其他佈局直接顯示內容 -->
    <router-view v-else />
  </component>

  <v-dialog v-model="searchDialog" max-width="640">
    <v-card>
      <v-card-title class="text-h6 bg-primary-variant pa-4">搜尋結果</v-card-title>
      <v-card-subtitle v-if="searchKeyword" class="pt-4"
        >關鍵字：{{ searchKeyword }}</v-card-subtitle
      >
      <v-card-text class="pt-2">
        <v-alert
          v-if="searchResults.length === 0"
          class="mt-2"
          density="compact"
          type="info"
          variant="tonal"
        >
          查無結果
        </v-alert>
        <v-list v-else density="compact">
          <v-list-item
            v-for="item in searchResults"
            :key="item.path"
            class="mb-2"
            @click="handleSearchSelect(item)"
          >
            <template #prepend>
              <v-icon v-if="item.icon" size="18" :icon="item.icon" />
            </template>
            <v-list-item-title>{{ item.title }}</v-list-item-title>
            <v-list-item-subtitle v-if="item.parents?.length">
              {{ item.parents.join(' / ') }}
            </v-list-item-subtitle>
          </v-list-item>
        </v-list>
      </v-card-text>
      <v-card-actions>
        <v-spacer />
        <v-btn color="primary" variant="text" @click="searchDialog = false">關閉</v-btn>
      </v-card-actions>
    </v-card>
  </v-dialog>

  <!--
    訊息中心 Dialog：
    放在 App.vue 的原因是要被「首頁卡片」與「頂部工具列訊息按鈕」共同觸發，
    並且避免在 layout/template 層放入業務 UI，維持模板的純展示特性。
  -->
  <v-dialog v-model="messageStore.isOpen" max-width="720">
    <v-card>
      <v-card-title class="text-h6 bg-primary-variant pa-4">訊息清單</v-card-title>
      <v-card-subtitle class="text-body-2 pt-4 text-medium-emphasis"
        >僅示意資料，不含延伸功能</v-card-subtitle
      >
      <v-card-text class="pa-4">
        <!--
          使用 v-data-iterator 進行資料展示，
          這樣若未來要加排序或分頁，不需改動結構。
        -->
        <v-data-iterator item-key="id" :items="messageItems" :items-per-page="-1">
          <template #default="{ items }">
            <v-list density="compact">
              <v-list-item
                v-for="wrapped in items"
                :key="resolveMessageItem(wrapped).id"
                border="sm"
                class="pa-2 mb-1"
              >
                <template #prepend>
                  <v-avatar color="primary" size="28" variant="tonal">
                    <v-icon size="16" :icon="resolveMessageItem(wrapped).icon" />
                  </v-avatar>
                </template>
                <v-list-item-title class="text-body-2 font-weight-medium">
                  {{ resolveMessageItem(wrapped).title }}
                </v-list-item-title>
                <v-list-item-subtitle class="text-caption text-medium-emphasis">
                  {{ resolveMessageItem(wrapped).meta }}
                </v-list-item-subtitle>
              </v-list-item>
            </v-list>
          </template>
        </v-data-iterator>
      </v-card-text>
      <v-card-actions class="justify-end">
        <v-btn color="primary" variant="text" @click="messageStore.close()">關閉</v-btn>
      </v-card-actions>
    </v-card>
  </v-dialog>

  <v-snackbar
    v-model="snackbar.visible"
    :color="snackbar.color"
    :location="snackbar.location"
    :timeout="snackbar.timeout"
    :variant="snackbar.variant"
  >
    {{ snackbar.message }}
  </v-snackbar>
</template>

<script setup>
import {
  mdiBellOutline,
  mdiCalendarOutline,
  mdiClose,
  mdiCloseCircle,
  mdiCog,
  mdiFileDocumentOutline,
  mdiFileTreeOutline,
  mdiHome,
  mdiHomeCityOutline,
  mdiPlusCircle,
  mdiSchoolOutline,
  mdiTableEdit,
} from '@mdi/js'
import { computed, onBeforeUnmount, onMounted, ref, watch } from 'vue'
import { useRoute, useRouter } from 'vue-router'
import MainLayout from '@/components/layouts/MainLayout.vue'
import PlainLayout from '@/components/layouts/PlainLayout.vue'
import { HTTP_TOAST_EVENT } from './services/http-toast'
import { SESSION_FORCE_LOGOUT_EVENT } from './services/session'
import { useAuthStore } from './stores/auth'
import { useBreadcrumbStore } from './stores/breadcrumbs'
import { useFavoritesStore } from './stores/favorites'
import { useMenuStore } from './stores/menu'
import { useMessageStore } from './stores/messages'
import { useSnackbarStore } from './stores/snackbar'

const route = useRoute()
const router = useRouter()
const snackbar = useSnackbarStore()
const authStore = useAuthStore()
const menuStore = useMenuStore()
const breadcrumbStore = useBreadcrumbStore()
const favoritesStore = useFavoritesStore()
// 訊息中心：集中控制 dialog 顯示狀態
const messageStore = useMessageStore()

// 固定選單（合併到 API 回傳的選單）
const _fixedMenuItems = [
  {
    title: '資料維護',
    navigable: false,
    subItems: [
      { title: '單筆資料維護', icon: mdiFileDocumentOutline, path: '/single-record-maintenance' },
      { title: '主從資料維護A', icon: mdiFileTreeOutline, path: '/master-detail-maintenance' },
      { title: '主從資料維護B', icon: mdiFileTreeOutline, path: '/master-detail-maintenance-b' },
      { title: '主從資料維護C', icon: mdiFileTreeOutline, path: '/master-detail-maintenance-c' },
      { title: '可編輯表格維護', icon: mdiTableEdit, path: '/editable-grid-maintenance' },
    ],
  },
  { title: '登入頁', path: '/login' },
]

// 範例選單（用於 tab 顯示名稱的保底資料）
const _menuItemsExample = [
  { title: '首頁', icon: mdiHome, path: '/' },
  {
    title: '設定',
    icon: mdiCog,
    path: '/settings',
    navigable: false,
  },
  ..._fixedMenuItems,
]

/**
 * 佈局對映表
 */
const layoutMap = {
  default: MainLayout,
  none: PlainLayout,
}

// 取得當前應使用的組件
const activeLayout = computed(() => {
  return layoutMap[route.meta.layout] || MainLayout
})

function buildMergedMenuItems(items) {
  const flatPaths = new Set()
  const collectPaths = (list) => {
    for (const item of list || []) {
      if (item?.path) flatPaths.add(item.path)
      if (item?.subItems?.length) collectPaths(item.subItems)
    }
  }

  collectPaths(items)

  const mergeFixedItems = (list) => {
    return (list || []).map((item) => {
      if (!item?.subItems?.length) return item
      const subItems = item.subItems.filter((sub) => !sub?.path || !flatPaths.has(sub.path))
      return { ...item, subItems }
    })
  }

  const fixedItems = mergeFixedItems(_fixedMenuItems).filter((item) => {
    if (!item?.subItems?.length) return !item?.path || !flatPaths.has(item.path)
    return item.subItems.length > 0
  })

  return [...(items || []), ...fixedItems]
}

// 根據不同 Layout 傳遞不同的 Props
const mergedMenuItems = computed(() => buildMergedMenuItems(menuStore.menuItems))

const mergedFavoriteItems = computed(() => {
  const combined = [...menuStore.favoriteItems, ...favoritesStore.layoutItems]
  const seen = new Set()
  return combined.filter((item) => {
    const key = item.path ?? item.title
    if (!key) return false
    if (seen.has(key)) return false
    seen.add(key)
    return true
  })
})

const layoutProps = computed(() => {
  const layout = route.meta.layout
  if (layout === 'default') {
    return {
      systemTitle: '測試環境',
      favoriteItems: mergedFavoriteItems.value,
      menuItems: mergedMenuItems.value,
      breadcrumbItems: breadcrumbStore.breadcrumbItems,
    }
  }
  return {}
})

function handleSelect(item) {
  console.log('Selected:', item)
  if (item.path) {
    router.push(item.path)
  }
}

const searchDialog = ref(false)
const searchKeyword = ref('')
const searchResults = ref([])

function buildSearchResults(items, keyword, parents = []) {
  const results = []
  for (const item of items || []) {
    const currentParents = item?.title ? [...parents, item.title] : parents
    if (item?.subItems?.length) {
      results.push(...buildSearchResults(item.subItems, keyword, currentParents))
    }
    if (item?.path && item?.title) {
      const hit = item.title.toLowerCase().includes(keyword)
      if (hit) {
        results.push({
          title: item.title,
          path: item.path,
          icon: item.icon,
          parents: parents,
        })
      }
    }
  }
  return results
}

// 接收 Layout 的搜尋事件：僅在「按鈕或 Enter」時觸發
function handleSearch(value) {
  const keyword = String(value ?? '').trim()
  searchKeyword.value = keyword
  if (!keyword) {
    // 空字串時不顯示結果彈窗
    searchResults.value = []
    searchDialog.value = false
    return
  }
  const lowered = keyword.toLowerCase()
  // 依合併後的 menuItems 進行比對
  searchResults.value = buildSearchResults(mergedMenuItems.value, lowered)
  // 開啟彈窗顯示搜尋結果
  searchDialog.value = true
}

// 點擊搜尋結果後導頁（行為等同選單點擊）
function handleSearchSelect(item) {
  searchDialog.value = false
  handleSelect(item)
}

// 訊息中心的示意資料，僅用於展示列表，不進行 API 呼叫
const messageItems = [
  { id: 1, title: '系統維護提醒', meta: '今天 09:00 · 資訊中心', icon: mdiBellOutline },
  { id: 2, title: '教務處公告', meta: '昨天 16:20 · 教務處', icon: mdiSchoolOutline },
  { id: 3, title: '宿舍申請結果', meta: '昨天 13:05 · 學務處', icon: mdiHomeCityOutline },
  { id: 4, title: '課表異動通知', meta: '2 天前 · 教務處', icon: mdiCalendarOutline },
]

// v-data-iterator 會包裝 items，這裡取回原始資料物件
function resolveMessageItem(wrapped) {
  if (wrapped && typeof wrapped === 'object' && 'raw' in wrapped) {
    return wrapped.raw
  }
  return wrapped
}

// 由 layout 的 action 事件統一進入此處處理
// 目前只處理訊息中心，其他 action 可在此擴充
function handleLayoutAction(type) {
  if (type === 'messages') {
    messageStore.open()
    return
  }
}

function performLogout({ message, color }) {
  authStore.logout()
  tabs.value = []
  activeTab.value = null
  snackbar.show({ message, color })
  router.replace({ name: 'login' })
}

function handleLogout() {
  performLogout({ message: '登出成功', color: 'success' })
}

function handleForceLogout(event) {
  const message = event?.detail?.message || '請重新登入'
  performLogout({ message, color: 'warning' })
}

function handleHttpToast(event) {
  const detail = event?.detail
  const message = detail?.message
  if (!message) return

  const level = detail?.level
  const color = level === 'error' ? 'error' : level === 'warning' ? 'warning' : 'info'
  snackbar.show({ message, color, timeout: 3000, location: 'top right', variant: 'flat' })
}

onMounted(() => {
  window.addEventListener(SESSION_FORCE_LOGOUT_EVENT, handleForceLogout)
  window.addEventListener(HTTP_TOAST_EVENT, handleHttpToast)
})

onBeforeUnmount(() => {
  window.removeEventListener(SESSION_FORCE_LOGOUT_EVENT, handleForceLogout)
  window.removeEventListener(HTTP_TOAST_EVENT, handleHttpToast)
})

// --- Tabs Logic ---

const tabs = ref([])
const activeTab = ref(null)

const showTabs = computed(() => {
  return route.meta.layout === 'default'
})

// 遞迴尋找標題
function findTitle(path) {
  const recursiveFind = (items) => {
    for (const item of items) {
      if (item.path === path) return item.title
      if (item.subItems?.length) {
        const found = recursiveFind(item.subItems)
        if (found) return found
      }
    }
    return null
  }

  // 1. 搜尋 Store 中的選單
  let title = recursiveFind(menuStore.menuItems)
  if (title) return title

  // 2. 搜尋最愛選單
  title = recursiveFind(menuStore.favoriteItems)
  if (title) return title

  // 3. 搜尋靜態範例選單
  title = recursiveFind(_menuItemsExample)
  if (title) return title

  // 4. 特殊路徑處理
  if (path === '/') return '首頁'

  return path
}

function findMenuItem(path) {
  const recursiveFind = (items) => {
    for (const item of items) {
      if (item.path === path) return item
      if (item.subItems?.length) {
        const found = recursiveFind(item.subItems)
        if (found) return found
      }
    }
    return null
  }

  return recursiveFind(mergedMenuItems.value)
}

const currentFavoriteInfo = computed(() => {
  const path = route.path
  const menuItem = findMenuItem(path)
  const title =
    menuItem?.title ||
    (typeof route.meta?.title === 'string' ? route.meta.title : null) ||
    findTitle(path)
  return {
    title,
    path,
    icon: menuItem?.icon,
  }
})

const isCurrentFavorite = computed(() => favoritesStore.isFavorite(route.path))
const isFavoriteActionDisabled = computed(
  () => !currentFavoriteInfo.value?.path || route.path === '/'
)

const favoriteActionLabel = computed(() => (isCurrentFavorite.value ? '移除常用' : '加入常用'))
const favoriteActionIcon = computed(() =>
  isCurrentFavorite.value ? mdiCloseCircle : mdiPlusCircle
)

function toggleFavoriteItem(item) {
  if (!item?.path || item.path === '/') return
  favoritesStore.toggle({
    title: item.title || findTitle(item.path),
    path: item.path,
    icon: item.icon,
  })
}

function toggleFavorite() {
  toggleFavoriteItem(currentFavoriteInfo.value)
}

function handleRemoveFavorite(item) {
  toggleFavoriteItem(item)
}

function goHome() {
  router.push('/')
}

function updateBreadcrumbs() {
  const resolvedTitle = findTitle(route.path)
  const fallbackTitle =
    resolvedTitle && resolvedTitle !== route.path
      ? resolvedTitle
      : typeof route.meta?.title === 'string'
        ? route.meta.title
        : null

  breadcrumbStore.setBreadcrumbs({
    path: route.path,
    menuItems: mergedMenuItems.value,
    favoriteItems: mergedFavoriteItems.value,
    fallbackTitle,
    homeLabel: '首頁',
    homeIcon: mdiHome,
  })
}

watch(
  [
    () => route.path,
    () => menuStore.menuItems,
    () => menuStore.favoriteItems,
    () => favoritesStore.items,
  ],
  () => updateBreadcrumbs(),
  { immediate: true, deep: true }
)

// 監聽路由變化，新增 Tab
watch(
  () => route.path,
  (newPath) => {
    if (!showTabs.value) return

    const existingTab = tabs.value.find((t) => t.path === newPath)
    if (!existingTab) {
      const title = findTitle(newPath)
      tabs.value.push({ title, path: newPath })
    }
    activeTab.value = newPath
  },
  { immediate: true }
)

function closeTab(path) {
  if (tabs.value.length <= 1) return

  const index = tabs.value.findIndex((t) => t.path === path)
  if (index === -1) return

  tabs.value.splice(index, 1)

  // 如果關閉的是當前分頁，則跳轉到其他分頁
  if (route.path === path) {
    const nextTab = tabs.value[index] || tabs.value[index - 1]
    if (nextTab) {
      router.push(nextTab.path)
    } else {
      // 若無剩餘分頁，回到首頁
      router.push('/')
    }
  }
}
</script>
