import { api } from '@/core/services/api'
import type { PaginatedApiResponse } from '@/core/types/api'
import type {
  Feedback,
  FeedbackApiResponse,
  FeedbackListItem,
  FeedbackStatistics,
  ListFeedbackParams,
  SubmitFeedbackPayload,
  UpdateFeedbackPayload,
} from '../types/feedback.types'

function appendIfPresent(formData: FormData, key: string, value: string | undefined | null) {
  if (value !== null && value !== undefined && value !== '') {
    formData.append(key, value)
  }
}

export function buildFeedbackFormData(payload: SubmitFeedbackPayload): FormData {
  const formData = new FormData()

  formData.append('type', payload.type)
  formData.append('title', payload.title)
  formData.append('description', payload.description)
  formData.append('priority', payload.priority)

  appendIfPresent(formData, 'page_url', payload.page_url)
  appendIfPresent(formData, 'steps_to_reproduce', payload.steps_to_reproduce)
  appendIfPresent(formData, 'expected_behavior', payload.expected_behavior)
  appendIfPresent(formData, 'actual_behavior', payload.actual_behavior)
  appendIfPresent(formData, 'additional_notes', payload.additional_notes)
  appendIfPresent(formData, 'screen_resolution', payload.screen_resolution)
  appendIfPresent(formData, 'viewport_size', payload.viewport_size)
  appendIfPresent(formData, 'timezone', payload.timezone)

  payload.images?.forEach((file, index) => {
    formData.append(`images[${index}]`, file)
  })

  payload.videos?.forEach((file, index) => {
    formData.append(`videos[${index}]`, file)
  })

  return formData
}

/** Public + authenticated: POST /v1/feedback (auth cookie attaches user when present). */
export async function submitFeedback(payload: SubmitFeedbackPayload): Promise<FeedbackApiResponse> {
  const formData = buildFeedbackFormData(payload)

  const { data } = await api.post<FeedbackApiResponse>('/v1/feedback', formData, {
    headers: {
      'Content-Type': 'multipart/form-data',
    },
  })

  if (!data.success) {
    throw new Error(data.message ?? 'Gagal menghantar maklum balas.')
  }

  return data
}

export async function listFeedback(
  params: ListFeedbackParams = {},
): Promise<PaginatedApiResponse<FeedbackListItem>> {
  const { data } = await api.get<PaginatedApiResponse<FeedbackListItem>>('/v1/feedback', {
    params,
  })

  if (!data.success) {
    throw new Error(data.message ?? 'Gagal memuatkan senarai maklum balas.')
  }

  return data
}

export async function getFeedback(id: string): Promise<Feedback> {
  const { data } = await api.get<FeedbackApiResponse>(`/v1/feedback/${id}`)

  if (!data.success) {
    throw new Error(data.message ?? 'Gagal memuatkan maklum balas.')
  }

  return data.data
}

export async function updateFeedback(
  id: string,
  payload: UpdateFeedbackPayload,
): Promise<FeedbackApiResponse> {
  const { data } = await api.patch<FeedbackApiResponse>(`/v1/feedback/${id}`, payload)

  if (!data.success) {
    throw new Error(data.message ?? 'Gagal mengemas kini maklum balas.')
  }

  return data
}

export async function deleteFeedback(id: string): Promise<void> {
  const { data } = await api.delete<{ success: boolean; message?: string }>(`/v1/feedback/${id}`)

  if (!data.success) {
    throw new Error(data.message ?? 'Gagal memadam maklum balas.')
  }
}

export async function getMyFeedback(
  params: ListFeedbackParams = {},
): Promise<PaginatedApiResponse<FeedbackListItem>> {
  const { data } = await api.get<{
    success: boolean
    data: FeedbackListItem[]
    meta: {
      current_page: number
      last_page: number
      per_page: number
      total: number
    }
    message?: string
  }>('/v1/my-feedback', { params })

  if (!data.success) {
    throw new Error(data.message ?? 'Gagal memuatkan maklum balas anda.')
  }

  return {
    success: true,
    data: data.data,
    pagination: {
      current_page: data.meta.current_page,
      per_page: data.meta.per_page,
      total: data.meta.total,
      last_page: data.meta.last_page,
      from: null,
      to: null,
      has_more_pages: data.meta.current_page < data.meta.last_page,
    },
  }
}

export async function getFeedbackStatistics(): Promise<FeedbackStatistics> {
  const { data } = await api.get<{ success: boolean; data: FeedbackStatistics; message?: string }>(
    '/v1/feedback-statistics',
  )

  if (!data.success) {
    throw new Error(data.message ?? 'Gagal memuatkan statistik maklum balas.')
  }

  return data.data
}

export async function fetchFeedbackDocument(
  feedbackId: string,
  documentId: string,
  mimeType?: string | null,
): Promise<Blob> {
  const response = await api.get(`/v1/feedback/${feedbackId}/documents/${documentId}/download`, {
    responseType: 'blob',
  })

  const contentType =
    mimeType ||
    (typeof response.headers['content-type'] === 'string' ? response.headers['content-type'] : null) ||
    'application/octet-stream'

  return new Blob([response.data], { type: contentType })
}
