<script setup lang="ts">
import axios from "axios";
import { MdCatalog, MdEditor, MdPreview, NormalToolbar } from "md-editor-v3";
import "md-editor-v3/lib/preview.css";
import "md-editor-v3/lib/style.css";
import { useNotes } from "@/pages/notes/store.ts";
import { useRoute } from "vue-router";
import { useRequest } from "vue-request";
import { myRequest } from "@/requests/request.ts";
import { userinfo } from "@/store/store.ts";
import { onMounted, watch } from "vue";
import _ from "lodash";
import { ElMessage } from "element-plus";
import { formatError } from "@/utils/utils.ts";
import router from "@/router/router.ts";
import YlActionDiv from "@/components/yl-action-div.vue";

let scrollElement = document.getElementsByClassName("yl-editor-preview")[0];
const route = useRoute();

const {
  data: note,
  loading,
  run,
} = useRequest(() =>
  myRequest(`/api/notes/${route.params.id}`, userinfo.token),
);

const { runAsync: save } = useRequest(
  () =>
    myRequest(
      `/api/notes/${route.params.id}`,
      userinfo.token,
      { id: Number(route.params.id), content: useNotes.content },
      "put",
    ),
  { manual: true },
);

const toSave = () => {
  save()
    .then(() => {
      useNotes.preview = true;
      run();
    })
    .catch((res) => ElMessage.error(formatError(res)));
};

const onUploadImg = async (files: File[], callback: (r: string[]) => void) => {
  const res = (await Promise.all(
    files.map((file) => {
      return new Promise((rev, rej) => {
        const form = new FormData();
        form.append("file", file);
        axios
          .post(`/api/notes/${route.params.id}/file`, form, {
            headers: {
              "Content-Type": "multipart/form-data",
              Authorization: `Bearer ${userinfo.token}`,
            },
          })
          .then((res) => {
            rev(res.data.data);
          })
          .catch((error) => rej(error));
      });
    }),
  )) as string[];

  callback(res);
};

onMounted(() => {
  scrollElement = document.getElementsByClassName("yl-editor-preview")[0];
});

watch(note, () => {
  useNotes.content = _.get(note.value, "data.content", "");
});
</script>

<template>
  <div v-if="useNotes.preview">
    <yl-action-div>
      <el-button link @click="router.push('/notes')">返回</el-button>
    </yl-action-div>
  </div>
  <div
    class="yl-editor-preview"
    v-if="useNotes.preview"
    v-loading="loading"
    @dblclick="() => (useNotes.preview = false)"
  >
    <MdPreview :editor-id="useNotes.id" :model-value="useNotes.content" />
    <MdCatalog
      :editor-id="useNotes.id"
      :scroll-element="scrollElement as HTMLElement"
    />
  </div>
  <MdEditor
    :editor-id="useNotes.id"
    v-else
    v-loading="loading"
    auto-focus
    v-model="useNotes.content"
    @onUploadImg="onUploadImg"
    @onSave="toSave"
    style="height: 100%"
    :toolbars="useNotes.toolbars"
    ><template #defToolbars>
      <normal-toolbar title="退出" @on-click="() => (useNotes.preview = true)">
        <template #trigger>
          <el-icon
            class="md-editor-icon"
            aria-hidden="true"
            style="padding: 4px"
          >
            <i class="bi-box-arrow-right" />
          </el-icon>
        </template>
      </normal-toolbar> </template
  ></MdEditor>
</template>

<style scoped>
.yl-editor-preview {
  display: flex;
  height: calc(100% - 55px);
  .md-editor-catalog {
    width: 20%;
    padding: 1rem;
  }
}
</style>
