import axios, { AxiosResponse, InternalAxiosRequestConfig } from 'axios'
import Config from '@/config/config.export'
import { useSpinnerStore } from '@/store/spinnerStore'

export function useAxios() {
  // const { setIsShow } = useSpinnerStore()

  const requestHandler = (config: InternalAxiosRequestConfig) => {
    // setIsShow(true)
    return config
  }

  const responseHandler = (response: AxiosResponse) => {
    // setIsShow(false)
    response.data = transferResponse(response)
    return response
  }

  const errorHandler = (error: any) => {
    // setIsShow(false)
    return Promise.reject(error)
  }

  const createAxiosInstance = (url: string | null | undefined) => {
    const baseURL = url || Config().baseUrl
    return axios.create({
      baseURL,
      headers: {
        Accept: 'application/json',
      },
    })
  }

  const axiosInstance = (url: string | null | undefined) => {
    const instance = axios.create({
      baseURL: url || Config().baseUrl,
      headers: {
        Accept: 'application/json',
      },
    })

    instance.interceptors.request.use(
      // (config) => {
      //   return config
      // },
      // (error) => {
      //   return Promise.reject(error)
      // },
      (config) => requestHandler(config),
      (error) => errorHandler(error),
    )

    instance.interceptors.response.use(
      // (response) => {
      //   response.data = transferResponse(response)
      //   return response
      // },
      // (error) => {
      //   return Promise.reject(error)
      // },
      (response) => responseHandler(response),
      (error) => errorHandler(error),
    )

    return instance
  }

  // response데이터가  array, object에 따라 분기하여 키 변환
  const transferResponse = (response: any) => {
    if (!response.data) return response.data

    // 배열인 경우 각 객체의 키를 변환
    if (Array.isArray(response.data)) {
      return response.data.map((item: any) => transformObjectKeys(item))
    }

    // 단일 객체인 경우
    return transformObjectKeys(response.data)
  }

  // camel case object 반환
  const transformObjectKeys = (obj: any): any => {
    if (Array.isArray(obj)) {
      return obj.map(transformObjectKeys)
    }

    if (obj !== null && typeof obj === 'object') {
      return Object.keys(obj).reduce((acc: any, key: string) => {
        let transformedKey = key

        // Handle uppercase snake_case (e.g., USER_NAME -> userName)
        // Handle lowercase snake_case (e.g., user_name -> userName)
        if (/^[A-Z_]+$/.test(key) || /^[a-z_]+$/.test(key)) {
          transformedKey = snakeToCamel(key)
        }
        // Handle single uppercase word (e.g., ROLE -> role)
        else if (/^[A-Z]+$/.test(key)) {
          transformedKey = key.toLowerCase()
        }
        // Preserve existing camelCase

        acc[transformedKey] = transformObjectKeys(obj[key])
        return acc
      }, {})
    }

    return obj
  }

  const snakeToCamel = (str: string): string => {
    return str.toLowerCase().replace(/([-_][a-z])/g, (group) => group.toUpperCase().replace('-', '').replace('_', ''))
  }

  return {
    axiosInstance,
    transferResponse,
    transformObjectKeys,
  }
}
