import { GetAccessToken } from "../../gcloud.js";
import { jsonError } from "../../common.js";

const allowedFileTypes = [
  "image/gif",
  "image/heic",
  "image/heif",
  "image/jpeg",
  "image/png",
  "video/mp4",
  "video/webm",
];

export async function onRequestPost(context: RequestContext) {
  if (
    !context.data.current_user?.permissions ||
    ![1 << 0, 1 << 2, 1 << 11].find(
      (p) => context.data.current_user.permissions & p,
    )
  )
    return jsonError("Forbidden", 403);

  if (
    !context.request.headers
      .get("content-type")
      ?.toLowerCase()
      .startsWith("multipart/form-data;")
  )
    return jsonError("Invalid content type", 400);

  let body: FormData;

  try {
    body = await context.request.formData();
  } catch {
    return jsonError("Invalid form data", 400);
  }

  if (
    ![
      "verbal",
      "warn",
      "mute",
      "ban_temp",
      "ban_perm",
      "ban_unappealable",
    ].includes(body.get("punishment") as string)
  )
    return jsonError("Invalid punishment", 400);

  if (!(body.get("user") as string).match(/^\d{17,19}$/))
    return jsonError("Invalid user", 400);

  const fileKeys = Array.from(body.keys()).filter((key) =>
    key.match(/^file\d$/),
  );

  if (fileKeys.length > 5)
    return jsonError("Only up to five files are allowed per infraction", 400);

  const files: File[] = [];

  for (const fileKey of fileKeys) {
    const file = body.get(fileKey);

    if (!(file instanceof File))
      return jsonError("File keys can only contain files", 400);

    files.push(file);
  }

  const uploadPromises = [];
  const origin = context.request.headers.get("Origin");

  if (!origin) return jsonError("Origin header missing", 400);

  const accessToken = await GetAccessToken(context.env);

  for (const file of files) {
    if (!allowedFileTypes.includes(file.type))
      return jsonError(`File ${file.name} is not valid`, 415);

    const attachmentKey = `${Date.now()}${Math.round(
      Math.random() * 10000000,
    ).toString()}/${file.name}`;

    uploadPromises.push(
      fetch(
        `https://storage.googleapis.com/upload/storage/v1/b/portal-carcrushers-cc/o?name=${encodeURIComponent(
          attachmentKey,
        )}&uploadType=media`,
        {
          headers: {
            authorization: `Bearer ${accessToken}`,
            "content-type": file.type,
          },
        },
      ),
    );
  }

  await Promise.allSettled(uploadPromises);

  const infractionId = `${body.get(
    "user",
  )}${Date.now()}${context.request.headers.get("cf-ray")?.split("-")[0]}`;

  await context.env.DATA.put(
    infractionId,
    JSON.stringify({
      created_at: Date.now(),
      moderator: context.data.current_user.id,
    }),
  );

  return new Response(null, {
    status: 204,
  });
}
