<script lang="ts">
	import { runCommand } from "$lib/client/lucifer";
	import HSplit from "$lib/components/HSplit.svelte";
	import HSplitPart from "$lib/components/HSplitPart.svelte";
  import Modal from "$lib/components/Modal.svelte";
	import ModalBody from "$lib/components/ModalBody.svelte";
	import ModalSection from "$lib/components/ModalSection.svelte";
	import ScriptLineBlock from "$lib/components/scripting/ScriptLineBlock.svelte";
	import { getModalContext } from "$lib/contexts/ModalContext.svelte";
	import { getSelectedContext } from "$lib/contexts/SelectContext.svelte";
	import { getStateContext } from "$lib/contexts/StateContext.svelte";
	import { toEditableScriptLine, type ScriptLineEditable, fromEditableScriptLine } from "$lib/models/script";

  const { state } = getStateContext();
  const { selectedMasks } = getSelectedContext();
  const { modal } = getModalContext();

  let show = false;
  let disabled = false;
  let selectedScript = "";
  let runMatch = "";
  let newScriptName = "New Script";
  let current: ScriptLineEditable[] = [];

  function onOpen() {
    disabled = false;
    current = [];
    selectedScript = scriptNames?.[0] || "";
    loadScript(selectedScript);
  }

  async function onSubmit() {
    disabled = true;

    try {
      await runCommand({updateScript: { name: selectedScript || newScriptName, lines: current.map(fromEditableScriptLine) }});
      if (runMatch !== "") {
        await runCommand({executeScript: { name: selectedScript || newScriptName, match: runMatch, }});
      }
      await new Promise(resolve => setTimeout(resolve, 500));
      
      selectedScript = selectedScript || newScriptName;
    } catch(_) {}

    disabled = false;
  }

  function loadScript(name: string) {
    if (name === "") {
      current = [];
    } else {
      current = $state?.scripts[name]?.map(toEditableScriptLine) || [];
    }
  }

  function addLine() {
    current = [
      ...current,
      toEditableScriptLine({if: {
        condition: { scope: "global", key: "", op: "eq" },
        then: [],
        else: [],
      }})
    ]
  }

  $: if ($modal.kind === "script.edit") {
    show = true;
    onOpen();
  } else {
    show = false;
  }

  $: scriptNames = Object.keys($state?.scripts||{}).sort();
  $: loadScript(selectedScript);
</script>

<form novalidate on:submit|preventDefault={onSubmit}>
  <Modal 
    ultrawide closable show={show} 
    titleText="Script Editor" 
    disabled={disabled || (selectedScript === "" && current.length === 0)}
    submitText={(current.length > 0 || selectedScript === "") ? "Save Script" : "Delete Script"}
  >
    <ModalBody>
      <HSplit>
        <HSplitPart weight={33.3}>
          <label for="mask">Script</label>
          <select bind:value={selectedScript}>
            {#each scriptNames as scriptName}
              <option value={scriptName}>{scriptName}</option>
            {/each}
            <option value="">New Script</option>
          </select>
        </HSplitPart>
        <HSplitPart weight={33.3}>
          {#if selectedScript === ""}
            <label for="mask">New Script Name</label>
            <input type="text" bind:value={newScriptName}>
          {/if}
        </HSplitPart>
        <HSplitPart weight={33.4}>
          {#if $selectedMasks.length > 0}
            <label for="mask">Run on Save</label>
            <select bind:value={runMatch}>
              <option value="">Don't Run</option>
              {#each $selectedMasks as option (option)}
                <option value={option}>{option}</option>
              {/each}
            </select>
          {/if}
        </HSplitPart>
      </HSplit>

      <ModalSection expanded disableExpandToggle title="Edit Script">
        <ScriptLineBlock add on:add={addLine} label="Script" bind:value={current} />
      </ModalSection>
    </ModalBody>
  </Modal>
</form>