import { objectTypeForOriginAndContentType } from "../object-types";
let mediaAPIEndpoint = "/api/v1/media";

if (process.env.RETICULUM_SERVER) {
  mediaAPIEndpoint = `https://${process.env.RETICULUM_SERVER}${mediaAPIEndpoint}`;
}

const fetchContentType = async url => {
  return fetch(url, { method: "HEAD" }).then(r => r.headers.get("content-type"));
};

const contentIndexCache = new Map();
export const fetchMaxContentIndex = async (documentUrl, pageUrl) => {
  if (contentIndexCache.has(documentUrl)) return contentIndexCache.get(documentUrl);
  const maxIndex = await fetch(pageUrl).then(r => parseInt(r.headers.get("x-max-content-index")));
  contentIndexCache.set(documentUrl, maxIndex);
  return maxIndex;
};

const resolveMediaCache = new Map();
export const resolveMedia = async (url, skipContentType, index) => {
  const parsedUrl = new URL(url);
  const cacheKey = `${url}|${index}`;
  if (resolveMediaCache.has(cacheKey)) return resolveMediaCache.get(cacheKey);

  const isHttpOrHttps = parsedUrl.protocol === "http:" || parsedUrl.protocol === "https:";
  const resolved = !isHttpOrHttps
    ? { raw: url, origin: url }
    : await fetch(mediaAPIEndpoint, {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ media: { url, index } })
      }).then(r => r.json());

  if (isHttpOrHttps && !skipContentType) {
    const contentType =
      (resolved.meta && resolved.meta.expected_content_type) || (await fetchContentType(resolved.raw));
    resolved.contentType = contentType;
  }

  resolveMediaCache.set(cacheKey, resolved);
  return resolved;
};

export const upload = file => {
  const formData = new FormData();
  formData.append("media", file);
  return fetch(mediaAPIEndpoint, {
    method: "POST",
    body: formData
  }).then(r => r.json());
};

let interactableId = 0;
export const addMedia = (src, contentOrigin, resize = false) => {
  const scene = AFRAME.scenes[0];

  const entity = document.createElement("a-entity");
  entity.id = "interactable-media-" + interactableId++;
  entity.setAttribute("networked", { template: "#interactable-media" });
  entity.setAttribute("media-loader", { resize, src: typeof src === "string" ? src : "" });
  scene.appendChild(entity);

  if (src instanceof File) {
    upload(src)
      .then(response => {
        const srcUrl = new URL(response.raw);
        srcUrl.searchParams.set("token", response.meta.access_token);
        entity.setAttribute("media-loader", { src: srcUrl.href });
      })
      .catch(() => {
        entity.setAttribute("media-loader", { src: "error" });
      });
  }

  entity.addEventListener("media_resolved", ({ detail }) => {
    const objectType = objectTypeForOriginAndContentType(contentOrigin, detail.contentType);
    scene.emit("object_spawned", { objectType });
  });

  return entity;
};