<template>
  <div>
    <div class="is-hidden">
      <img
        id="image"
        :src="image"
      />
    </div>
    <div class="field is-grouped is-grouped-multiline">
      <div class="control">
        <div class="file is-primary">
          <label class="file-label">
            <button :class="['button is-primary is-small', loading && 'is-loading']">
              <span class="icon">
                <Icon
                  name="material-symbols:upload-rounded"
                  :size="18"
                />
              </span>
              <span>Tải lên từ máy tính</span>
            </button>
            <input
              type="file"
              @change="doChange"
              multiple
              name="resume"
              class="file-input is-clickable"
              :id="docid"
            />
          </label>
        </div>
      </div>
      <div :class="['control', !showUrl && 'is-expanded']">
        <button
          class="button is-small"
          @click="displayInput"
        >
          <span class="icon">
            <Icon
              name="material-symbols:link-rounded"
              :size="18"
            />
          </span>
          <span>Tải lên từ đường dẫn</span>
        </button>
      </div>
      <div
        v-if="showUrl"
        class="field has-addons is-flex-grow-1 mb-0"
      >
        <div class="control">
          <input
            class="input is-small w-60"
            id="url"
            v-model.trim="url"
            type="text"
            placeholder="Nhập đường dẫn"
          />
        </div>
        <div class="control">
          <button
            class="button is-light is-small rounded-full"
            @click="showUrl = false"
          >
            <span class="icon">
              <Icon
                name="material-symbols:close-rounded"
                :size="18"
              />
            </span>
          </button>
        </div>
        <div class="control">
          <button
            class="button is-primary is-small"
            :disabled="!url"
            @click="checkUrl"
          >
            <span class="icon">
              <Icon
                name="material-symbols:arrow-forward-rounded"
                :size="20"
              />
            </span>
          </button>
        </div>
      </div>
      <div class="control has-icons-left">
        <input
          v-model="search"
          type="text"
          @keyup="beginSearch"
          class="input is-small is-rounded w-2xs"
          placeholder="Tìm kiếm"
        />
        <span
          class="icon is-small is-left"
          style="left: 2px"
        >
          <Icon
            name="material-symbols:search"
            :size="18"
          />
        </span>
      </div>
      <div class="tabs is-toggle m-0">
        <ul class="is-flex-grow-0 ml-auto">
          <li
            v-for="viewMode in viewModes"
            :key="viewMode.name"
            :class="[viewMode.name === mode && 'is-active']"
            @click="mode = viewMode.name"
          >
            <a class="px-3 py-1">
              <span class="icon m-0">
                <Icon
                  :name="viewMode.icon"
                  :size="18"
                />
              </span>
            </a>
          </li>
        </ul>
      </div>
    </div>
    <DataView
      v-if="mode === 'list'"
      v-bind="vbind"
      class="mt-3"
    />
    <div v-else>
      <div
        class="fixed-grid has-5-cols"
        v-for="(_, i) in group"
        :key="i"
      >
        <div class="grid">
          <div
            v-for="(k, j) in getData(i)"
            :key="j"
            @mouseover="focus = k"
            @mouseleave="focus = undefined"
            class="cell relative rounded-md is-clipped"
          >
            <figure
              v-if="k.file && type === 'image'"
              class="image is-square mx-auto is-flex is-align-items-center"
            >
              <NuxtImg
                :src="`${path}download?name=${k.file}`"
                :id="'commentImage' + k.id"
              />
            </figure>
            <div
              class="ml-2 mr-2"
              v-else-if="k.file && type === 'video'"
            >
              <vue-plyr>
                <video :src="path + 'static/videos/' + k.file">
                  <source
                    :src="path + 'static/videos/' + k.file"
                    type="video/mp4"
                    size="720"
                  />
                </video>
                <div
                  class="mt-2"
                  v-if="focus === k"
                >
                  <button
                    class="button is-primary"
                    @click="selectMedia(k)"
                  >
                    <span class="icon">
                      <Icon
                        name="material-symbols:check-rounded"
                        :size="18"
                      />
                    </span>
                  </button>
                </div>
              </vue-plyr>
            </div>
            <div
              class="ml-2 mr-2"
              v-else-if="k.file && type === 'file'"
            >
              {{ k.file }}
              <div
                class="mt-2"
                v-if="focus === k"
              >
                <button
                  class="button is-primary"
                  @click="selectMedia(k)"
                >
                  <span class="icon">
                    <Icon
                      name="material-symbols:check-rounded"
                      :size="18"
                    />
                  </span>
                </button>
              </div>
            </div>
            <div
              v-if="focus === k"
              class="absolute top-0 size-full"
            >
              <div class="size-full has-background-black opacity-15"></div>
              <div class="buttons has-addons absolute left-0 right-0 bottom-2 mx-auto w-fit">
                <button
                  class="button is-small is-white"
                  @click="selectMedia(k)"
                >
                  <span class="icon">
                    <Icon
                      name="material-symbols:check-rounded"
                      :size="18"
                    />
                  </span>
                </button>
                <button
                  class="button is-small is-white"
                  @click="editImage(k)"
                >
                  <span class="icon">
                    <Icon
                      name="material-symbols:crop-free-rounded"
                      :size="18"
                    />
                  </span>
                </button>
                <button
                  class="button is-small is-white"
                  @click="copyMedia(k)"
                >
                  <span class="icon">
                    <Icon
                      name="material-symbols:content-copy-outline-rounded"
                      :size="18"
                    />
                  </span>
                </button>
                <button
                  class="button is-small is-white"
                  @click="deleteMedia(k, 'file')"
                >
                  <span class="icon">
                    <Icon
                      name="material-symbols:delete-outline-rounded"
                      :size="18"
                      class="has-text-danger"
                    />
                  </span>
                </button>
              </div>
            </div>
          </div>
        </div>
      </div>
    </div>
    <Modal
      v-if="showmodal"
      v-bind="showmodal"
      @close="showmodal = undefined"
      @image="updateImage"
      @files="getFiles"
    />
  </div>
</template>
<script>
import DataView from "~/components/datatable/DataView.vue";

export default {
  props: ["source"],
  data() {
    return {
      file: undefined,
      image: undefined,
      showmodal: undefined,
      data: [],
      group: [],
      focus: undefined,
      type: "image",
      selected: undefined,
      loading: false,
      path: this.$getpath(),
      showUrl: false,
      url: undefined,
      search: undefined,
      mode: "image",
      viewModes: [
        { name: "list", icon: "material-symbols:format-list-bulleted-rounded" },
        { name: "image", icon: "material-symbols:grid-view-outline-rounded" },
      ],
      timer: undefined,
      vbind: { api: "file", setting: "image-fields", pagename: "image-fields" },
      dataFiles: [],
      files: [],
      docid: this.$id(),
    };
  },
  async created() {
    const fileApi = this.$findapi("file");
    fileApi.params = {
      sort: "-create_time",
      filter: {
        user: this.login.id,
        type__code: this.type,
      },
    };
    const result = await this.$getapi([fileApi]);
    this.data = result[0].data.rows;
  },
  watch: {
    data() {
      this.group = [];
      for (let index = 0; index < this.data.length / (this.type === "video" ? 4 : 5); index++) {
        this.group.push(index);
      }
    },
  },
  computed: {
    login: {
      get() {
        return this.$store.login;
      },
      set(val) {
        this.$store.commit("updateLogin", { login: val });
      },
    },
    media: {
      get() {
        return this.$store.media;
      },
      set(val) {
        this.$store.commit("updateMedia", { media: val });
      },
    },
  },
  methods: {
    doChange() {
      this.dataFiles = [];
      let fileList = document.getElementById(this.docid).files;
      this.files = Array.from(fileList);
      if (this.files.length === 0) return;
      this.files.map((v) => {
        let file = this.$upload(v, this.vtype, this.$store.login.id);
        this.dataFiles.push(file);
      });
      this.showmodal = {
        component: "media/UploadProgress",
        title: "Upload files",
        width: "700px",
        height: "200px",
        vbind: { files: this.dataFiles },
      };
      this.clearFileList();
    },
    clearFileList() {
      const fileInput = document.getElementById(this.docid);
      const dt = new DataTransfer();
      fileInput.files = dt.files;
    },
    getFiles(files) {
      this.data = files.concat(this.data);
      setTimeout(() => (this.showmodal = undefined), 3000);
    },
    beginSearch(e) {
      if (this.timer) clearTimeout(this.timer);
      this.timer = setTimeout(() => this.startSearch(e.target.value), 150);
    },
    async startSearch(value) {
      const filter = { user: this.login.id, type__code: this.type };
      if (!this.$empty(value)) filter.name__icontains = value.toLowerCase();
      this.data = await this.$getdata("file", { filter });
    },
    displayInput() {
      this.showUrl = true;
      this.url = undefined;
      setTimeout(() => document.getElementById("url").focus(), 100);
    },
    async checkUrl() {
      if (this.$empty(this.url)) return this.$snackbar("Đường dẫn không hợp lệ", "Error");

      try {
        const self = this;
        this.loading = true;
        const res = await $fetch(this.url);
        const reader = new window.FileReader();
        reader.onload = (e) => {
          self.image = e.target.result;
          setTimeout(() => self.doUpload(e.target.result), 100);
        };
        reader.readAsDataURL(res);
      } catch (error) {
        this.$snackbar("Đường dẫn không hợp lệ", "Error");
        console.error(error);
      } finally {
        this.loading = false;
      }
    },
    doUpload() {
      const image = document.getElementById("image");
      const canvas = document.createElement("canvas");
      canvas.width = image.width;
      canvas.height = image.height;
      const ctx = canvas.getContext("2d");
      ctx.drawImage(image, 0, 0);
      if (canvas) canvas.toBlob((blod) => this.saveAs(blod));
    },
    async saveAs(blob) {
      const form = new FormData();
      const fileName = this.$dayjs(new Date()).format("YYYYMMDDhhmmss") + "-" + this.$id() + ".png";

      form.append("filename", fileName);
      form.append("name", `${this.$id()}.png`);
      form.append("file", blob);
      form.append("type", "image");
      form.append("size", 100);
      form.append("user", this.$store.login.id);

      const result = await this.$insertapi("upload", { data: form });
      if (result === "error") return;
      this.updateImage(result.rows[0]);
      this.showUrl = false;
    },
    async uploadImage(file) {
      this.loading = true;
      const result = await this.$insertapi("upload", { data: file.form });
      this.data.splice(0, 0, result.rows[0]);
      this.loading = false;
    },
    getData(i) {
      const list = this.data.slice(i * 5, i * 5 + 5);
      for (let index = 0; index < 5; index++) {
        if (list.length < index + 1) list.push({ file: undefined });
      }
      return list;
    },
    async selectMedia(v) {
      const copy = this.media ? this.$copy(this.media) : {};
      copy.type = "image";
      copy.open = false;
      copy.select = v;
      this.media = copy;
      const row = this.$copy(v);

      if (this.source) {
        const res = await $fetch(`${this.path}download/`, {
          params: {
            name: v.file,
            type: "file",
          },
        });

        const reader = new window.FileReader();
        reader.onload = (e) => {
          fetch(e.target.result)
            .then((res) => res.blob())
            .then((blob) => {
              const file = new File([blob], v.name, { type: "image/png" });
              row.source = { file };
            });
        };
        reader.readAsDataURL(res);
      }
      this.$emit("modalevent", { name: "selectimage", data: row });
    },
    async editImage(v) {
      this.loading = true;
      this.selected = v;
      const self = this;

      const res = await $fetch(`${this.path}download/`, {
        params: {
          name: v.file,
          type: "file",
        },
      });

      const reader = new window.FileReader();
      reader.onload = (e) => {
        self.image = e.target.result;
        self.showmodal = {
          component: "media/CropImage",
          title: "Cắt hình ảnh",
          width: "90%",
          height: "auto",
          vbind: { selected: self.selected, image: self.image },
        };
      };
      reader.readAsDataURL(res);
      self.loading = false;
    },
    copyMedia(v) {
      this.$copyToClipboard(`${this.path}download/?name=${v.file}`);
    },
    deleteMedia(v, name) {
      let self = this;
      const remove = async function () {
        await self.$deleteapi(name, v.id);
        const idx = self.data.findIndex((x) => x.id === v.id);
        self.$delete(self.data, idx);
      };
      this.$buefy.dialog.confirm({
        message: "Bạn muốn xóa file: " + v.file,
        onConfirm: remove,
      });
    },
    updateImage(v) {
      this.data.splice(0, 0, v);
      this.showmodal = undefined;
    },
  },
};
</script>
<style scoped>
.tabs {
  --bulma-tabs-toggle-link-active-background-color: var(--bulma-link-90);
  --bulma-tabs-toggle-link-active-border-color: var(--bulma-link-90);
  --bulma-tabs-toggle-link-active-color: var(--bulma-link-40);
}
</style>
