<script>
import { defineComponent } from "vue";

import axios from "axios";
import localforage from "localforage";
import yaml from "js-yaml";

import settingsData from "@/data/settings.yaml";
import generatorSettings from "@/data/generator-settings.yaml";

import VueMarkdown from "vue-markdown-render";

export default defineComponent({
  components: {
    VueMarkdown,
  },
  props: {
    prefix: null,
    generator: null,
  },
  data() {
    return {
      uploaded_yaml: null,
      yaml_error: null,
    };
  },
  async mounted() {
    document.title = "ALttPR Mystery"
  },
  computed: {
    settings() {
      const settingsList = generatorSettings[this.generator];
      const validSettings = {};

      for (const setting of Object.keys(settingsList)) {
        var generatorValue = settingsList[setting];
        if (generatorValue == "all") {
          validSettings[setting] = Object.keys(settingsData[setting].values);
        } else if (Array.isArray(generatorValue)) {
          validSettings[setting] = generatorValue;
        } else {
          validSettings[setting] = Object.keys(generatorValue.values);
        }
      }

      return validSettings;
    },
  },
  methods: {
    async generate(race) {
      await axios.post(`/mystery/${this.generator}`, this.uploaded_yaml, {
        headers: {
          "Content-Type": "text/yaml",
        },
        params: {
          race: race,
        },
      })
        .then(response => {
          const id = response.data;
          this.$router.push(`/seed/${id}`);
        })
        .catch(error => {
          this.yaml_error = "Bad YAML";
          console.log(error.response?.data);
        });
    },
    yamlErrors(yaml) {
      const errorList = [];

      for (const key of Object.keys(yaml)) {
        if (!(key in this.settings)) {
          errorList.push(`Invalid setting \`${key}\``);
          continue;
        }

        if (yaml[key] instanceof Object) {
          for (const option of Object.keys(yaml[key])) {
            if (!this.settings[key].includes(option)) {
              errorList.push(`Invalid setting \`${key}.${option}\``);
              continue;
            }

            const weight = yaml[key][option];
            if (!/^\d+$/.test(weight)) {
              errorList.push(`Invalid setting weight \`${yaml[key][option]}\` for \`${key}.${option}\``);
            }
          }
        } else {
          const option = yaml[key];
          if (!this.settings[key].includes(option)) {
            errorList.push(`Invalid setting \`${key}.${option}\``);
          }
        }
      }

      return errorList;
    },
    uploadYaml(file) {
      if (!file) {
        this.yaml_error = null;
        this.uploaded_yaml = null;
        return;
      }

      const reader = new FileReader();
      reader.onload = async function() {
        try {
          const parsed_yaml = yaml.load(reader.result, { schema: yaml.FAILSAFE_SCHEMA });
          const errors = this.yamlErrors(parsed_yaml);
          if (errors) {
            this.uploaded_yaml = null;
            this.yaml_error = errors.join("\\\n");
          } else {
            this.uploaded_yaml = reader.result;
            this.yaml_error = null;
          }
        } catch (error) {
          this.uploaded_yaml = null;
          this.yaml_error = "Error parsing YAML";
          if (error.reason) {
            this.yaml_error += `: ${error.reason}`;
          }
          console.log(error);
        }
      }.bind(this);
      reader.readAsText(file);
    },
  },
});
</script>

<template>
  <div class="mw-30">
    <div class="card content-div m-3">
      <div class="card-header">
        Generate Mystery Seed
      </div>
      <ul class="list-group list-group-flush">
        <li class="list-group-item">
          Upload Mystery YAML:
          <a class="example-yaml-link" href="/sample_mystery.yaml">(example)</a>
          <div class="input-group mt-2 mb-2">
            <input id="yaml-input" class="form-control" type="file" accept=".yaml,.yml" @change="uploadYaml($event.target.files[0], true)" />
          </div>
          <div v-if="yaml_error" class="invalid mt-3">
            <vue-markdown :source="yaml_error" />
          </div>
        </li>
      </ul>

      <div class="card-footer">
        <div class="nav nav-pills nav-fill" role="group">
          <button type="button" class="m-1 nav-item btn btn-outline-danger"
              @click="generate(true);" :disabled="uploaded_yaml == null || yaml_error">
            Generate Race Mystery
          </button>
          <button type="button" class="m-1 nav-item btn btn-outline-primary"
              @click="generate(false);" :disabled="uploaded_yaml == null || yaml_error">
            Generate Mystery
          </button>
        </div>
      </div>
    </div>
  </div>
</template>

<style>
.example-yaml-link {
  position: absolute;
  right: 0;
  padding-right: var(--bs-list-group-item-padding-x);
}
</style>
