import axios from "axios";
import { refreshAccessToken, getAccessToken, logout, API_URL } from "./auth";

const apiInstance = axios.create({
    baseURL: API_URL,
    headers: {
        "Content-Type": "application/json",
    },
});

// Request Interceptor - Attaches access token
apiInstance.interceptors.request.use(
    async (config) => {
        const token = getAccessToken();
        if (token) {
            config.headers["Authorization"] = `Bearer ${token}`;
        }
        return config;
    },
    (error) => Promise.reject(error)
);

// Response Interceptor - Refreshes token if needed
apiInstance.interceptors.response.use(
    (response) => response,
    async (error) => {
        const originalRequest = error.config;

        if (error.response) {
            // Check for 401 Unauthorized
            if (error.response.status === 401) {
                console.log("401 Unauthorized detected.");
            }

            // Check for 403 with token invalid message
            if (error.response.status === 403 && error.response.data?.code === "token_not_valid") {
                console.log("403 Forbidden detected with 'token_not_valid'.");
            }

            // Handle both cases
            if ((error.response.status === 401 || error.response.status === 403) && !originalRequest._retry) {
                console.log("Attempting token refresh...");

                originalRequest._retry = true;

                const newAccessToken = await refreshAccessToken();
                if (newAccessToken) {
                    originalRequest.headers["Authorization"] = `Bearer ${newAccessToken}`;
                    return apiInstance(originalRequest);
                } else {
                    console.log("Token refresh failed, logging out user.");
                }
            }
        }

        return Promise.reject(error);
    }
);

// API Request Functions
// -------------------

// Fetch posts example
export const fetchPosts = async (page: number = 1) => {
    const response = await apiInstance.get(`/posts/?page=${page}&page_size=25`);
    return response.data;
};

// Fetch a specific post by source site, creator, and ID
export const fetchPostByDetails = async (source_site: string, creator: string, id: string) => {
    const response = await apiInstance.get(`/posts/${source_site}/${creator}/${id}/`);
    return response.data;
};

// Function to get file URL with authentication
export const getFileUrl = (fileHash: string, options?: { thumbnail?: 'sx' | 'sm' | 'md' | 'lg' | 'xl', download?: boolean }) => {
    const token = getAccessToken();

    // Build URL with query parameters
    let url = `${API_URL}/files/${fileHash}/`;
    const queryParams: string[] = [];

    if (options?.thumbnail) {
        queryParams.push(`t=${options.thumbnail}`);
    }

    if (options?.download !== undefined) {
        queryParams.push(`d=${options.download ? '0' : '1'}`);
    }

    if (queryParams.length > 0) {
        url += `?${queryParams.join('&')}`;
    }

    // Append token as query parameter
    url += (queryParams.length > 0 ? '&' : '?') + `token=${token}`;

    return url;
};

// Direct fetch function if you need the file data instead of a URL
export const fetchFile = async (fileHash: string, options?: { thumbnail?: 'sx' | 'sm' | 'md' | 'lg' | 'xl', download?: boolean }) => {
    const response = await apiInstance.get(`${API_URL}/files/${fileHash}/`, {
        params: {
            ...(options?.thumbnail && { t: options.thumbnail }),
            ...(options?.download !== undefined && { d: options.download ? '0' : '1' }),
        },
        responseType: 'blob', // Important for handling binary data
    });

    return response.data;
};

export default apiInstance;
