import { buildAtlas } from "./atlas.js";
import { emitEvent } from "./events.js";
import { setState, STATE } from "./state.js";
import { registerLoadCallback } from "./main.js";
import { addEventToButton } from "./dom-utils.js";
import { showOpenFileDialog } from "./files.js";
import { DevError, UserError } from "./errors.js";

export let configuration = {};

registerLoadCallback(() => {
  addEventToButton("load-configuration", "click", loadConfiguration);
});

export async function loadConfiguration(event) {
  setState(STATE.initialization);

  emitEvent("config:load:start");
  let configData = null;
  if (typeof event === "string") {
    configData = await fetch(`./configurations/${event}.ncpf.json`)
          .then(data => data.json());
  } else if (event.currentTarget?.dataset?.configuration) {
    const configuration = event.currentTarget.dataset.configuration;
    console.log(configuration);
    configData = await fetch(`./configurations/${configuration}.ncpf.json`)
          .then(data => data.json());
  } else if (event.currentTarget?.tagName === "BUTTON") {
    const { data } = await new Promise(resolve => showOpenFileDialog(resolve));
    console.log(data);
    configData = data;
  } else if (event?.target?.files && event.target.files[0]) {
    const file = event.target.files[0];
    configData = await new Promise(resolve => {
      const reader = new FileReader();
      reader.addEventListener("load", () => {
        resolve(JSON.parse(reader.result));
      });
      reader.readAsText(file);
    });
  } else {
    throw new DevError("Configuration load failed - unrecognised event");
  }

  if ((configData.designs ?? []).length > 0) {
    throw new UserError("Configuration load failed - contains designs, not a full configuration!");
  }

  emitEvent("config:load:end");

  try {
    await processConfiguration(configData);
  } catch (e) {
    emitEvent("config:fail");
    throw e;
  }

  configuration = configData;

  emitEvent("config:end");
}

export async function processConfiguration(data) {
  emitEvent("config:process:start");

  data = configurationDatafixer(data);

  console.log("Configuration: ", data);

  try {
    await buildAtlas(data);
  } catch (e) {
    console.error(e);
    emitEvent("config:process:fail");
    throw e;
  }

  emitEvent("config:process:end");
}

export function configurationDatafixer(data, options = {}) {
  if (!options.dontSetSFRCasingForPorts) {
    for (const block of data.configuration["nuclearcraft:overhaul_sfr"].blocks) {
      if (block.modules["nuclearcraft:overhaul_sfr:port"] && !block.modules["nuclearcraft:overhaul_sfr:casing"]) {
        block.modules["nuclearcraft:overhaul_sfr:casing"] = {
          edge: false,
        };
      }
    }
  }
  return data;
}
