import { createReadStream } from "fs";
import FormData from "form-data";
import axios from "axios";
import { getMobileBundle, getGitShas } from "./projectSetup";
import { makeHeadersWithCookie, getMidUrlAppValue } from "../utils";
import { getAppConfigsFromFS } from "./workspace";

/**
 * Upload a mobile bundle to the Apptile server
 * @param appId The ID of the app
 * @param bundleName The name of the bundle
 * @param os The operating system ('ios' or 'android')
 * @param apptileCookie The cookie for authentication
 * @returns Promise resolving to the upload result
 */
export async function uploadMobileBundle(
  appId: string,
  bundleName: string,
  os: "ios" | "android",
  apptileCookie: string | null
) {
  // Get the bundle file
  const { err: bundleErr, assetZip } = await getMobileBundle(
    appId,
    bundleName,
    os
  );
  if (bundleErr || !assetZip) {
    throw new Error(
      `Failed to retrieve bundle: ${bundleErr || "Asset zip not found"}`
    );
  }

  // Get git shas
  const { err, gitsha, sdksha } = await getGitShas(appId);
  if (err) {
    throw new Error(`Failed to retrieve git shas: ${err}`);
  }

  // Get app config
  const apptileConfig = await getAppConfigsFromFS(appId);

  // Create form data
  const formData = new FormData();
  formData.append("assetZipFile", createReadStream(assetZip));
  formData.append(
    "uploadDestination",
    os === "ios" ? "ios-jsbundle" : "android-jsbundle"
  );
  formData.append("gitsha", gitsha);
  formData.append("sdksha", sdksha);
  formData.append("tag", "sometag");

  // Create headers with cookie
  const headers = makeHeadersWithCookie(apptileCookie, formData.getHeaders());

  // Make request to upload
  const response = await axios.post(
    `${apptileConfig.APPTILE_BACKEND_URL}/${getMidUrlAppValue()}/${appId}/upload`,
    formData,
    headers
  );

  // Handle errors
  if (response.status >= 400) {
    try {
      const errorMessage = response.data;
      throw new Error(`Failed to upload: ${errorMessage}`);
    } catch (err) {
      console.error("Unprocessable error:", err);
      throw err;
    }
  }

  return {
    status: response.status,
    data: response.data,
  };
}
