import { ElMessage } from 'element-plus'
import { router } from '@/router'
import { $t } from '@/locales'
import { ApiStatus } from '@/utils/http/status'
import type { HttpError } from '@/utils/http/error'

const collectValidationMessages = (payload: unknown): string[] => {
  if (!payload) return []
  if (typeof payload === 'string') return [payload]
  if (Array.isArray(payload)) return payload.map((item) => String(item))

  if (typeof payload === 'object') {
    const messages: string[] = []
    Object.entries(payload as Record<string, unknown>).forEach(([field, value]) => {
      if (Array.isArray(value)) {
        value.forEach((item) => messages.push(`${field}: ${String(item)}`))
        return
      }

      if (typeof value === 'string') {
        messages.push(`${field}: ${value}`)
        return
      }

      if (value) {
        messages.push(`${field}: ${String(value)}`)
      }
    })

    return messages
  }

  return []
}

const redirectForbidden = () => {
  router.replace('/403').catch(() => {})
}

export const handleHttpError = (error: HttpError, showMessage: boolean = true) => {
  if (error.code === ApiStatus.forbidden) {
    redirectForbidden()
    if (showMessage) {
      ElMessage.error($t('httpMsg.forbidden'))
    }
    return
  }

  if (!showMessage) {
    return
  }

  if (error.code === ApiStatus.conflict) {
    ElMessage.warning($t('httpMsg.conflict'))
    return
  }

  if (error.code === ApiStatus.error || error.code === ApiStatus.unprocessableEntity) {
    const messages = collectValidationMessages(error.data)
    ElMessage.error(messages.length > 0 ? messages.join('; ') : error.message)
    return
  }

  if (error.code >= ApiStatus.internalServerError) {
    ElMessage.error($t('httpMsg.internalServerError'))
    return
  }

  ElMessage.error(error.message)
}
