<script setup lang="ts">
import {
  mdiBellOutline,
  mdiCalendarOutline,
  mdiHomeCityOutline,
  mdiSchoolOutline,
} from '@mdi/js'
import { onBeforeUnmount, onMounted, ref } from 'vue'
import { HTTP_TOAST_EVENT } from '@/services/http-toast'
import { useMessageStore } from '@/stores/messages'
import { useSnackbarStore } from '@/stores/snackbar'
import type { LayoutMenuItem } from '@/stores/menu'

const props = defineProps<{
  menuItems?: LayoutMenuItem[]
}>()

const emit = defineEmits<{
  (e: 'searchSelect', item: { title: string; path: string; icon?: string }): void
}>()

const snackbar = useSnackbarStore()
const messageStore = useMessageStore()

const searchDialog = ref(false)
const searchKeyword = ref('')
const searchResults = ref<
  Array<{ title: string; path: string; icon?: string; parents: string[] }>
>([])

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 },
]

function buildSearchResults(
  items: LayoutMenuItem[] | undefined,
  keyword: string,
  parents: string[] = []
): Array<{ title: string; path: string; icon?: string; parents: string[] }> {
  const results: Array<{ title: string; path: string; icon?: string; parents: string[] }> = []
  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,
        })
      }
    }
  }
  return results
}

function handleSearch(value: unknown) {
  const keyword = String(value ?? '').trim()
  searchKeyword.value = keyword
  if (!keyword) {
    searchResults.value = []
    searchDialog.value = false
    return
  }
  const lowered = keyword.toLowerCase()
  searchResults.value = buildSearchResults(props.menuItems, lowered)
  searchDialog.value = true
}

function handleSearchSelect(item: { title: string; path: string; icon?: string }) {
  searchDialog.value = false
  emit('searchSelect', item)
}

function resolveMessageItem(wrapped: unknown) {
  if (wrapped && typeof wrapped === 'object' && 'raw' in (wrapped as object)) {
    return (wrapped as { raw: (typeof messageItems)[0] }).raw
  }
  return wrapped as (typeof messageItems)[0]
}

function handleHttpToast(event: Event) {
  const detail = (event as CustomEvent)?.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(HTTP_TOAST_EVENT, handleHttpToast)
})

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

defineExpose({ handleSearch })
</script>

<template>
  <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>

  <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 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 as any"
    :timeout="snackbar.timeout"
    :variant="snackbar.variant"
  >
    {{ snackbar.message }}
  </v-snackbar>
</template>
