<script>
import {TabulatorFull as Tabulator} from 'tabulator-tables';
import {
  prepColumns,
  sorter,
  renderGroupHeader,
  groupByFunction,
  makedFiltering,
  tablefy
} from "./helper";
import localization from "./localization";
import { cond, equals, is, mergeAll, sort, T, mergeDeepRight } from "ramda";
import { pipe } from "@helpers/functions";
import Pagination from "./VTabulatorPagination.vue";

export default {
  name: 'VTabulator',
  components: {
    Pagination
  },
  props: {
    dataSource: {
      type: Array,
      default: () => []
    },
    columns: {
      type: Array,
      default: () => []
    },
    initialSort: {
      type: String,
      default: null
    },
    groupBy: {
      type: String,
      default: null
    },
    groupByTemplate: {
      type: String,
      default: null
    },
    groupValues: {
      type: String,
      default: null
    },
    height: {
      type: String,
      default: "550px"
    },
    groupExtraValues: {
      type: String,
      default: null
    },
    groupHeader: {
      type: String,
      default: null
    },
    pagination: {
      type: Object,
      default: null
    },
    selectOption: {
      type: String,
      default: null
    },
    filterData: {
      type: String,
      default: null
    },
    withTablefy: {
      type: Boolean,
      default: true
    }
  },
  data() {
    return {
      refId: Math.random().toString(36).slice(4),
    }
  },
  computed: {
    data () {
      if (!is(Array, this.dataSource)) return []
      if (this.withTablefy) return tablefy(this.dataSource)
      return this.dataSource
    }
  },
  mounted() {
    this.makeTabele()
  },
  updated() {
    this.makeTabele()
  },
  methods: {
    makeTabele () {
      this.table = new Tabulator(this.$refs[this.refId], this.getConfig())
    },
    getConfig () {
      let configurator = pipe(this.__defaultCfg());
      return configurator(
        (x) => mergeDeepRight(x, this.__getColsCfg()),
        (x) => mergeDeepRight(x, this.__getSortCfg()),
        (x) => mergeDeepRight(x, this.__getGroupCfg()),
        (x) => mergeDeepRight(x, this.__getGroupHeaderCfg()),
        // (x) => mergeAll(x, this.__getPaginationCgs())
      );
    },
    __defaultCfg () {
      return {
        locale: "ru",
        langs: localization(),
        height: this.height || "250px",
        responsiveLayout: "collapse",
        placeholder: "Нет записей",
        movableColumns: true,
        autoResize: false,
        data: this.data,
        groupStartOpen: false,

        groupHeader: function (value, count, data, group) {
          return value + "<span>(" + count + " записей)</span>";
        },
      };
    },
    __getColsCfg() {
      let layout, columns = []
      if (this.autoColumns && is(Object, this.data[0])) {
        let first = this.data[0];
        let keys = Object.keys(first).map((key) => ({
          headerFilter: "input",
          headerFilterPlaceholder: key,
          title: key,
          field: key,
          download: false,
          print: false,
          vertAlign: "middle",
          sorter: "string",
          responsive: 0,
          minWidth: 80,
          maxWidth: 300,
        }));
        layout = "fitDataFill"
        columns = sort(sorter, keys)
      } else {
        layout = "fitDataStretch"
        columns = prepColumns(this.columns)
      }
      if (this.withTablefy) {
        columns = tablefy(columns)
      }
      return {columns, layout}
    },
    __getSortCfg() {
      if (this.initialSort) return { initialSort: this.initialSort };
      return {};
    },
    __getGroupCfg() {
      if (this.groupByTemplate)
      return { groupBy: groupByFunction(this.groupByTemplate) };
      if (this.groupBy) return { groupBy: this.groupBy };
      return {};
    },
    __getGroupHeaderCfg() {
      if (this.groupHeader)
      return {
        groupHeader: (value, count, data, group) =>
          renderGroupHeader({
            extra: this.groupExtraValues,
            groupHeader: this.groupHeader,
            value,
            count,
            data,
            group,
          }),
      };
      return {};
    },
  }
}

</script>

<template>
  <div class="mb-4">
    <div class="overflow-x-auto w-full">
      <div
        :ref="refId"
        class="w-full"
      />
    </div>
  </div>
  <div v-if="pagination">
    <Pagination :params="pagination"/>
  </div>
</template>
