<script setup lang="ts">
import { computed, onMounted, ref } from 'vue';

const title = ref('');
const content = ref('');
const timestamp = ref('');
//const editedTimestamp = ref('');
const draft = ref(false);

const generateTimestamp = (): string => {
  return Math.round((new Date()).getTime() / 1000).toString();
}

const parseTimestamp = (unixTimestamp: string): string => {
  if (!unixTimestamp) {
    return ''
  }

  return new Date(Number(unixTimestamp) * 1000).toUTCString();
}

const parseFilename = (titleToFilename: string): string => {
  if (!titleToFilename) {
    return 'None yet.'
  }

  titleToFilename = titleToFilename.replace(/[^a-zA-Z0-9_]+/gi, '-').toLowerCase();

  while (titleToFilename.endsWith('-')) {
    titleToFilename = titleToFilename.slice(0, -1);
  }

  if (titleToFilename.length > 50) { // Limit filename size
    titleToFilename = titleToFilename.substring(0, 50);

    if (titleToFilename.includes('-')) {
      titleToFilename = titleToFilename.substring(0, Math.min(titleToFilename.length, titleToFilename.lastIndexOf('-'))); // Re-trim to avoid cutting a word in half.
    }
  }

  return titleToFilename + '.json';
}

const generatePostObj = (isDraft?: boolean): Object => {
  return {
    postTitle: title.value,
    timestamp: isDraft ? '' : timestamp.value,
    //editedTimestamp: isDraft ? '' : editedTimestamp.value,
    postContent: content.value,
    filename: computedFilename.value,
    draft: draft.value
  }
}

const downloadFile = (isDraft?: boolean, archiveFile?: boolean): void => {
  const blob = new Blob([JSON.stringify(generatePostObj(isDraft), null, 2)], { type: 'text/plain' });
  const a = document.createElement('a');
  a.setAttribute('download', archiveFile ? 'archive.json' : computedFilename.value);
  a.setAttribute('href', window.URL.createObjectURL(blob));
  a.click();
}

const savePost = (): void => {
  if (!title.value) {
    title.value = 'No title.';
  }

  if (!content.value) {
    content.value = 'No content.';
  }

  if (draft.value) { // Save post as draft (no timestamps)
    downloadFile(true);
  } else { // Save post for publishing

    // Reminder for when we have an editedTimestamp. Requires way more than this and I have no patience right now.
    // if (timestamp.value) {
    //   editedTimestamp.value = generateTimestamp();
    // }

    downloadFile();

    // Reminder when we get to the point of saving archives.
    //saveAs(new Blob([JSON.stringify(this.archives, null, 2)], { type: 'text/plain;charset=utf-8;' }), 'archive.json');
  }
}

onMounted(() => {
  // Refactor this later when we have an editedTimestamp.
  setInterval(() => {
    timestamp.value = generateTimestamp();
  }, 1000)
});

const computedFilename = computed(() => parseFilename(title.value))
const computedTimestamp = computed(() => parseTimestamp(timestamp.value));
// const computedEditedTimestamp = computed(() => parseTimestamp(timestamp.value));

</script>

<template>
  <div class="wrapper">
    <div class="editor-area">
      <div class="title-area">
        <input class="title" type="text" placeholder="Post title..." v-model="title" />
        <input type="checkbox" id="draft" v-model="draft" /><label for="draft">Draft</label>
      </div>
      <br>
      <textarea class="editor" v-model="content" placeholder="Post content..." />
    </div>
    <div class="preview">
      <p class="preview-title">&nbsp; Preview: </p>
      <VueShowdown v-bind:markdown="content" flavor="github" :options="{ emoji: true }" tag="span" />
    </div>
  </div>
  <div class="footer">
    Filename: {{ computedFilename }} <br />
    Created on Timestamp: {{ computedTimestamp }} <br />
    <!-- Edited on Timestamp: {{ computedEditedTimestamp }} <br /> -->
    Is it a draft? {{ draft ? 'Yes' : 'No' }}. <br />
    <button class="btn-primary" @click="savePost">Save (ngx-retroblog format)</button>
  </div>
</template>

<style>
#app {
  font-family: Avenir, Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  color: #2c3e50;
}

button {
  cursor: pointer;
  transition: all 0.3s ease-in-out;
  text-decoration: none;
  padding: 0.6rem;
  border: none;
  box-shadow: #000a 4px 4px;
}

.btn-primary {
  background-color: rgb(97, 0, 162);
  color: white;
  font-size: .8rem;
}

.btn-primary:hover {
  box-shadow: 0px 0px 7px rgb(97, 0, 162);
}

.wrapper {
  display: flex;
  grid-gap: 1rem;
  flex-direction: row;
  justify-content: center;
  width: 100%;
  height: 85vh;
  position: relative;
}

.editor-area {
  text-align: left;
  flex: 1;
}

.title-area {
  display: flex;
}

.title {
  flex: 1;
}

.editor {
  resize: none;
  width: -webkit-fill-available;
  height: 90%;
}

.preview {
  max-width: 50vw;
  flex: 1;
  border: 1px solid #969696;
  max-height: 96.8%;
  overflow-y: auto;
}

.preview-title {
  margin-top: 0;
}

.preview>* {
  max-width: 50vw;
  line-break: normal;
}

@media only screen and (hover: none) {
  .wrapper {
    flex-direction: column;
  }

  .preview {
    max-width: 100vw;
    margin-top: 1rem;
  }
}
</style>
