<script>
  import SpTitle from "./SpTitle.svelte";
  import SpTiers from "./SpTiers.svelte";
  import SpKeys from "./SpKeys.svelte";
  import SpCandidates from "./SpCandidates.svelte";
  import SpJournal from "./SpJournal.svelte";
  import SpNotsand from "./SpNotsand.svelte";
  import { onMount } from "svelte";
  let v = "loading...";
  let relpath = "";
  let relpermalink = "";
  let protocol = "";
  let title = "Foo bar";
  let hases = [];
  let hasesCandidates = [];
  let frontmatter = {};
  frontmatter["triad"] = [];
  frontmatter["ascription"] = [];
  frontmatter["journal"] = [];
  frontmatter["notsand"] = [];

  function keyUp(e) {
    if (e.key == "Escape") {
      window.history.back();
    }
  }

  function reckonHasesCandidates() {
    return diffArrr(hases, [
      ...frontmatter["triad"].map((t) => {
        return t.fmKey;
      }),
      ...frontmatter["ascription"].map((t) => {
        return t.fmKey;
      }),
    ]);
  }

  function diffArrr(arr, arrr) {
    let diff = new Set(arr);
    for (let e of arrr) {
      diff.delete(e);
    }
    return Array.from(diff);
  }

  function newFmItem(fmKeyType, fmKey, fmValue) {
    if (["abstract", "keywords"].includes(fmKey.toLowerCase())) {
      fmKeyType = "journal";
    }

    if (fmKey == "_new") {
      fmKey = `_new${Math.random()}`;
    }

    if (Array.isArray(fmValue)) {
      let fmValueArray = [];
      fmValue.forEach((v) => fmValueArray.push(v));
      frontmatter[fmKeyType].push({ fmKey: fmKey, fmValue: fmValueArray });
    } else {
      frontmatter[fmKeyType].push({ fmKey: fmKey, fmValue: fmValue });
    }
    console.log("newFmItem", { frontmatter });
    hasesCandidates = [...new Set(reckonHasesCandidates())];
    toggleNewTiersButtons();
  }

  function newTier(fmKeyType, fmKey, fmValue) {
    let tiers = [];
    let candidates = [];
    if (fmKey == "_new") {
      hasesCandidates = [...new Set(reckonHasesCandidates())];
      if (hasesCandidates.length > 0) {
        fmKey = hasesCandidates[0];
      }
    }

    if (fmKey != "_new") {
      if (fmValue) {
        METASP[fmKey].tiers.forEach((t) => {
          if (fmValue.includes(t.file)) {
            tiers.push(t);
          } else {
            candidates.push(t);
          }
        });
      } else {
        tiers = [];
        candidates = METASP[fmKey].tiers;
      }
      frontmatter[fmKeyType].push({
        fmKey: fmKey,
        tiers: tiers,
        candidates: [...new Set(candidates)],
      });
      frontmatter = { ...frontmatter };
    }
    hasesCandidates = [...new Set(reckonHasesCandidates())];
    toggleNewTiersButtons();
  }

  function loadHugoPageMetadata(editHash) {
    let el = document.createElement("script");
    el.onload = () => {
      v = repo.content;
      if (v.startsWith("\n")) {
        v = v.substring(1);
      }

      relpath = repo.path;
      relpermalink = repo.relpermalink;
      protocol = document.location.protocol.substring(0, 4);
      const notSelf = Object.entries(METASP).filter((n) => n[1].singular == relpath.split("/")[0])[0][0];
      hases = Object.keys(METASP).filter((k) => k != notSelf);
      Object.entries(repo.frontmatter).forEach(([fmKey, fmValue]) => {
        let fmKeyType = "";
        if (fmKey.toLowerCase().startsWith("has_")) {
          if (hases.includes(fmKey.substr(4))) {
            fmKeyType = "triad";
            fmKey = fmKey.substr(4);
          }
        } else if (hases.includes(fmKey.toLowerCase())) {
          fmKeyType = "ascription";
        } else if (["abstract", "keywords"].includes(fmKey.toLowerCase())) {
          fmKeyType = "journal";
        } else {
          fmKeyType = "notsand";
        }

        if (["triad", "ascription"].includes(fmKeyType)) {
          if (Array.isArray(fmValue)) {
            newTier(fmKeyType, fmKey, fmValue);
          }
        } else if (!["draft", "iscjklanguage", "title"].includes(fmKey)) {
          newFmItem(fmKeyType, fmKey, fmValue);
        }
      });
      const tkey = Object.keys(repo.frontmatter).filter((t) => t.toLowerCase() == "title")[0];
      title = repo.frontmatter[tkey];

      toggleNewTiersButtons();
    };
    el.src = `../js/repo/${editHash}.js`;
    document.body.appendChild(el);
  }

  function addToCandidatesRemoveFromTiers(arrgs) {
    const [fmKeyType, index, fmKey, tier] = arrgs.detail;
    frontmatter[fmKeyType][index]["fmKey"] = fmKey;
    frontmatter[fmKeyType][index]["tiers"] = frontmatter[fmKeyType][index]["tiers"].filter(
      (t) => t !== tier
    );
    frontmatter[fmKeyType][index]["candidates"] = [...frontmatter[fmKeyType][index]["candidates"], tier];
  }

  function addToTiersRemoveFromCandidates(arrgs) {
    const [fmKeyType, index, , value] = arrgs.detail;
    const tier = frontmatter[fmKeyType][index]["candidates"].filter((t) => t.file == value);
    if (tier.length > 0) {
      frontmatter[fmKeyType][index]["tiers"] = [...frontmatter[fmKeyType][index]["tiers"], tier[0]];
      frontmatter[fmKeyType][index]["candidates"] = frontmatter[fmKeyType][index]["candidates"].filter(
        (t) => t != tier[0]
      );
    }
  }

  function fmItemDottedBorder(e) {
    e.target.parentNode.parentNode.style.border = "2px #ff000075 dotted";
  }

  function fmItemNoBorder(e) {
    e.target.parentNode.parentNode.style.border = "0px";
  }

  function removeTier(fmKey, fmValue) {
    frontmatter[fmKey] = frontmatter[fmKey].filter((v) => v["fmKey"] != fmValue["fmKey"]);
    toggleNewTiersButtons();
  }

  function toggleFold() {
    let e = document.getElementById("frontmatter");
    if (e && e.classList.contains("fmHidden")) {
      e.classList.remove("fmHidden");
      e.classList.add("fmShown");
    } else if (e && e.classList.contains("fmShown")) {
      e.classList.remove("fmShown");
      e.classList.add("fmHidden");
    }
    let i = document.getElementById("fmicon");
    if (i && i.classList.contains("fmCollapse")) {
      i.classList.remove("fmCollapse");
      i.classList.add("fmExpand");
    } else if (i && i.classList.contains("fmExpand")) {
      i.classList.remove("fmExpand");
      i.classList.add("fmCollapse");
    }
  }

  function toggleNewTiersButtons() {
    hasesCandidates = [...new Set(reckonHasesCandidates())];

    if (hasesCandidates.length == 0) {
      document.querySelectorAll(".newtiers").forEach((button) => {
        button.style.display = "none";
      });
      let newtierstitle = document.getElementById("newtierstitle");
      if (newtierstitle) {
        newtierstitle.style.display = "none";
      }
    } else {
      document.querySelectorAll(".newtiers").forEach((button) => {
        button.style.display = "block";
      });
      let newtierstitle = document.getElementById("newtierstitle");
      if (newtierstitle) {
        newtierstitle.style.display = "block";
      }
    }

    const ct = Object.entries(frontmatter).filter((i) => i[1].length == 0 && i[0] == "triad")[0];
    if (!ct) {
      document.getElementById("newtriad").style.display = "none";
    }
  }

  function dispatchHash() {
    const searchParams = new URLSearchParams(location.search);
    const editHash = searchParams.get("edit");
    if (editHash) {
      loadHugoPageMetadata(editHash);
    } else {
      let newPage = searchParams.get("new");
      console.log({ newPage });
    }
  }

  onMount(() => {
    dispatchHash();
    // loadHugoPageMetadata();
    console.dir({ frontmatter });
  });

  $: hashChanged = () => dispatchHash();
</script>

<svelte:window on:keyup={keyUp} on:hashchange={hashChanged} />
<main id="sandpoints">
  <form>
    <div class="formgrid">
      <SpTitle {relpath} {title} />
    </div>
    <div id="fmicon" on:click={toggleFold} class="fmCollapse">Frontmatter</div>
    <span id="frontmatter" class="fmHidden">
      {#each Object.entries(frontmatter) as fmItems}
        {#each fmItems[1] as fmItem, i}
          {#if ["ascription", "triad"].includes(fmItems[0])}
            <div class="fmMeta">
              <div class="fmMetaTitle">
                {fmItems[0]}<button
                  type="button"
                  on:click={() => removeTier(fmItems[0], fmItem)}
                  on:mouseover={fmItemDottedBorder}
                  on:mouseout={fmItemNoBorder}>×</button
                >
              </div>
              <div class="fmItem">
                <SpKeys
                  index={i}
                  fmKeyType={fmItems[0]}
                  {fmItem}
                  {hases}
                  {hasesCandidates}
                  on:hasTiersSelected={newTier}
                />
                <SpTiers
                  on:addToCandidatesRemoveFromTiers={addToCandidatesRemoveFromTiers}
                  index={i}
                  fmKeyType={fmItems[0]}
                  {fmItem}
                />
                <SpCandidates
                  on:addToTiersRemoveFromCandidates={addToTiersRemoveFromCandidates}
                  index={i}
                  fmKeyType={fmItems[0]}
                  {fmItem}
                />
              </div>
            </div>
          {:else if fmItems[0] == "journal"}
            <div class="fmMeta">
              <div class="fmMetaTitle">
                {fmItems[0]}<button
                  type="button"
                  on:click={() => removeTier(fmItems[0], fmItem)}
                  on:mouseover={fmItemDottedBorder}
                  on:mouseout={fmItemNoBorder}>×</button
                >
              </div>
              <div class="fmItem">
                <SpJournal {fmItem} />
              </div>
            </div>
          {:else if fmItems[0] == "notsand"}
            <div class="fmMeta">
              <div class="fmMetaTitle">
                Not Sandpoints<button
                  type="button"
                  on:click={() => removeTier(fmItems[0], fmItem)}
                  on:mouseover={fmItemDottedBorder}
                  on:mouseout={fmItemNoBorder}>×</button
                >
              </div>
              <div class="fmItem">
                <SpNotsand {fmItem}/>
              </div>
            </div>
          {/if}
        {/each}
      {/each}
      <div class="newtiersbar">
        <div id="newtierstitle">Add new:</div>
        <div id="newtriad" class="newtiers newtierbutton" on:click={() => newTier("triad", "_new", null)}>
          TRIAD TIER
        </div>
        <div
          id="newascription"
          class="newtiers newtierbutton"
          on:click={() => newTier("ascription", "_new", null)}
        >
          ASCRIPTION
        </div>
        <div
          id="newfmitem"
          class="newtiers newtierbutton"
          on:click={() => newFmItem("notsand", "_new", null)}
        >
          MISC
        </div>
      </div>
    </span>
    <div class="formgrid">
      <label for="pagecontent">Content:</label>
      <textarea
        id="pagecontent"
        bind:value={v}
        oninput="this.style.height = '';this.style.height = this.scrollHeight + 3 + 'px'"
      />
      {#if document.location.protocol.substring(0, 4) != "file"}
        <label for="publish">Publish</label>
        <input type="checkbox" id="publish" name="publish" />
      {/if}
      <label for="offline">Offline</label>
      <input type="checkbox" id="offline" name="offline" />
      <input type="hidden" name="relpermalink" bind:value={relpermalink} />
      <input type="hidden" name="relpath" bind:value={relpath} />
      <input type="hidden" name="protocol" bind:value={protocol} />
      <button id="sandpointsButton">COMMIT/SAVE</button>
    </div>
  </form>
</main>
