import jwtDefaultConfig from './jwtDefaultConfig'

export default class JwtService {
    // Will be used by this service for making API calls
    axiosIns = null

    // jwtConfig <= Will be used by this service
    jwtConfig = {
        ...jwtDefaultConfig
    }

    // For Refreshing Token
    isAlreadyFetchingAccessToken = false

    // For Refreshing Token
    subscribers = []

    constructor(axiosIns, jwtOverrideConfig) {
        this.axiosIns = axiosIns
        this.jwtConfig = {
            ...this.jwtConfig,
            ...jwtOverrideConfig
        }

        // Request Interceptor
        this.axiosIns.interceptors.request.use(
            config => {
                // Get token from localStorage
                const accessToken = this.getToken()
                // If token is present add it to request's Authorization Header
                if (accessToken) {
                    // eslint-disable-next-line no-param-reassign
                    config.headers.Authorization = `${this.jwtConfig.tokenType} ${accessToken}`
                }
                return config
            },
            error => Promise.reject(error),
        )

        // Add request/response interceptor
        this.axiosIns.interceptors.response.use(
            response => response,
            error => {
                // const { config, response: { status } } = error
                if (error.request && error.request.status === 401) {
                    // Set Failed Request
                    let failedRequest = error.config;

                    //Method to get new token
                    error = "401錯誤! \n你沒有在" + failedRequest.url + "使用" + failedRequest.method + "的權限! 如有問題請聯絡管理員"
                } else if (error.request && error.request.status === 403) {
                    // Set Failed Request
                    let failedRequest = error.config;

                    //Method to get new token
                    error = "403錯誤! \n你沒有在" + failedRequest.url + "使用" + failedRequest.method + "的權限! 如有問題請聯絡管理員"
                } else if (error.request && error.request.status === 422) {
                    // Set Failed Request
                    let failedRequest = error.config;

                    //Method to get new token
                    error = "422錯誤! 請檢查是否有未填寫的欄位!"
                }else if (error.request && error.request.status === 500) {
                    // Set Failed Request
                    let failedRequest = error.config;

                    //Method to get new token
                    error = "500錯誤! 伺服器發生錯誤!"
                }
                throw error;
            },
        )
    }

    onAccessTokenFetched(accessToken) {
        this.subscribers = this.subscribers.filter(callback => callback(accessToken))
    }

    addSubscriber(callback) {
        this.subscribers.push(callback)
    }

    getToken() {
        return localStorage.getItem(this.jwtConfig.storageTokenKeyName)
    }

    getRefreshToken() {
        return localStorage.getItem(this.jwtConfig.storageRefreshTokenKeyName)
    }

    setToken(value) {
        localStorage.setItem(this.jwtConfig.storageTokenKeyName, value)
    }

    setRefreshToken(value) {
        localStorage.setItem(this.jwtConfig.storageRefreshTokenKeyName, value)
    }

    login(...args) {
        return this.axiosIns.post(this.jwtConfig.loginEndpoint, ...args)
    }

    logout() {
        return this.axiosIns.post(this.jwtConfig.logoutEndpoint)
    }

    register(...args) {
        return this.axiosIns.post(this.jwtConfig.registerEndpoint, ...args)
    }

    refreshToken() {
        return this.axiosIns.post(this.jwtConfig.refreshEndpoint, {
            refreshToken: this.getRefreshToken(),
        })
    }

    postData(url, ...args) {
        return this.axiosIns.post(url, ...args)
    }

    getData(url, ...args) {
        return this.axiosIns.get(url, ...args)
    }

}
