<template>
  <div class="card">
    <div class="card-header pb-0">
      <h6>{{ title }}</h6>
      <div class="d-flex justify-content-between">
        <div class="form-group">
          <div class="input-icon">
            <input
              type="text"
              v-model="keyword"
              class="form-control"
              placeholder="Search for..."
            />
          </div>
        </div>
        <div>
          <router-link
            v-if="canAdd"
            :to="`/${path}/create`"
            type="button"
            class="btn btn-primary btn-round ml-auto"
          >
            <div class="fa fa-fw fa-plus mr-2"></div>
            {{ addDataText ?? "Add Data" }}
          </router-link>
        </div>
      </div>
    </div>
    <div class="card-body px-0 pt-0 pb-2">
      <div class="table-responsive p-0">
        <table class="table align-items-center mb-0">
          <thead>
            <tr>
              <th
                v-for="(header, index) in headers"
                :key="index"
                :class="`text-${header['align'] ? header['align'] : 'center'}`"
                :style="header['style']"
              >
                <div
                  @click="header.sortable ? handleHeaderClick(header) : null"
                  style="cursor: pointer"
                >
                  {{ header["text"] }}
                  <span
                    v-if="
                      header.sortable &&
                      sortBy.column == header.value &&
                      sortBy.type == 'ASC'
                    "
                    class="mdi mdi-chevron-up"
                  ></span>
                  <span
                    v-if="
                      header.sortable &&
                      sortBy.column == header.value &&
                      sortBy.type == 'DESC'
                    "
                    class="mdi mdi-chevron-down"
                  ></span>
                </div>
              </th>
              <th :style="actionStyle" class="text-center">Actions</th>
            </tr>
          </thead>
          <tbody>
            <tr v-if="isContentLoading">
              <td :colspan="headers.length + 1">
                <div class="d-flex justify-content-center">
                  <div class="spinner-border text-primary" role="status"></div>
                </div>
              </td>
            </tr>
            <template v-if="!isContentLoading">
              <tr v-for="(content, index) in contents" :key="index">
                <td
                  v-for="(header, _index) in headers"
                  :key="_index"
                  :class="`text-${
                    header['align'] ? header['align'] : 'center'
                  }`"
                  :style="header['style']"
                >
                  <slot
                    :name="`${header['value']}`"
                    :content="content"
                    :value="content[header['value']]"
                  >
                    <span
                      :class="`text-${
                        header['align'] ? header['align'] : 'left'
                      }`"
                      >{{ resolve(content, header["value"]) }}</span
                    >
                  </slot>
                </td>
                <td :style="actionStyle" class="text-center">
                  <!-- <div class="d-flex"> -->
                  <slot name="left-action" :content="content"> </slot>
                  <router-link
                    v-if="canEdit"
                    :to="`/${path}/${content.id}/edit`"
                    type="button"
                    class="btn btn-xs bg-primary me-1 text-white"
                  >
                    Edit
                  </router-link>
                  <button
                    v-if="canDelete"
                    @click="deleteData(content.id)"
                    type="button"
                    class="btn btn-xs btn-danger"
                  >
                    Delete
                  </button>
                  <slot name="right-action" :content="content"> </slot>
                  <!-- </div> -->
                </td>
              </tr>
            </template>
          </tbody>
        </table>
      </div>
      <div class="px-5 mt-4">
        <paginate-content
          @onPageClick="handlePageItemClick"
          :page="page"
          :per_page="per_page"
          :total="total"
        />
      </div>
    </div>
  </div>
</template>

<script>
import PaginateContent from "./PaginateContent.vue";

let fetchController = new AbortController();

export default {
  components: { PaginateContent },
  props: {
    addDataText: {
      type: String,
      required: false,
      default: null,
    },
    addDataLink: {
      type: String,
      required: false,
      default: null,
    },
    api: {
      required: true,
    },
    path: {
      type: String,
      required: false,
      default: null,
    },
    listUrl: {
      type: String,
      required: false,
      default: null,
    },
    headers: {
      type: Array,
      required: true,
    },
    title: {
      type: String,
      reqired: true,
    },
    actionStyle: {
      type: String,
      reqired: false,
      default: null,
    },
    canAdd: {
      type: Boolean,
      default: true,
    },
    canEdit: {
      type: Boolean,
      default: true,
    },
    canDelete: {
      type: Boolean,
      default: true,
    },
    additionalFilter: {
      type: Object,
      default: {},
    },
    deleteMethod: {
      type: Function,
      required: false,
    },
  },
  data() {
    return {
      isContentLoading: false,
      contents: [],
      keyword: "",
      total: 0,
      page: 1,
      per_page: 10,
      isSearchFocused: false,
      sortBy: {
        column: null,
        type: null,
      },
    };
  },
  watch: {
    page(newPage, oldPage) {
      this.fetchData();
    },
    keyword() {
      this.fetchData();
    },
    sortBy() {
      this.fetchData();
    },
  },
  created() {
    this.fetchData();
  },
  methods: {
    resolve(obj, path, separator = ".") {
      var properties = path.split(separator);
      return properties.reduce((prev, curr) => prev && prev[curr], obj);
    },
    handlePageItemClick(page) {
      this.page = page;
    },
    handleHeaderClick(header) {
      if (this.sortBy.column == header.value && this.sortBy.type == "DESC") {
        this.sortBy = {
          column: null,
          type: null,
        };
        return;
      }
      if (this.sortBy.column == header.value) {
        this.sortBy = {
          column: header.value,
          type: "DESC",
        };
        return;
      }
      this.sortBy = {
        column: header.value,
        type: "ASC",
      };
    },
    async fetchData() {
      try {
        fetchController.abort();
      } catch (err) {}
      this.isContentLoading = true;
      const { page, per_page, keyword } = this;
      fetchController = new AbortController();
      const result = await this.api.datatable({
        page,
        per_page,
        keyword,
        ...this.additionalFilter,
        sortBy: this.sortBy,
      });
      this.total = result.total;
      this.contents = result.result.data;
      this.isContentLoading = false;
    },
    async deleteData(id) {
      await this.api.delete(`${id}`);
      this.fetchData();

      // swal.fire({
      //   title: "Are you sure want delete this data?",
      //   showDenyButton: true,
      //   confirmButtonText: `Yes`,
      //   denyButtonText: `No`,
      // }).then(async (result) => {
      //   if (result.isConfirmed) {
      //     await this.api.delete(`${id}`);
      //     swal.fire("Data berhasil dihapus!", "", "success");
      //     this.fetchData();
      //   } else if (result.isDenied) {
      //     swal.fire("Proses hapus dibatalkan", "", "info");
      //     this.fetchData();
      //   }
      // });
    },
  },
};
</script>
