<template>
  <div class="page-header">
    <h1>Notifications</h1>
    <div class="actions">
      <router-link to="/settings/notificationtypes" class="btn btn-secondary">Manage Types</router-link>
      <router-link to="/notifications/new" class="btn btn-primary">New Notification</router-link>
    </div>
  </div>

  <div class="filters">
    <input
      v-model="searchQuery"
      type="text"
      class="form-control"
      placeholder="Search notifications..."
      @input="debouncedSearch"
    />
    <select v-model="selectedType" class="form-control" @change="applyFilter">
      <option value="">All Types</option>
      <option v-for="type in types" :key="type.notificationtypeid" :value="type.notificationtypeid">
        {{ type.typename }}
      </option>
    </select>
    <select v-model="currentFilter" class="form-control" @change="applyFilter">
      <option value="">All</option>
      <option value="current">Current Only</option>
      <option value="pinned">Pinned Only</option>
    </select>
  </div>

  <div class="card">
    <div v-if="loading" class="loading">Loading...</div>
    <div v-else-if="notifications.length === 0" class="empty">
      No notifications found.
    </div>
    <div v-else class="table-container">
      <table>
        <thead>
          <tr>
            <th>Title</th>
            <th>Type</th>
            <th>Start Date</th>
            <th>End Date</th>
            <th>Status</th>
            <th>Actions</th>
          </tr>
        </thead>
        <tbody>
          <tr v-for="notification in notifications" :key="notification.notificationid">
            <td>
              <router-link :to="`/notifications/${notification.notificationid}/edit`">
                {{ notification.title }}
              </router-link>
              <span v-if="notification.ispinned" class="badge badge-primary" title="Pinned">Pinned</span>
            </td>
            <td>
              <span class="badge" :style="{ backgroundColor: notification.typecolor }">
                {{ notification.typename }}
              </span>
            </td>
            <td>{{ formatDate(notification.startdate) }}</td>
            <td>{{ notification.enddate ? formatDate(notification.enddate) : 'No end' }}</td>
            <td>
              <span :class="['badge', notification.iscurrent ? 'badge-success' : 'badge-secondary']">
                {{ notification.iscurrent ? 'Active' : 'Inactive' }}
              </span>
            </td>
            <td class="actions">
              <router-link :to="`/notifications/${notification.notificationid}/edit`" class="btn btn-small">
                Edit
              </router-link>
            </td>
          </tr>
        </tbody>
      </table>
    </div>

    <!-- Pagination -->
    <PaginationBar
      :page="page"
      :totalPages="totalPages"
      :perPage="perPage"
      @update:page="goToPage"
      @update:perPage="changePerPage"
    />
  </div>
</template>

<script setup>
import { ref, onMounted } from 'vue'
import { notificationsApi, settingsApi } from '@/api'
import PaginationBar from '@/components/PaginationBar.vue'
import { useListQuery } from '@/composables/listQuery'
import { formatInZone, DEFAULT_TZ } from '@/utils/datetime'

const notifications = ref([])
const types = ref([])
const loading = ref(true)
const { page, search: searchQuery, setPage, setSearch } = useListQuery({ onChange: loadNotifications })
const selectedType = ref('')
const currentFilter = ref('')
const perPage = ref(20)
const total = ref(0)
const totalPages = ref(1)
const siteTimezone = ref(DEFAULT_TZ)

let searchTimeout = null

onMounted(async () => {
  try {
    const tzRes = await settingsApi.get('site_timezone')
    const tzValue = tzRes?.data?.data?.value
    if (tzValue) siteTimezone.value = tzValue
  } catch (e) { /* keep default tz */ }
  await loadTypes()
  await loadNotifications()
})

async function loadTypes() {
  try {
    const response = await notificationsApi.types.list()
    types.value = response.data.data
  } catch (error) {
    console.error('Error loading types:', error)
  }
}

// A filter change must go back to page 1. Selecting a filter while on page 5
// asked the server for page 5 of a result set that now has one page, and the
// list came back empty as though the filter matched nothing.
//
// setPage(1) writes the URL, which the composable's watcher picks up and
// answers with onChange - so calling the loader as well would fetch twice.
// Load directly only when already on page 1, where nothing changes and the
// watcher stays silent.
function applyFilter() {
  if (page.value > 1) setPage(1)
  else loadNotifications()
}

async function loadNotifications() {
  loading.value = true
  try {
    const params = {
      page: page.value,
      perpage: perPage.value
    }

    if (searchQuery.value) {
      params.search = searchQuery.value
    }
    if (selectedType.value) {
      params.typeid = selectedType.value
    }
    if (currentFilter.value === 'current') {
      params.current = 'true'
    } else if (currentFilter.value === 'pinned') {
      params.pinned = 'true'
    }

    const response = await notificationsApi.list(params)
    notifications.value = response.data.data
    total.value = response.data.meta?.pagination?.total || notifications.value.length
    totalPages.value = Math.ceil(total.value / perPage.value)
  } catch (error) {
    console.error('Error loading notifications:', error)
  } finally {
    loading.value = false
  }
}

function debouncedSearch() {
  clearTimeout(searchTimeout)
  searchTimeout = setTimeout(() => {
    setSearch(searchQuery.value)
    loadNotifications()
  }, 300)
}

function goToPage(p) {
  setPage(p)
  loadNotifications()
}

function changePerPage(newPerPage) {
  perPage.value = newPerPage
  setPage(1)
  loadNotifications()
}

function formatDate(dateStr) {
  if (!dateStr) return ''
  // startdate/enddate are UTC; show the site-zone calendar date.
  return formatInZone(dateStr, siteTimezone.value, {
    year: 'numeric', month: 'numeric', day: 'numeric', hour: undefined, minute: undefined
  })
}
</script>
