import client from "./client"

export interface NotificationItem {
  id: number
  category: string
  level: "info" | "success" | "warning" | "error" | "urgent" | string
  sender_id?: number | null
  sender_name?: string
  sender_type?: string
  source_label?: string
  title: string
  content: string
  link: string | null
  action_label?: string | null
  action_url?: string | null
  action?: { label: string; url: string } | null
  is_read: boolean
  read_at: string | null
  handled_at?: string | null
  archived_at?: string | null
  created_at: string | null
}

export interface AnnouncementItem {
  id: number
  title: string
  content: string
  category: string
  sender_name?: string
  sender_type?: string
  source_label?: string
  is_read: boolean
  published_at: string | null
  created_at: string | null
}

export interface UnreadCount {
  notifications: number
  announcements: number
  total: number
}

export interface NotificationPreference {
  category: string
  in_app_enabled: boolean
  email_enabled: boolean
  sms_enabled: boolean
}

export interface ListResult<T> {
  items: T[]
  total: number
}

function listResult<T>(value: unknown): ListResult<T> {
  const data = value as { items?: unknown; total?: unknown } | null | undefined
  return {
    items: Array.isArray(data?.items) ? data.items as T[] : [],
    total: Number(data?.total ?? 0) || 0,
  }
}

export async function getUnreadCount() {
  const res = await client.get("/v1/notifications/unread-count")
  const data = res.data.data as Partial<UnreadCount> | null | undefined
  return {
    notifications: Number(data?.notifications ?? 0) || 0,
    announcements: Number(data?.announcements ?? 0) || 0,
    total: Number(data?.total ?? 0) || 0,
  }
}

export async function listNotifications(params: {
  category?: string
  level?: string
  unread_only?: boolean
  important_only?: boolean
  archived_only?: boolean
  handled_state?: "handled" | "unhandled"
  limit?: number
  offset?: number
} = {}) {
  const res = await client.get("/v1/notifications", { params })
  return listResult<NotificationItem>(res.data.data)
}

export async function markNotificationRead(id: number) {
  const res = await client.post(`/v1/notifications/${id}/read`)
  return res.data.data as { ok: boolean }
}

export async function markAllNotificationsRead() {
  const res = await client.post("/v1/notifications/read-all")
  return res.data.data as { count: number }
}

export async function batchMarkNotificationsRead(ids: number[]) {
  const res = await client.post("/v1/notifications/batch/read", { ids })
  return res.data.data as { count: number }
}

export async function batchDeleteNotifications(ids: number[]) {
  const res = await client.post("/v1/notifications/batch/delete", { ids })
  return res.data.data as { count: number }
}

export async function batchArchiveNotifications(ids: number[], archived: boolean) {
  const res = await client.post("/v1/notifications/batch/archive", { ids, archived })
  return res.data.data as { count: number }
}

export async function batchHandleNotifications(ids: number[], handled: boolean) {
  const res = await client.post("/v1/notifications/batch/handled", { ids, handled })
  return res.data.data as { count: number }
}

export async function deleteNotification(id: number) {
  const res = await client.delete(`/v1/notifications/${id}`)
  return res.data.data as { ok: boolean }
}

export async function getNotificationPreferences() {
  const res = await client.get("/v1/notifications/preferences")
  return Array.isArray(res.data.data) ? res.data.data as NotificationPreference[] : []
}

export async function updateNotificationPreferences(preferences: NotificationPreference[]) {
  const res = await client.put("/v1/notifications/preferences", { preferences })
  return Array.isArray(res.data.data) ? res.data.data as NotificationPreference[] : []
}

export async function listAnnouncements(params: { limit?: number; offset?: number } = {}) {
  const res = await client.get("/v1/notifications/announcements", { params })
  return listResult<AnnouncementItem>(res.data.data)
}

export async function markAnnouncementRead(id: number) {
  const res = await client.post(`/v1/notifications/announcements/${id}/read`)
  return res.data.data as { ok: boolean }
}
