import {
    getEncryptToBase64 as encrypt,
    getDecryptByBase64 as decrypt,
  } from './encryption'
const encodeReserveRE = /[!'()*]/g
const encodeReserveReplacer = (c) => '%' + c.charCodeAt(0).toString(16)
const commaRE = /&2c/g

const encode = (str)=>{
    return encodeURIComponent(str)
        .replace(encodeReserveRE,encodeReserveReplacer)
        .replace(commaRE,',')
}

const decode = decodeURIComponent

function isBase64(str){
    if(!str || str.trim() === ''){
        return false
    }

    const base64Pattern = /^[A-Za-z0-9+/]*={0,2}$/

    if(!base64Pattern.test(str)){
        return false
    }

    try{
        return btoa(atob(str)) === str
    }catch(err){
        return false
    }
}

export const stringifyQuery = (obj)=>{
    const res = obj
        ? Object.keys(obj).map((key)=>{
            const val = obj[key]
            if(val === null || val === undefined){
                return encode(key)
            }

            if(Array.isArray(val)){
                const result = []
                val.forEach((val2)=>{
                    if(val === null || val === undefined){
                        result.push(encode(key))
                    }else{
                        result.push(encode(key) + '=' + encode(val2))
                    }
                })
                return result.join('&')
            }
            return encode(key) + '=' + encode(val)
        }).join('&')
        : null
    return res ? `?${encrypt(res)}` : ''
}


export const parseQuery = (query) =>{
    const res = {}

    query = query.trim().replace(/^(\?|#|&)/,'')

    if(!query){
        return res
    }

    query = isBase64(query) ? decrypt(query) : query
    // try{
    //     query = decrypt(query)
    // }catch(err){
    //     query = query
    // }

    query.split('&').forEach((param)=>{
        const parts = param.split('=')
        const key = decode(parts.shift())
        const val = parts.length>0 ? decode(parts.join('')) : null
        if(res[key] === undefined){
            res[key] = val
        }else if(Array.isArray(res[key])){
            res[key].push(val)
        }else{
            res[key] = [res[key],val]
        }
    })
    return res
}