import createClient, { type Middleware } from "openapi-fetch";
import useAuthStore from "../composables/store/useAuthStore";
import type { paths } from "./types/schema"; // generated by openapi-typescript
import {
	ForbiddenError,
	RequestError,
	UnAuthError,
	InternalServerError,
} from "@/types/ErrorTypes";

const myMiddleware: Middleware = {
	onRequest({ request, options }) {
		const authStore = useAuthStore();
		request.headers.set("Authorization", authStore.get());
		return request;
	},
	async onResponse({ request, response, options }) {
		const { body, ...resOptions } = response;
		if (response.status >= 400 && response.status < 500) {
			if (response.status === 401) {
				handleAuthError(response);
			} else if (response.status === 403) {
				handleForbiddenError(response);
			} else {
				handleRequestError(response);
			}
		} else if (response.status >= 500) {
			await handleServerError(response);
		} else {
			return response;
		}
	},
	async onError({ error }) {
		// wrap errors thrown by fetch
		return;
	},
};

const client = createClient<paths>({
	baseUrl: `${import.meta.env.VITE_BASE_URL}`,
	querySerializer: {
		object: {
			style: "form",
			explode: true,
		},
	},
});

// register middleware
client.use(myMiddleware);

const handleAuthError = (response: Response) => {
	throw new UnAuthError(response.status);
};

const handleForbiddenError = (response: Response) => {
	throw new ForbiddenError(response.status);
};

const handleRequestError = (response: Response) => {
	throw new RequestError(response.status);
};

const handleServerError = async (response: Response) => {
	const data = await response.json();
	throw new InternalServerError(response.status, data.detail);
};

export default client;
