import apiClient from './client'
import type {
  AttachmentResponse,
  MessageListResponse,
  MessageResponse,
} from '@/types/api.types'

export interface MessageFilters {
  page?: number
  page_size?: number
  /** Filtra per Virtual Box assegnata all'utente corrente */
  vbox_id?: string
  mailbox_id?: string
  direction?: 'inbound' | 'outbound'
  state?: string
  pec_type?: string
  is_read?: boolean
  is_starred?: boolean
  is_archived?: boolean
  is_trashed?: boolean
  /** Filtra per messaggi in attesa di conservazione (cartella Da Conservare) */
  is_pending_conservation?: boolean
  /** Filtra per messaggi gia' conservati (cartella Storico) */
  is_conserved?: boolean
  search?: string
  /** Data minima nel formato ISO 8601 (es. "2026-01-01T00:00:00Z") */
  date_from?: string
  /** Data massima nel formato ISO 8601 */
  date_to?: string
}

export interface MessageBulkUpdatePayload {
  ids: string[]
  is_read?: boolean
  is_starred?: boolean
  is_archived?: boolean
  is_trashed?: boolean
  is_pending_conservation?: boolean
  is_conserved?: boolean
}

export interface MessageUpdatePayload {
  is_read?: boolean
  is_starred?: boolean
  is_archived?: boolean
  is_trashed?: boolean
  is_pending_conservation?: boolean
  is_conserved?: boolean
  /** Rischio e Riservatezza (N3) — stringa vuota per resettare a null */
  risk_level?: string
  confidentiality?: string
}

export interface MessageBulkUpdateResponse {
  updated: number
  items: MessageResponse[]
}

export const messagesApi = {
  list: (filters: MessageFilters = {}) =>
    apiClient
      .get<MessageListResponse>('/messages', { params: filters })
      .then((r) => r.data),

  get: (id: string) =>
    apiClient.get<MessageResponse>(`/messages/${id}`).then((r) => r.data),

  markRead: (id: string) =>
    apiClient.patch<MessageResponse>(`/messages/${id}`, { is_read: true }).then((r) => r.data),

  markUnread: (id: string) =>
    apiClient.patch<MessageResponse>(`/messages/${id}`, { is_read: false }).then((r) => r.data),

  toggleStar: (id: string, starred: boolean) =>
    apiClient
      .patch<MessageResponse>(`/messages/${id}`, { is_starred: starred })
      .then((r) => r.data),

  archive: (id: string) =>
    apiClient
      .patch<MessageResponse>(`/messages/${id}`, { is_archived: true })
      .then((r) => r.data),

  unarchive: (id: string) =>
    apiClient
      .patch<MessageResponse>(`/messages/${id}`, { is_archived: false })
      .then((r) => r.data),

  trash: (id: string) =>
    apiClient
      .patch<MessageResponse>(`/messages/${id}`, { is_trashed: true })
      .then((r) => r.data),

  untrash: (id: string) =>
    apiClient
      .patch<MessageResponse>(`/messages/${id}`, { is_trashed: false })
      .then((r) => r.data),

  /** Sposta un messaggio nella cartella Da Conservare */
  conserve: (id: string) =>
    apiClient
      .patch<MessageResponse>(`/messages/${id}`, { is_pending_conservation: true })
      .then((r) => r.data),

  /** Rimuove un messaggio dalla cartella Da Conservare */
  unconserve: (id: string) =>
    apiClient
      .patch<MessageResponse>(`/messages/${id}`, { is_pending_conservation: false })
      .then((r) => r.data),

  /** Aggiorna uno o piu' campi del messaggio (PATCH generico) — include risk_level/confidentiality (N3) */
  update: (id: string, payload: MessageUpdatePayload) =>
    apiClient
      .patch<MessageResponse>(`/messages/${id}`, payload)
      .then((r) => r.data),

  /** Aggiorna in blocco is_starred e/o is_archived e/o is_trashed su più messaggi */
  bulkUpdate: (payload: MessageBulkUpdatePayload) =>
    apiClient
      .patch<MessageBulkUpdateResponse>('/messages/bulk', payload)
      .then((r) => r.data),

  getAttachments: (id: string) =>
    apiClient.get<AttachmentResponse[]>(`/messages/${id}/attachments`).then((r) => r.data),

  /**
   * Scarica un allegato autenticato e lo salva localmente.
   * Utilizza apiClient (con Bearer token) per evitare il 401 che si ottiene
   * navigando direttamente verso l'URL con un <a href>.
   */
  downloadAttachment: async (messageId: string, attachmentId: string, filename: string): Promise<void> => {
    const response = await apiClient.get(
      `/messages/${messageId}/attachments/${attachmentId}/download`,
      { responseType: 'blob' },
    )
    const blobUrl = window.URL.createObjectURL(new Blob([response.data]))
    const anchor = document.createElement('a')
    anchor.href = blobUrl
    anchor.setAttribute('download', filename)
    document.body.appendChild(anchor)
    anchor.click()
    anchor.remove()
    window.URL.revokeObjectURL(blobUrl)
  },

  getReceipts: (id: string) =>
    apiClient.get<MessageResponse[]>(`/messages/${id}/receipts`).then((r) => r.data),

  // ─── Feature 3: Thread ────────────────────────────────────────────────────

  getThread: (id: string) =>
    apiClient.get<MessageResponse[]>(`/messages/${id}/thread`).then((r) => r.data),

  // ─── Feature 7: Preview allegati ─────────────────────────────────────────

  getAttachmentPreviewUrl: (messageId: string, attachmentId: string) =>
    apiClient.get<{
      previewable: boolean
      content_type: string
      filename: string
      url?: string
    }>(`/messages/${messageId}/attachments/${attachmentId}/preview-url`).then((r) => r.data),

  // ─── Feature 8: Stampa ────────────────────────────────────────────────────

  /** Apre la vista di stampa HTML in una nuova tab. */
  openPrint: (messageId: string, token: string) => {
    const baseUrl = (window as any).__API_BASE_URL__ || '/api/v1'
    window.open(`${baseUrl}/messages/${messageId}/print?token=${token}`, '_blank')
  },

  /**
   * Scarica il pacchetto ZIP completo della PEC (postacert.eml, daticert.xml,
   * ricevute di accettazione/consegna per le mail outbound).
   */
  downloadPackage: async (messageId: string, subject?: string | null): Promise<void> => {
    const response = await apiClient.get(
      `/messages/${messageId}/download-package`,
      { responseType: 'blob' },
    )
    const blobUrl = window.URL.createObjectURL(new Blob([response.data], { type: 'application/zip' }))
    const anchor = document.createElement('a')
    anchor.href = blobUrl
    const safeSubject = (subject || 'pec').replace(/[/\\]/g, '_').slice(0, 50)
    anchor.setAttribute('download', `pec_${safeSubject}.zip`)
    document.body.appendChild(anchor)
    anchor.click()
    anchor.remove()
    window.URL.revokeObjectURL(blobUrl)
  },
}
