<template>
  <v-card class="w-100 h-100 d-flex flex-column bg-transparent pa-2 pa-lg-4" elevation="3">
    <v-card-title class="text-h6 text-lg-h5 font-weight-bold text-accent mb-4">{{
      title
    }}</v-card-title>

    <v-tabs v-model="activeTab" class="mb-3" color="primary" density="comfortable">
      <v-tab v-for="tab in normalizedTabs" :key="tab.value" :value="tab.value">
        {{ tab.label }}
      </v-tab>
    </v-tabs>

    <div class="announcement-content mb-3">
      <v-table v-if="!isSystemTab" density="comfortable" fixed-header height="300">
        <thead>
          <tr>
            <th class="text-left">{{ dateHeader }}</th>
            <th class="text-left">{{ schoolHeader }}</th>
            <th class="text-left">{{ titleHeader }}</th>
          </tr>
        </thead>
        <tbody>
          <tr v-for="item in pageItems" :key="item.id">
            <td class="text-no-wrap">{{ item.date }}</td>
            <td class="text-no-wrap">{{ item.school }}</td>
            <td>
              <v-btn
                class="px-0 text-none justify-start"
                color="primary"
                variant="text"
                @click="emit('select-announcement', item)"
              >
                {{ item.title }}
              </v-btn>
            </td>
          </tr>
          <tr v-if="pageItems.length === 0">
            <td class="text-center text-medium-emphasis py-6" :colspan="3">{{ emptyText }}</td>
          </tr>
        </tbody>
      </v-table>

      <v-list v-else class="rounded border overflow-y-auto h-100" density="comfortable" lines="two">
        <v-list-item v-for="item in systemPageItems" :key="item.id" border="b">
          <v-list-item-title class="text-h6 mb-2">
            {{ item.content }}
          </v-list-item-title>
          <v-list-item-subtitle v-if="item.title || item.createdAt">
            {{ item.title }}<span v-if="item.title && item.createdAt"> ・ </span
            >{{ item.createdAt }}
          </v-list-item-subtitle>
        </v-list-item>
        <v-list-item v-if="systemPageItems.length === 0" class="h-100">
          <v-list-item-title class="text-center text-medium-emphasis">{{
            emptyText
          }}</v-list-item-title>
        </v-list-item>
      </v-list>
    </div>

    <div class="d-flex justify-space-between align-center mt-auto pt-3">
      <span class="text-caption text-medium-emphasis">
        {{ paginationLabel }} {{ totalItems }}
      </span>
      <v-pagination v-model="page" density="comfortable" :length="pageCount" rounded="circle" />
    </div>
  </v-card>
</template>

<script setup lang="ts">
import { computed, ref, watch } from 'vue'

interface AnnouncementTab {
  label: string
  value: string
}

interface AnnouncementItem {
  id: string | number
  date: string
  school: string
  title: string
  tab?: string
}

interface SystemAnnouncementItem {
  id: string | number
  content: string
  title?: string
  createdAt?: string
}

interface Props {
  title?: string
  tabs?: AnnouncementTab[]
  items?: AnnouncementItem[]
  systemAnnouncements?: SystemAnnouncementItem[]
  allTabLabel?: string
  itemsPerPage?: number
  dateHeader?: string
  schoolHeader?: string
  titleHeader?: string
  emptyText?: string
  paginationLabel?: string
}

const props = withDefaults(defineProps<Props>(), {
  title: '學校甄選簡章公告區',
  tabs: () => [{ label: '全部', value: '__all__' }],
  items: () => [],
  systemAnnouncements: () => [],
  allTabLabel: '全部',
  itemsPerPage: 5,
  dateHeader: '公告時間',
  schoolHeader: '公告學校',
  titleHeader: '公告標題',
  emptyText: '目前沒有公告資料',
  paginationLabel: '總筆數：',
})

const emit = defineEmits<{
  (event: 'select-announcement', item: AnnouncementItem): void
}>()

const allTabValue = '__all__'
const systemTabValue = '__system__'

const systemTab = computed<AnnouncementTab>(() => ({
  label: '系統公告',
  value: systemTabValue,
}))

const normalizedTabs = computed<AnnouncementTab[]>(() => {
  const baseTabs =
    props.tabs.length > 0 ? props.tabs : [{ label: props.allTabLabel, value: allTabValue }]
  if (baseTabs.some((tab) => tab.value === systemTabValue)) return baseTabs
  return [...baseTabs, systemTab.value]
})

const activeTab = ref(normalizedTabs.value[0]?.value ?? allTabValue)
const page = ref(1)
const isSystemTab = computed(() => activeTab.value === systemTabValue)

const filteredItems = computed(() => {
  if (activeTab.value === allTabValue) return props.items
  return props.items.filter((item) => item.tab === activeTab.value)
})

const totalItems = computed(() => {
  if (isSystemTab.value) return props.systemAnnouncements.length
  return filteredItems.value.length
})

const pageCount = computed(() => {
  const size = Math.max(1, props.itemsPerPage)
  return Math.max(1, Math.ceil(totalItems.value / size))
})

const pageItems = computed(() => {
  const size = Math.max(1, props.itemsPerPage)
  const start = (page.value - 1) * size
  return filteredItems.value.slice(start, start + size)
})

const systemPageItems = computed<SystemAnnouncementItem[]>(() => {
  const size = Math.max(1, props.itemsPerPage)
  const start = (page.value - 1) * size
  return props.systemAnnouncements.slice(start, start + size)
})

watch(
  normalizedTabs,
  (tabs) => {
    if (tabs.some((tab) => tab.value === activeTab.value)) return
    activeTab.value = tabs[0]?.value ?? allTabValue
  },
  { immediate: true }
)

watch(activeTab, () => {
  page.value = 1
})

watch(pageCount, (count) => {
  if (page.value <= count) return
  page.value = count
})
</script>

<style scoped>
.announcement-content {
  height: 300px;
}
</style>
