<script setup lang="ts">
import { computed, onMounted, onUnmounted, ref } from 'vue'
import { getApiErrorMessage } from '@/services/api'
import { notificationService, type AppNotification, type BusinessAlert, type NotificationPayload } from '@/modules/notification/services/notificationService'
import { useCompanyContextStore } from '@/stores/companyContext'

const payload = ref<NotificationPayload>({
  summary: {
    unread_notifications: 0,
    active_alerts: 0,
    total: 0,
  },
  notifications: [],
  alerts: [],
})
const loading = ref(false)
const saving = ref(false)
const error = ref('')
const success = ref('')
const lastUpdatedAt = ref('')
const autoRefresh = ref(true)
const notificationFilter = ref<'all' | 'unread' | 'read'>('all')
const currentCompanyId = ref(localStorage.getItem('current_company_id') || '')
const companyContext = useCompanyContextStore()
const canManageNotifications = computed(() => companyContext.hasPermission('notification.manage'))
let refreshTimer: number | undefined
const form = ref({
  type: 'info',
  title: '',
  message: '',
  action_url: '',
})

const visibleNotifications = computed(() => {
  if (notificationFilter.value === 'unread') {
    return payload.value.notifications.filter((notification) => !notification.read_at)
  }

  if (notificationFilter.value === 'read') {
    return payload.value.notifications.filter((notification) => notification.read_at)
  }

  return payload.value.notifications
})

const unreadNotifications = computed(() => payload.value.notifications.filter((notification) => !notification.read_at))
const readNotifications = computed(() => payload.value.notifications.filter((notification) => notification.read_at))
const attentionLevel = computed(() => {
  if (payload.value.summary.total === 0) {
    return 'Clear'
  }

  if (payload.value.summary.active_alerts > 0) {
    return 'Action needed'
  }

  return 'Review'
})

async function load(silent = false) {
  if (!currentCompanyId.value) {
    error.value = 'Select a company workspace first.'
    return
  }

  if (!silent) {
    loading.value = true
    error.value = ''
  }

  try {
    payload.value = await notificationService.all()
    lastUpdatedAt.value = new Date().toLocaleTimeString([], {
      hour: '2-digit',
      minute: '2-digit',
      second: '2-digit',
    })
  } catch (loadError) {
    if (!silent) {
      error.value = getApiErrorMessage(loadError, 'Unable to load notifications.')
    }
  } finally {
    if (!silent) {
      loading.value = false
    }
  }
}

async function createNotification() {
  saving.value = true
  error.value = ''
  success.value = ''

  try {
    await notificationService.create({
      type: form.value.type,
      title: form.value.title,
      message: form.value.message || undefined,
      action_url: form.value.action_url || undefined,
    })
    form.value = {
      type: 'info',
      title: '',
      message: '',
      action_url: '',
    }
    success.value = 'Notification created.'
    await load()
  } catch (createError) {
    error.value = getApiErrorMessage(createError, 'Unable to create notification.')
  } finally {
    saving.value = false
  }
}

async function markRead(notification: AppNotification) {
  error.value = ''

  try {
    await notificationService.markRead(notification)
    await load(true)
  } catch (markError) {
    error.value = getApiErrorMessage(markError, 'Unable to mark notification as read.')
  }
}

async function markAllRead() {
  error.value = ''
  success.value = ''

  try {
    await notificationService.markAllRead()
    success.value = 'All notifications marked as read.'
    await load(true)
  } catch (markAllError) {
    error.value = getApiErrorMessage(markAllError, 'Unable to mark all notifications as read.')
  }
}

function typeLabel(item: AppNotification | BusinessAlert) {
  return item.type.charAt(0).toUpperCase() + item.type.slice(1)
}

function typeClass(item: AppNotification | BusinessAlert) {
  return {
    off: item.type === 'info' || item.type === 'success',
    warn: item.type === 'warning',
    danger: item.type === 'danger',
  }
}

function startPolling() {
  window.clearInterval(refreshTimer)
  refreshTimer = window.setInterval(() => {
    if (autoRefresh.value && currentCompanyId.value) {
      void load(true)
    }
  }, 30000)
}

onMounted(async () => {
  await companyContext.loadCurrent()
  await load()
  startPolling()
})

onUnmounted(() => {
  window.clearInterval(refreshTimer)
})
</script>

<template>
  <section class="stack">
    <article class="panel">
      <div class="report-toolbar">
        <div>
          <h2>Notifications</h2>
          <p class="muted">{{ attentionLevel }} - last updated {{ lastUpdatedAt || 'not yet' }}</p>
          <p v-if="loading" class="muted">Loading notifications...</p>
          <p v-if="error" class="error">{{ error }}</p>
          <p v-if="success" class="success">{{ success }}</p>
        </div>
        <div class="inline-actions">
          <label class="inline-check">
            <input v-model="autoRefresh" type="checkbox" />
            Auto refresh
          </label>
          <button class="button ghost" type="button" :disabled="loading" @click="load()">Refresh</button>
          <button class="button ghost" type="button" :disabled="loading || payload.summary.unread_notifications === 0" @click="markAllRead">
            Mark All Read
          </button>
        </div>
      </div>
    </article>

    <section class="grid compact-grid">
      <article class="metric">
        <span>Total Attention</span>
        <strong>{{ payload.summary.total }}</strong>
        <small>{{ attentionLevel }}</small>
      </article>
      <article class="metric">
        <span>Unread</span>
        <strong>{{ payload.summary.unread_notifications }}</strong>
        <small>{{ readNotifications.length }} read</small>
      </article>
      <article class="metric">
        <span>Live Alerts</span>
        <strong>{{ payload.summary.active_alerts }}</strong>
        <small>{{ unreadNotifications.length }} saved unread</small>
      </article>
    </section>

    <section class="grid wide-grid">
      <article class="panel stack">
        <h2>Live Business Alerts</h2>
        <div v-for="alert in payload.alerts" :key="alert.id" class="list-item">
          <div>
            <strong>{{ alert.title }}</strong>
            <span>{{ alert.category }}</span>
            <span>{{ alert.message }}</span>
          </div>
          <div class="inline-actions">
            <span class="status-pill" :class="typeClass(alert)">{{ typeLabel(alert) }}</span>
            <RouterLink class="button ghost" :to="alert.action_url">Open</RouterLink>
          </div>
        </div>
        <p v-if="payload.alerts.length === 0 && !loading">No live alerts.</p>
      </article>

      <article v-if="canManageNotifications" class="panel">
        <h2>Create Notification</h2>
        <form class="form" @submit.prevent="createNotification">
          <div class="field">
            <label for="notification_type">Type</label>
            <select id="notification_type" v-model="form.type">
              <option value="info">Info</option>
              <option value="success">Success</option>
              <option value="warning">Warning</option>
              <option value="danger">Danger</option>
            </select>
          </div>
          <div class="field">
            <label for="notification_title">Title</label>
            <input id="notification_title" v-model="form.title" type="text" required />
          </div>
          <div class="field">
            <label for="notification_message">Message</label>
            <textarea id="notification_message" v-model="form.message" rows="3"></textarea>
          </div>
          <div class="field">
            <label for="notification_url">Action URL</label>
            <input id="notification_url" v-model="form.action_url" type="text" placeholder="/reports" />
          </div>
          <button class="button primary" type="submit" :disabled="saving || !currentCompanyId">Create</button>
        </form>
      </article>
    </section>

    <article class="panel stack">
      <div class="portal-section-header">
        <h2>Saved Notifications</h2>
        <select v-model="notificationFilter">
          <option value="all">All</option>
          <option value="unread">Unread</option>
          <option value="read">Read</option>
        </select>
      </div>
      <div
        v-for="notification in visibleNotifications"
        :key="notification.id"
        class="list-item"
        :class="{ unread: !notification.read_at }"
      >
        <div>
          <strong>{{ notification.title }}</strong>
          <span>{{ notification.created_at || 'No date' }}</span>
          <span>{{ notification.message || 'No message' }}</span>
        </div>
        <div class="inline-actions">
          <span class="status-pill" :class="typeClass(notification)">{{ typeLabel(notification) }}</span>
          <span class="status-pill" :class="{ off: notification.read_at }">{{ notification.read_at ? 'Read' : 'Unread' }}</span>
          <RouterLink v-if="notification.action_url" class="button ghost" :to="notification.action_url">Open</RouterLink>
          <button v-if="!notification.read_at" class="button ghost" type="button" @click="markRead(notification)">Read</button>
        </div>
      </div>
      <p v-if="visibleNotifications.length === 0 && !loading">No saved notifications.</p>
    </article>
  </section>
</template>
