<template>
  <dashboard-page :loading="loading" :title="title">
    <template #actions>
      <factor-link btn="default" :path="url">View</factor-link>
      <dashboard-btn btn="primary" :loading="sending" @click="savePost()">Update</dashboard-btn>
    </template>
    <template #primary>
      <dashboard-panel class="compose">
        <dashboard-input
          v-model="post.title"
          input="factor-input-text"
          label="Title"
          class="post-title"
          @keyup="doDraftSave()"
        />

        <dashboard-input label="Post Content">
          <factor-input-editor v-model="post.content" :autosave-id="post._id" />
        </dashboard-input>
      </dashboard-panel>
    </template>
    <template #meta>
      <dashboard-panel class="post-media">
        <dashboard-input
          v-model="post.status"
          label="Status"
          :list="['published', 'draft', 'trash']"
          input="factor-input-select"
        />

        <dashboard-input v-if="postTypeConfig.customPermalink" label="Permalink">
          <input-permalink v-model="post.permalink" :post-id="post._id" :post-type="postType" />
        </dashboard-input>
        <dashboard-input
          v-model="post.synopsis"
          input="factor-input-text"
          label="Synopsis"
          description="A short description or teaser"
          class="post-title"
          @keyup="doDraftSave()"
        />
        <vue-client-only>
          <dashboard-input v-model="post.date" input="factor-input-date" label="Date" />
        </vue-client-only>
        <dashboard-input label="Tags">
          <factor-input-tags v-model="post.tag" />
        </dashboard-input>
        <dashboard-input
          v-if="postTypeConfig.categories && postTypeConfig.categories.length > 0"
          label="Category"
        >
          <factor-input-tags v-model="post.category" :list="postTypeConfig.categories" />
        </dashboard-input>
        <dashboard-input
          v-model="post.avatar"
          input="factor-input-image-upload"
          label="Avatar / Primary"
          max="1"
          @autosave="saveDraft()"
        />
        <dashboard-input
          v-model="post.images"
          selector="post-images"
          input="factor-input-image-upload"
          label="Post Images"
          @autosave="saveDraft()"
        />
        <dashboard-input v-model="post.author" input="dashboard-user-list" label="Author" />
        <dashboard-input
          v-model="post.source"
          input="factor-input-text"
          label="Source"
          description="Used when sharing DB in multiple apps"
        />
      </dashboard-panel>
      <slot name="meta" />
    </template>
    <template #secondary>
      <slot name="edit" />
    </template>
  </dashboard-page>
</template>
<script lang="ts">
import {
  dashboardBtn,
  factorLink,
  factorInputTags,
  factorInputEditor,
  dashboardPage,
  dashboardPanel,
  dashboardInput,
} from "@factor/ui"
import {
  isEmpty,
  toLabel,
  emitEvent,
  stored,
  timeUtil,
  storeItem,
  getPostTypeConfig,
  PostTypeConfig,
} from "@factor/api"
import { excerpt } from "@factor/api/excerpt"
import { requestPostSave } from "@factor/post/request"

import { FactorPost } from "@factor/post/types"
export default {
  components: {
    dashboardInput,
    dashboardPage,
    dashboardPanel,
    dashboardBtn,
    factorLink,
    factorInputTags,
    factorInputEditor,
    vueClientOnly: () => import("vue-client-only"),
    inputPermalink: () => import("../el/permalink.vue"),
  },

  data() {
    return {
      sending: false,
      sendingDraft: false,
      loading: false,
      isNew: null,
      saveNeeded: false,
      willsave: null,
      settings: [],
      reactivePost: {},
    }
  },
  metaInfo(): Record<string, any> {
    return {
      title: this.title,
    }
  },
  computed: {
    post: {
      get(this: any): FactorPost {
        return stored(this._id) || {}
      },
      set(this: any, v: FactorPost): void {
        storeItem(this._id, v)
      },
    },

    test(this: any) {
      return this.post.title
    },

    _id(this: any): string {
      return this.$route.query._id || ""
    },

    excerpt(this: any) {
      return excerpt(this.post.content)
    },
    postTypeConfig(this: any): PostTypeConfig | Record<string, any> {
      return getPostTypeConfig(this.postType) || {}
    },
    title(this: any) {
      const mode = this.isNew ? "Add New" : "Edit"
      const name = this.postTypeConfig.nameSingle || toLabel(this.postType)
      return `${mode} ${name}`
    },

    postType(this: any) {
      return this.$route.params.postType || this.post.postType || "page"
    },
    url(this: any) {
      return this.postTypeConfig.permalink(this.post)
    },

    lastRevision(this: any) {
      return this.post.revisions && this.post.revisions.length > 0
        ? this.post.revisions[0]
        : {}
    },
    canRevert(this: any) {
      if (
        !this.lastRevision.published &&
        this.post.revisions &&
        this.post.revisions.length > 0 &&
        this.post.revisions.some((_) => _.published)
      ) {
        return true
      } else {
        return false
      }
    },
  },

  methods: {
    isEmpty,
    timeUtil,
    async savePost(this: any) {
      this.sending = true

      this.clearAutosave()

      emitEvent("save-post")

      let saved
      try {
        saved = await requestPostSave({
          post: this.post,
          postType: this.postType,
        })
      } catch {
        this.sending = false
      }

      if (saved) {
        this.post = saved
        emitEvent("notify", `Saved!`)
      }

      this.sending = false
    },

    doDraftSave(this: any) {
      if (!this.willsave) {
        this.willsave = setTimeout(() => {
          this.saveDraft()
        }, 30000)
      }
    },

    clearAutosave(this: any) {
      clearTimeout(this.willsave)
      this.willsave = null
    },

    async saveDraft(this: any) {
      this.sendingDraft = true

      this.sendingDraft = false
    },
  },
}
</script>
<style lang="less">
.post-grid {
  display: grid;

  @media (max-width: 960px) {
    grid-gap: 1em 0;
  }

  .content-column,
  .meta-column {
    min-width: 0;
    @media (max-width: 960px) {
      grid-column: span 3;
    }
  }
  .meta-column {
    .post-actions {
      top: 20px;
      position: sticky;
      @media (max-width: 767px) {
        .foot {
          position: fixed;
          bottom: 0;
          top: auto;
          width: 100%;
          left: 0;
        }
      }
    }
  }

  .save-info {
    line-height: 1.5;
    font-size: 12px;
    opacity: 0.4;
    .draft-actions {
      display: flex;
      justify-content: space-between;
      padding: 8px 0;
      .el-tag {
        margin-right: 8px;
      }
    }

    .unpublished {
      font-weight: var(--font-weight-bold);
    }
    .revert {
      cursor: pointer;
    }
  }
  .post-title input[type="text"] {
    width: 100%;
    font-size: 1.2em;
  }

  .post-actions .foot .actions {
    width: 100%;
    display: flex;
    justify-content: space-between;
    align-items: center;
    .trash {
      font-size: 0.9em;
      font-weight: 500;
    }
  }
}
</style>
