import { API } from "../Constants.ts"

export interface Authentication {
    token: string
    expirationDate: Date
}

export class Fetcher {
    private auth?: Authentication

    public constructor(auth?: Authentication) {
        this.auth = auth
    }

    async fetchAPI(
        url: string,
        payload: unknown,
        method = "POST",
    ): Promise<Response> {
        const token = this.auth?.token

        const headers: HeadersInit = {
            Accept: "application/json",
            "Content-Type": "application/json",
        }

        if (token) {
            headers.Authorization = token
        }

        const response = await fetch(`${API}/${url}`, {
            method,
            headers,
            body: JSON.stringify(payload),
        })

        return await this.handleResponse(response)
    }

    async fetchAPIGet(url: string): Promise<Response> {
        const token = this.auth?.token

        const headers: HeadersInit = {
            Accept: "application/json",
            "Content-Type": "application/json",
        }

        if (token) {
            headers.Authorization = token
        }

        const response = await fetch(`${API}/${url}`, {
            method: "GET",
            headers,
        })

        return await this.handleResponse(response)
    }

    updateAuthentication(auth: Authentication) {
        this.auth = auth
    }

    async handleResponse(response: Response): Promise<Response> {
        // if we provided a token but still unauthorized, the token has expired
        if (!response.ok) {
            return response
        }

        const nextToken = response.headers.get("Next-Authorization")!
        const expirationDate = response.headers.get(
            "Next-Authorization-Expiration-Date",
        )!
        if (nextToken && expirationDate) {
            this.auth = {
                token: nextToken,
                expirationDate: new Date(expirationDate),
            }
        }

        return response
    }
}
