import { toApiUrl } from './runtime'

function emitBackendStatus(detail) {
  if (typeof window === 'undefined') return
  window.dispatchEvent(new CustomEvent('tier-maker:backend-status', { detail }))
}

async function request(path, { method = 'GET', body, headers } = {}) {
  let res
  try {
    res = await fetch(toApiUrl(path), {
      method,
      credentials: 'include',
      headers: {
        ...(body ? { 'Content-Type': 'application/json' } : {}),
        ...(headers || {}),
      },
      body: body ? JSON.stringify(body) : undefined,
    })
  } catch (error) {
    emitBackendStatus({
      state: 'offline',
      message: '서버 연결을 확인할 수 없어 잠시 후 다시 시도해주세요.',
      path,
    })
    throw error
  }

  const contentType = res.headers.get('content-type') || ''
  const data = contentType.includes('application/json') ? await res.json() : await res.text()

  if (!res.ok) {
    if (res.status >= 500 && data?.error === 'db_init_failed') {
      emitBackendStatus({
        state: 'maintenance',
        message: '서비스 점검 중이거나 데이터베이스 초기화 중입니다. 잠시 후 다시 이용해주세요.',
        path,
      })
    } else if (res.status >= 500) {
      emitBackendStatus({
        state: 'maintenance',
        message: '서비스 내부 점검중입니다. 잠시 후 다시 이용해주세요.',
        path,
      })
    }
    const err = new Error('request_failed')
    err.status = res.status
    err.data = data
    throw err
  }
  emitBackendStatus({ state: 'online', path })
  return data
}

export const api = {
  me: () => request('/api/auth/me'),
  authMeta: () => request('/api/auth/meta'),
  signup: ({ email, nickname, password }) => request('/api/auth/signup', { method: 'POST', body: { email, nickname, password } }),
  login: ({ email, password }) => request('/api/auth/login', { method: 'POST', body: { email, password } }),
  verifyEmail: ({ token }) => request('/api/auth/email/verify', { method: 'POST', body: { token } }),
  resendVerificationEmail: ({ email }) => request('/api/auth/email/resend', { method: 'POST', body: { email } }),
  requestPasswordReset: ({ email }) => request('/api/auth/password-reset/request', { method: 'POST', body: { email } }),
  confirmPasswordReset: ({ token, password }) =>
    request('/api/auth/password-reset/confirm', { method: 'POST', body: { token, password } }),
  changePassword: ({ currentPassword, nextPassword }) =>
    request('/api/auth/password', { method: 'POST', body: { currentPassword, nextPassword } }),
  logout: () => request('/api/auth/logout', { method: 'POST' }),

  listTopics: () => request('/api/topics'),
  getTopic: (topicId) => request(`/api/topics/${encodeURIComponent(topicId)}`),
  favoriteTopic: (topicId) => request(`/api/topics/${encodeURIComponent(topicId)}/favorite`, { method: 'POST' }),
  unfavoriteTopic: (topicId) => request(`/api/topics/${encodeURIComponent(topicId)}/favorite`, { method: 'DELETE' }),
  updateAdminTemplateDisplayOrder: (payload) => request('/api/admin/templates/display-order', { method: 'PATCH', body: payload }),
  updateAdminTemplateItemDisplayOrder: (templateId, payload) =>
    request(`/api/admin/templates/${encodeURIComponent(templateId)}/items/display-order`, { method: 'PATCH', body: payload }),
  updateAdminTemplate: (templateId, payload) =>
    request(`/api/admin/templates/${encodeURIComponent(templateId)}`, { method: 'PATCH', body: payload }),
  updateAdminTemplateItem: (templateId, itemId, payload) =>
    request(`/api/admin/templates/${encodeURIComponent(templateId)}/items/${encodeURIComponent(itemId)}`, { method: 'PATCH', body: payload }),
  listAdminCustomItems: ({ q = '', page = 1, limit = 50, filter = 'all', collapseShared = false } = {}) =>
    request(
      `/api/admin/custom-items?q=${encodeURIComponent(q)}&page=${encodeURIComponent(page)}&limit=${encodeURIComponent(limit)}&filter=${encodeURIComponent(filter)}&collapseShared=${encodeURIComponent(collapseShared ? '1' : '0')}`
    ),
  listAdminTierLists: ({ q = '', topicId = '', sort = 'recent', minFavorites = 0, page = 1, limit = 50 } = {}) =>
    request(`/api/admin/tierlists?q=${encodeURIComponent(q)}&topicId=${encodeURIComponent(topicId)}&sort=${encodeURIComponent(sort)}&minFavorites=${encodeURIComponent(minFavorites)}&page=${encodeURIComponent(page)}&limit=${encodeURIComponent(limit)}`),
  getAdminTierListStats: ({ q = '', topicId = '', minFavorites = 0 } = {}) =>
    request(`/api/admin/tierlists/stats?q=${encodeURIComponent(q)}&topicId=${encodeURIComponent(topicId)}&minFavorites=${encodeURIComponent(minFavorites)}`),
  updateAdminTierList: (tierListId, payload) =>
    request(`/api/admin/tierlists/${encodeURIComponent(tierListId)}`, { method: 'PATCH', body: payload }),
  updateAdminTierListFeatured: (tierListId, payload) =>
    request(`/api/admin/tierlists/${encodeURIComponent(tierListId)}/featured`, { method: 'PATCH', body: payload }),
  deleteAdminTierList: (tierListId) =>
    request(`/api/admin/tierlists/${encodeURIComponent(tierListId)}`, { method: 'DELETE' }),
  listAdminTemplateRequests: () => request('/api/admin/template-requests'),
  getAdminImageAssetStats: ({ month = '', limit = 12 } = {}) => {
    const query = new URLSearchParams()
    if (month) query.set('month', month)
    query.set('limit', String(limit))
    return request(`/api/admin/image-assets/stats?${query.toString()}`)
  },
  resetAdminImageAssetStats: (payload) => request('/api/admin/image-assets/stats/reset', { method: 'POST', body: payload || {} }),
  cleanupAdminMissingImageReferences: () => request('/api/admin/image-assets/missing/cleanup', { method: 'POST', body: {} }),
  listAdminUnusedImageAssets: ({ limit = 100, minAgeHours = 24 } = {}) => request(`/api/admin/image-assets/orphans?limit=${encodeURIComponent(limit)}&minAgeHours=${encodeURIComponent(minAgeHours)}`),
  cleanupAdminUnusedImageAssets: (payload) => request('/api/admin/image-assets/cleanup', { method: 'POST', body: payload || {} }),
  promoteAdminTemplateItem: (itemId, payload) =>
    request(`/api/admin/custom-items/${encodeURIComponent(itemId)}/promote`, { method: 'POST', body: payload }),
  unlinkAdminCustomItemTemplate: (itemId, payload) =>
    request(`/api/admin/custom-items/${encodeURIComponent(itemId)}/unlink-template`, { method: 'POST', body: payload }),
  replaceAdminCustomItem: (itemId, payload) =>
    request(`/api/admin/custom-items/${encodeURIComponent(itemId)}/replace`, { method: 'POST', body: payload }),
  restoreAdminCustomItem: (itemId) =>
    request(`/api/admin/custom-items/${encodeURIComponent(itemId)}/restore`, { method: 'POST', body: {} }),
  updateAdminCustomItemLabel: (itemId, payload) =>
    request(`/api/admin/custom-items/${encodeURIComponent(itemId)}/label`, { method: 'PATCH', body: payload }),
  promoteAdminTierListItems: (tierListId, payload) =>
    request(`/api/admin/tierlists/${encodeURIComponent(tierListId)}/promote-items`, { method: 'POST', body: payload }),
  createAdminTemplateFromTierList: (tierListId, payload) =>
    request(`/api/admin/tierlists/${encodeURIComponent(tierListId)}/create-template`, { method: 'POST', body: payload }),
  startAdminTemplateRequestReview: (requestId) =>
    request(`/api/admin/template-requests/${encodeURIComponent(requestId)}/review`, { method: 'POST', body: {} }),
  linkAdminTemplateRequestTemplate: (requestId, payload) =>
    request(`/api/admin/template-requests/${encodeURIComponent(requestId)}/link-template`, { method: 'POST', body: payload }),
  promoteAdminTemplateRequestItems: (requestId, payload) =>
    request(`/api/admin/template-requests/${encodeURIComponent(requestId)}/promote-items`, { method: 'POST', body: payload }),
  completeAdminTemplateRequest: (requestId) =>
    request(`/api/admin/template-requests/${encodeURIComponent(requestId)}/complete`, { method: 'POST', body: {} }),
  approveAdminTemplateRequest: (requestId, payload) =>
    request(`/api/admin/template-requests/${encodeURIComponent(requestId)}/approve`, { method: 'POST', body: payload || {} }),
  rejectAdminTemplateRequest: (requestId) => request(`/api/admin/template-requests/${encodeURIComponent(requestId)}/reject`, { method: 'POST', body: {} }),
  listAdminUsers: ({ q = '', sort = 'recent', direction = 'desc' } = {}) =>
    request(`/api/admin/users?q=${encodeURIComponent(q)}&sort=${encodeURIComponent(sort)}&direction=${encodeURIComponent(direction)}`),
  updateAdminUser: (userId, payload) =>
    request(`/api/admin/users/${encodeURIComponent(userId)}`, { method: 'PATCH', body: payload }),
  updateAdminUserPassword: (userId, payload) =>
    request(`/api/admin/users/${encodeURIComponent(userId)}/password`, { method: 'PATCH', body: payload }),
  updateAdminUserAvatar: async (userId, { file, removeAvatar = false } = {}) => {
    const fd = new FormData()
    if (file) fd.append('avatar', file)
    if (removeAvatar) fd.append('removeAvatar', '1')
    const res = await fetch(toApiUrl(`/api/admin/users/${encodeURIComponent(userId)}/avatar`), {
      method: 'POST',
      credentials: 'include',
      body: fd,
    })
    const data = await res.json()
    if (!res.ok) {
      const err = new Error('request_failed')
      err.status = res.status
      err.data = data
      throw err
    }
    return data
  },
  deleteAdminUser: (userId) => request(`/api/admin/users/${encodeURIComponent(userId)}`, { method: 'DELETE' }),

  listPublicTierListsByTopic: (topicId) =>
    request(`/api/tierlists/public?topicId=${encodeURIComponent(topicId || '')}`),
  searchPublicTierListsByTopic: (topicId, q = '') =>
    request(`/api/tierlists/public?topicId=${encodeURIComponent(topicId || '')}&q=${encodeURIComponent(q || '')}`),
  searchAllPublicTierLists: (q = '') => request(`/api/tierlists/public?q=${encodeURIComponent(q || '')}`),
  listMyTierLists: () => request('/api/tierlists/me'),
  listMyFavoriteTierLists: ({ q = '', sort = 'favorited' } = {}) =>
    request(`/api/tierlists/favorites/me?q=${encodeURIComponent(q)}&sort=${encodeURIComponent(sort)}`),
  getUserProfile: (userId) => request(`/api/users/${encodeURIComponent(userId)}`),
  listUserPublicTierLists: (userId, { q = '' } = {}) =>
    request(`/api/users/${encodeURIComponent(userId)}/tierlists?q=${encodeURIComponent(q || '')}`),
  listFollowingFeed: ({ q = '' } = {}) =>
    request(`/api/users/following-feed?q=${encodeURIComponent(q || '')}`),
  followUser: (userId) => request(`/api/users/${encodeURIComponent(userId)}/follow`, { method: 'POST', body: {} }),
  unfollowUser: (userId) => request(`/api/users/${encodeURIComponent(userId)}/follow`, { method: 'DELETE' }),
  getTierList: (id) => request(`/api/tierlists/${encodeURIComponent(id)}`),
  favoriteTierList: (id) => request(`/api/tierlists/${encodeURIComponent(id)}/favorite`, { method: 'POST' }),
  unfavoriteTierList: (id) => request(`/api/tierlists/${encodeURIComponent(id)}/favorite`, { method: 'DELETE' }),
  deleteTierList: (id) => request(`/api/tierlists/${encodeURIComponent(id)}`, { method: 'DELETE' }),
  duplicateTierList: (id) => request(`/api/tierlists/${encodeURIComponent(id)}/duplicate`, { method: 'POST' }),
  requestTierListTemplate: (payload) => request('/api/tierlists/template-request', { method: 'POST', body: payload }),
  saveTierList: (payload) => request('/api/tierlists', { method: 'POST', body: payload }),
  uploadTierListThumbnail: async (file) => {
    const fd = new FormData()
    fd.append('thumbnail', file)
    const res = await fetch(toApiUrl('/api/tierlists/thumbnail'), {
      method: 'POST',
      credentials: 'include',
      body: fd,
    })
    const data = await res.json()
    if (!res.ok) {
      const err = new Error('request_failed')
      err.status = res.status
      err.data = data
      throw err
    }
    return data
  },
  deleteAdminCustomItem: (itemId) => request(`/api/admin/custom-items/${encodeURIComponent(itemId)}`, { method: 'DELETE' }),
  deleteAdminUnusedCustomItems: ({ q = '' } = {}) =>
    request(`/api/admin/custom-items?q=${encodeURIComponent(q)}`, { method: 'DELETE' }),
}
