<script>
  import template from "lodash/template";
  import Icon from "$/client/components/Icon.svelte";
  import Toasts from "$/client/components/Toasts.svelte";
  import Code from "$/client/components/Code.svelte";
  import { log } from "$/client/logging.js";
  import Layout from "../Layout.svelte";
  import api from '$/client/api.js';
  import { onMount } from "svelte";

  export let selected_template;

  let showing_rendered = false;
  let results = "";
  let source = "";
  let variable_json = "{ }";
  let generators = [];

  let variables = {};
  let renderer = () => source;
  let notice = "";
  let last_good = "";
  let send_toast;

  let language = "javascript";
  const language_list = {
    "html": "html",
    "svelte": "javascript",
    "sh": "shell",
    "js": "javascript"
  }

  const list_generators = async () => {
    let [status, data] = await api.get('/api/devtools/djenterator');

    if(status == 200) {
      generators = data;
      selected_template = generators[0];
    } else {
      log.debug("failed to load generators", status);
    }
  }

  const render_template = () => {
    try {
      // avoid rendering when the current template doesn't match the renderer
      if(selected_template == renderer._template) {
        variables = variable_json ? JSON.parse(variable_json): {};
        results = renderer(variables);
        notice = "";
        last_good = results;
      }

      return true;
    } catch(err) {
      log.error(err);
      notice = err.message;
      results = last_good;
      return false;
    }
  }

  const load_variables = async (template_name) => {
    let res = await fetch(`/djenterator/${template_name}.vars`);

    if(res.status == 200) {
      variable_json = await res.text();
    } else {
      variable_json = '{}';
      notice = `No ${template_name}.vars file found. ${res.status}`;
    }
  }

  const detect_language = (name) => {
    const ext = name.split(".")[1];
    language = language_list[ext];
  }

  const load_template = async (template_name) => {
    let res = await fetch(`/djenterator/${template_name}`);

    if(res.status == 200) {
      source = await res.text();
      last_good = source;
      detect_language(template_name);

      try {
        renderer = template(source);
        // tag this template renderer so that we don't try to render it against the wrong one
        renderer._template = template_name;
        render_template();
      } catch(error) {
        log.error(error);
        notice = `${error.message}`;
        results = source;
      }
    } else {
      notice = `Error loading ${template_name}: ${res.status}`;
    }
  }

  const copy_code = () => {
    navigator.clipboard.writeText(results).then(() => {
      notice = "Code copied to clipboard.";
    }, () => {
      notice = "Failed copying to clipboard.";
    });
  }

  $: if(variable_json) render_template();

  // this reload the templates when you click on a new one
  const re_render = async (what) => {
    await load_variables(what);
    await load_template(what);
  }

  $: if(selected_template) re_render(selected_template);

  onMount(async () => await list_generators());
</script>

<style>
  textarea.editor {
    height: 15em;
    background-color: var(--value0);
    color: var(--value9);
  }
</style>

<Layout fullscreen={ true } header={ false } testid="page-bando-djenterator">
  <blockstart style="width: 100%">
    <block style="--w: 100%">
      <select bind:value={ selected_template }>
        {#each generators as template}
          <option value={ template }>{ template }</option>
        {/each}
      </select>

      <textarea class="editor" bind:value={ variable_json }></textarea>
      {#if notice}
        <callout class="error">{notice}</callout>
      {/if}

      {#if results}
        <Code on:copy={ send_toast("Copied to clipboard!") } content={ results } language={ language } />
      {/if}

    </block>
  </blockstart>
  <Toasts bind:send_toast fade_after={ 10000 } orientation="bottom right" />
</Layout>
