let flashActive = false;
const flashTypes = [ "error", "success", "warn" ];

const flash = ({ type, msg }) => {
  let flashContainer;
  if(tmp = document.querySelector("div#flash"))
    flashContainer = tmp;
  else {
    flashContainer = document.createElement("div");
    flashContainer.id = "flash";
    document.body.insertAdjacentElement("afterbegin", flashContainer);
  }

  flashContainer.innerHTML = msg;
  if(flashTypes.includes(type)) {
    flashContainer.className = "";
    flashContainer.classList.add(type);
  }
  if(flashActive)
    return false;

  flashActive = true;
  flashContainer.animate(
    [ { bottom: "-28px" }, { bottom: 0 } ], {
      duration: 500,
      fill: "both"
    }
  ).onfinish = () => setTimeout(() => {
    flashContainer.animate(
      [ { bottom: 0 }, { bottom: "-28px" } ], {
        duration: 500,
        fill: "both"
      }
    ).onfinish = () => flashActive = false;
  }, 4 * 1e3);
  return true;
};

(async () => {
  if(_addtag = document.querySelector("a#a_addtag")) {
    const postid = +document.querySelector("a.id-link").innerText;
    const poster = document.querySelector("a#a_username").innerText;
    let tags = [...document.querySelectorAll("#tags > .badge")].map(t => t.innerText.slice(0, -2));

    const deleteEvent = async e => {
      e.preventDefault();
      if(!confirm("Do you really want to delete this tag?"))
        return;
      const tagname = e.target.parentElement.querySelector('a:first-child').innerText;

      const res = await (await fetch("/api/v2/admin/" + postid + "/tags/" + encodeURIComponent(tagname), {
        method: 'DELETE'
      })).json();

      if(!res.success)
        return alert("uff");
      tags = res.tags.map(t => t.tag);
      renderTags(res.tags);
    };

    const queryapi = async (url, data, method = 'GET') => {
      let req;
      if(method == 'POST') {
        req = await fetch(url, {
          method: "POST",
          headers: {
            "Content-Type": "application/json"
          },
          body: JSON.stringify(data)
        });
      }
      else {
        let s = [];
        for(const [ key, val ] of Object.entries(data))
          s.push(encodeURIComponent(key) + "=" + encodeURIComponent(val));
        req = await fetch(url + '?' + s.join('&'));
      }
      return await req.json();
    };

    const get  = async (url, data) => queryapi(url, data, 'GET');
    const post = async (url, data) => queryapi(url, data, 'POST');

    const renderTags = _tags => {
      [...document.querySelectorAll("#tags > .badge")].forEach(tag => tag.parentElement.removeChild(tag));
      _tags.reverse().forEach(tag => {
        const a = document.createElement("a");
        a.href = `/tag/${tag.normalized}`;
        a.style = "color: inherit !important";
        a.innerHTML = tag.tag;
        a.addEventListener("click", editTagEvent); // tmp

        const span = document.createElement("span");
        span.classList.add("badge", "mr-2");
        span.setAttribute('tooltip', tag.user);

        tag.badge.split(" ").forEach(b => span.classList.add(b));

        const delbutton = document.createElement("a");
        delbutton.innerHTML = " ×";
        delbutton.href = "#";
        delbutton.addEventListener("click", deleteEvent);
        span.insertAdjacentElement("beforeend", a);
        span.innerHTML += ' ';
        span.insertAdjacentElement("beforeend", delbutton);
  
        document.querySelector("#tags").insertAdjacentElement("afterbegin", span);
      });
    };

    const addtagClick = (ae = false) => {
      if(ae)
        ae.preventDefault();

      const insert = document.querySelector("a#a_addtag");
      const span = document.createElement("span");
      span.classList.add("badge", "badge-light", "mr-2");

      const input = document.createElement("input");
      input.size = "10";
      input.value = "";
      input.setAttribute("list", "testlist");
      input.setAttribute("autoComplete", "off");

      span.insertAdjacentElement("afterbegin", input);
      insert.insertAdjacentElement("beforebegin", span);

      input.focus();

      let tt = null;
      let lastInput = '';
      const testList = document.querySelector('#testlist');

      input.addEventListener("keyup", async e => {
        if(e.key === "Enter") {
          const tmptag = input.value?.trim();
          if(tags.includes(tmptag))
            return alert("tag already exists");
          const res = await post("/api/v2/admin/" + postid + "/tags", {
            tagname: tmptag
          });
          if(!res.success) {
            return flash({
              type: "error",
              msg: res.msg
            });
          }
          tags = res.tags.map(t => t.tag);
          renderTags(res.tags);
          addtagClick();
          testList.innerText = "";
        }
        else if(e.key === "Escape") {
          span.parentElement.removeChild(span);
          testList.innerText = "";
        }
        else {
          if(tt != null)
            clearTimeout(tt);

          tt = setTimeout(async () => {
            tt = null;  

            const tmptag = input.value?.trim();

            if(tmptag == lastInput || tmptag.length <= 1)
              return false;

            testList.innerText = "";
            lastInput = tmptag;
  
            const res = await get('/api/v2/admin/tags/suggest', {
              q: tmptag
            });
  
            for(const entry of res.suggestions) {
              const option = document.createElement('option');
              option.value = entry.tag;

              if(!/fox/.test(navigator.userAgent))
                option.innerText = `tagged ${entry.tagged} times (score: ${entry.score.toFixed(2)})`;

              testList.insertAdjacentElement('beforeEnd', option);
            };
          }, 500);
        }
        return true;
      });

      input.addEventListener("focusout", ie => {
        if(input.value.length === 0)
          input.parentElement.parentElement.removeChild(input.parentElement);
      });
    };

    const toggleEvent = async (e = false) => {
      if(e)
        e.preventDefault();

      const res = await (await fetch('/api/v2/admin/' + encodeURIComponent(postid) + '/tags/toggle', {
        method: 'PUT'
      })).json();

      renderTags(res.tags);
      tags = res.tags.map(t => t.tag);

      flash({
        type: "success",
        msg: tags.join()
      });
    };

    const deleteButtonEvent = async e => {
      if(e)
        e.preventDefault();
      if(!confirm(`Reason for deleting f0ckpost ${postid} by ${poster} (Weihnachten™)`))
        return;
      const res = await post("/api/v2/admin/deletepost", {
        postid: postid
      });
      if(res.success) {
        flash({
          type: "success",
          msg: "post was successfully deleted"
        });
      }
      else {
        flash({
          type: "error",
          msg: res.msg
        });
      }
    };

    const toggleFavEvent = async e => {
      const res = await post('/api/v2/admin/togglefav', {
        postid: postid
      });
      if(res.success) {
        const fav = document.querySelector("svg#a_favo > use").href;
        fav.baseVal = '/s/img/iconset.svg#heart_' + (fav.baseVal.match(/heart_(regular|solid)$/)[1] == "solid" ? "regular" : "solid");

        // span#favs
        const favcontainer = document.querySelector('span#favs');
        favcontainer.innerHTML = "";

        favcontainer.hidden = !(favcontainer.hidden || res.favs.length > 0);

        res.favs.forEach(f => {
          const a = document.createElement('a');
          a.href = `/user/${f.user}/favs`;
          a.setAttribute('tooltip', f.user);
          a.setAttribute('flow', 'up');

          const img = document.createElement('img');
          img.src = `/t/${f.avatar}.webp`;
          img.style.height = "32px";
          img.style.width = "32px";

          a.insertAdjacentElement('beforeend', img);
          favcontainer.insertAdjacentElement('beforeend', a);
          favcontainer.innerHTML += "&nbsp;";
        });
      }
      else {
        // lul
      }
    };

    let tmptt = null;
    const editTagEvent = async e => { // mousedown
      e.preventDefault();

      if(e.detail === 2) {
        clearTimeout(tmptt);
        const old = e.target;
        const parent = e.target.parentElement;
        const oldtag = e.target.innerText;

        const textfield = document.createElement('input');
        textfield.value = e.target.innerText;
        textfield.size = 10;

        parent.insertAdjacentElement('afterbegin', textfield);
        textfield.focus();
        parent.removeChild(e.target);
        parent.querySelector('a:last-child').style.display = 'none';

        textfield.addEventListener("keyup", async e => {
          if(e.key === 'Enter') {
            parent.removeChild(textfield);
            // send
            let res = await fetch('/api/v2/admin/tags/' + encodeURIComponent(oldtag), {
              method: 'PUT',
              headers: {
                "Content-Type": "application/json"
              },
              body: JSON.stringify({
                newtag: textfield.value
              })
            });
            const status = res.status;
            res = await res.json();

            switch(status) {
              case 200: // success, change
              case 201:
                //parent.removeChild(textfield);
                parent.insertAdjacentElement('afterbegin', old);
                parent.querySelector('a:last-child').style.display = '';
                old.href = `/tag/${res.tag}`;
                old.innerText = res.tag.trim();
              break;
              default:
                console.log(res);
              break;
            }
          }
          else if(e.key === 'Escape') {
            parent.removeChild(textfield);
            parent.insertAdjacentElement('afterbegin', old);
            parent.querySelector('a:last-child').style.display = '';
          }
        });
      }
      else
        tmptt = setTimeout(() => location.href = e.target.href, 250);

      return false;
    };

    _addtag.addEventListener("click", addtagClick);
    document.querySelector("a#a_toggle").addEventListener("click", toggleEvent);
    [...document.querySelectorAll("#tags > .badge > a:first-child")].map(t => t.addEventListener("click", editTagEvent));
    [...document.querySelectorAll("#tags > .badge > a:last-child")].map(t => t.addEventListener("click", deleteEvent));
    document.querySelector("svg#a_delete").addEventListener("click", deleteButtonEvent);
    document.querySelector("svg#a_favo").addEventListener("click", toggleFavEvent);

    document.addEventListener("keyup", e => {
      if(e.target.tagName === "INPUT")
        return;
      if(e.key === "p")
        toggleEvent();
      else if(e.key === "i")
        addtagClick();
      else if(e.key === "x")
        deleteButtonEvent();
      else if(e.key === "f")
        toggleFavEvent();
    });
  }

  if(document.location.pathname === '/settings') {
    const saveAvatar = async e => {
      e.preventDefault();

      const avatar = +document.querySelector('input[name="i_avatar"]').value;
      let res = await fetch('/api/v2/settings/setAvatar', {
        method: 'PUT',
        headers: {
          "Content-Type": "application/json"
        },
        body: JSON.stringify({ avatar })
      });
      const code = res.status;
      res = await res.json();

      switch(code) {
        case 200:
          document.querySelector('#img_avatar').src = `/t/${avatar}.webp`;
          document.querySelector('img.avatar').src = `/t/${avatar}.webp`;
        break;
        default:
          console.log(res);
        break;
      }
    };

    document.querySelector('input#s_avatar').addEventListener('click', saveAvatar);
    document.querySelector('input[name="i_avatar"]').addEventListener('keyup', async e => {
      if(e.key === 'Enter')
        await saveAvatar(e);
    });
  }
})();