import nodeFetch, { RequestInfo, RequestInit } from "node-fetch";
import { getGlobalConfig, railwayUrl, backboardUrl } from "./config";
import { Envs, Project, User } from "./types";

export const fetch = async (info: RequestInfo, init?: RequestInit) => {
  const config = getGlobalConfig();
  const envToken = process.env.RAILWAY_PRODUCTION_TOKEN;

  const authHeader: [string, string] | null =
    envToken != null
      ? ["x-access-token", envToken]
      : config.token != null
      ? ["Authorization", config.token]
      : null;

  const res = await nodeFetch(info, {
    ...init,
    headers: {
      ...(init?.headers ?? {}),
      ...(authHeader != null ? { [authHeader[0]]: authHeader[1] } : {}),
    },
  });

  if (res.status !== 200) {
    const text = await res.text();

    try {
      const json = JSON.parse(text);
      throw new Error(json?.error ?? "Error making request");
    } catch (e) {
      if (e instanceof SyntaxError) {
        throw new Error(text ?? "Error making request");
      }

      throw e;
    }
  }

  const json = await res.json();
  return json;
};

export const getProjectEnv = (
  projectId?: string,
  environmentId?: string,
): Promise<Envs> =>
  fetch(
    `${railwayUrl}/api/cli?projectId=${projectId}&environmentId=${environmentId}`,
  );

export const createProject = async (name: string): Promise<Project> => {
  const { project } = await fetch(`${railwayUrl}/api/project`, {
    method: "POST",
    headers: {
      "content-type": "application/json",
    },
    body: JSON.stringify({
      name,
    }),
  });

  return project;
};

export const getProject = async (projectId: string): Promise<Project> => {
  const { project } = await fetch(`${railwayUrl}/api/project/${projectId}`);
  return project;
};

export const getUser = async (): Promise<User> => {
  const { user } = await fetch(`${railwayUrl}/api/user`);
  return user;
};

export const deployDirectory = async (
  projectId: string,
  body: any,
): Promise<string> => {
  const { URL } = await fetch(`${backboardUrl}/api/project/${projectId}/up`, {
    method: "POST",
    body,
  });
  return URL;
};
