import type { BackendResponse } from './BackendTypes'

declare global {
    interface Window {
        __ENV__: {
            CDN: string
            API: string
            WEB: string
        }
    }
}

export const API_BASE = window.__ENV__.API
export const CDN_BASE = window.__ENV__.CDN
export const WEB_BASE = window.__ENV__.WEB

export function BackendDebounce(resp: BackendResponse<any>, iteration = 1) {
    const ratelimit = resp.status === 429 && resp.ratelimit.remains === 0
    return {
        ratelimit,
        sleep: new Promise<void>((next) => {
            if (ratelimit) {
                const sleep = resp.ratelimit.reset * 1000
                console.warn(`Ratelimited! sleeping for ${sleep}ms`)
                setTimeout(next, sleep)
            } else {
                setTimeout(next, iteration * 2000)
            }
        }),
    }
}

export function BackendFetch<T>(path: string): Promise<BackendResponse<T>> {
    return new Promise((resolve) => {
        const data: BackendResponse<T> = {
            success: false,
            status: -1,
            error: '',
            ratelimit: { remains: 0, reset: 0, limit: 0 },
            text: '',
            json: null as T,
        }

        fetch(API_BASE + path)
            .then(async (res) => {
                data.status = res.status
                data.success = res.ok
                data.ratelimit.limit = parseInt(res.headers.get('X-Ratelimit-Limit') || '0')
                data.ratelimit.reset = parseFloat(res.headers.get('X-Ratelimit-Reset') || '0')
                data.ratelimit.remains = parseInt(res.headers.get('X-Ratelimit-Remaining') || '0')

                data.text = await res.text()
                data.json = (() => {
                    try {
                        return JSON.parse(data.text)
                    } catch {
                        return null
                    }
                })()

                // Check for Backend Error
                if (!res.ok) {
                    data.error = (data.json as any)?.message ?? `Request failed: ${res.status} ${res.statusText}`
                    return
                }
            })
            .catch((err) => {
                console.error('Request failed due to a network error:', err)
                data.error = 'Network Unavailable'
            })
            .finally(() => resolve(data))
    })
}

// export function BackendGET<T>(path: string): Promise<BackendResponse<T>> {
//     return BackendPOST(path, undefined, {})
// }

// export function BackendPOST<T>(path: string, body: any, headers: Record<string, string>): Promise<BackendResponse<T>> {
//     return new Promise((resolve) => {
//         let requestHeaders = new Headers()
//         let requestMethod = 'GET'

//         Object.entries(headers).forEach(([k, v]) => requestHeaders.set(k, v))
//         if (body) {
//             if (!(body instanceof FormData)) {
//                 requestHeaders.set('Content-Type', 'application/json')
//                 body = JSON.stringify(body)
//             }
//             requestMethod = 'POST'
//         }

//         const data: BackendResponse<T> = {
//             success: false,
//             status: -1,
//             error: '',
//             ratelimit: { remains: 0, reset: 0, limit: 0 },
//             text: '',
//             json: null as T,
//         }

//         fetch(API_BASE + path, {
//             method: requestMethod,
//             headers: requestHeaders,
//             body: body,
//         })
//             .then(async (res) => {
//                 data.status = res.status
//                 data.success = res.ok
//                 data.ratelimit.limit = parseInt(res.headers.get('X-Ratelimit-Limit') || '0')
//                 data.ratelimit.reset = parseFloat(res.headers.get('X-Ratelimit-Reset') || '0')
//                 data.ratelimit.remains = parseInt(res.headers.get('X-Ratelimit-Remaining') || '0')

//                 data.text = await res.text()
//                 data.json = (() => {
//                     try {
//                         return JSON.parse(data.text)
//                     } catch {
//                         return null
//                     }
//                 })()

//                 // Check for Backend Error
//                 if (!res.ok) {
//                     const debugID = res.headers.get('X-Debug-ID')
//                     const message = (data.json as any)?.message ?? `Request failed: ${res.status} ${res.statusText}`

//                     data.error = `${message} ${debugID ? `(${debugID})` : ''}`
//                     return
//                 }
//             })
//             .catch((err) => {
//                 console.error('Request failed due to a network error:', err)
//                 data.error = 'Network Unavailable'
//             })
//             .finally(() => resolve(data))
//     })
// }
