import { AuthToken } from "./types";
import {
  ErrorResponse,
  isErrorResponse,
  ApiError,
  buildUnknownError,
} from "./errors";
import { getSourceByPathname } from "@/utils/source.utils";

export function createMethod<P, R>(createRequest: (payload: P) => Request) {
  return async (payload: P): Promise<R> => {
    const request = createRequest(payload);
    const source = getSourceByPathname()

    const sessionId = localStorage.getItem(`${source}_sessionId`);

    if (sessionId?.length) {
      request.headers.append("session-id", sessionId);
    }
    const response = await fetch(request);
    const data: R | ErrorResponse = await response.json();
    const statusCode = response.status;

    if (!response.ok) {
      const body = isErrorResponse<R>(data)
        ? data
        : { error: buildUnknownError(statusCode) };
      throw new ApiError<R | ErrorResponse>({ body, statusCode, responseData: data });
    }

    if (isErrorResponse<R>(data)) {
      throw new ApiError<R | ErrorResponse>({ body: data, statusCode, responseData: data });
    }

    return data;
  };
}

export function getBaseHeaders(): Headers {
  return new Headers({
    "Content-Type": "application/json",
  });
}

export function getAuthHeaders(token: AuthToken): Headers {
  const headers = getBaseHeaders();
  headers.append("Authorization", `Bearer ${token}`);
  return headers;
}

export function getAuthOpenAIHeaders(token: AuthToken): Headers {
  const headers = getBaseHeaders();
  headers.append("Authorization", `Bearer ${token}`);
  headers.append("OpenAI-Beta", "assistants=v1");
  return headers;
}
