<template>
  <div>
    <WsDataTablePagenateTypeB
      @pageto="$_onPageto($event)"
      :currentPage="currentPage"
      :dataTotalCount="dataTotalCount"
      :itemsPerPage="itemsPerPage"
      :lastPage="lastPage"
    ></WsDataTablePagenateTypeB>
    <v-data-table
      v-if="items&&items.length"
      class="ws-data-table"
      :items="_items"
      :items-per-page="itemsPerPage"
      :headers="headers"
      :expanded.sync="expanded"
      hide-default-footer
      :loading="loading"
      :show-expand="showExpand"
      item-key="id"
      :sort-by="sortBy"
      :sort-desc="sortDesc"
      @update:options="$_onOptionsUpdate($event)"
      @click:row="$_onRowClick($event)"
      :class="[{'row-link':rowClickRead}]"
    >
      <template v-slot:footer>
        <WsDataTablePagenateTypeB
          @pageto="$_onPageto($event)"
          :dataTotalCount="dataTotalCount"
          :itemsPerPage="itemsPerPage"
          :currentPage="currentPage"
          :lastPage="lastPage"
        ></WsDataTablePagenateTypeB>
      </template>
      <template v-slot:expanded-item="{ headers,item }">
        <td :colspan="headers.length">
          <div class="ws-data-table__expand-content">
            <WsEasyTable
              :fields="displayFields"
              :modelData="$_getModelDataById(item.id)"
            />
          </div>
        </td>
      </template>
      <template v-slot:item.actions="{ item }">
        <template v-if="pageMode">
          <WsIconBtn
            v-show="inRowBtnRead"
            tooltip="查看"
            tooltipPosition="top"
            :to="`/${modelName}/${item.id}`"
            class="ml-1 mr-1"
          >mdi-eye</WsIconBtn>
          <WsIconBtn
            v-show="inRowBtnUpdate"
            tooltip="編輯"
            tooltipPosition="top"
            :to="`/${modelName}/${item.id}/update?redirect=${$route.fullPath}`"
            class="ml-1 mr-1"
          >mdi-pencil</WsIconBtn>
        </template>
        <template v-else>
          <WsIconBtn
            v-show="inRowBtnRead"
            tooltip="查看"
            tooltipPosition="top"
            @click.stop="$_onActionReadClick(item)"
            class="ml-1 mr-1"
          >mdi-eye</WsIconBtn>
          <WsIconBtn
            v-show="inRowBtnUpdate"
            tooltip="編輯"
            tooltipPosition="top"
            class="ml-1 mr-1"
            @click.stop="$_onActionUpdateClick(item)"
          >mdi-pencil</WsIconBtn>
        </template>
        <WsIconBtn
          v-show="inRowBtnDelete"
          tooltip="刪除"
          tooltipPosition="top"
          class="ml-1 mr-1"
          @click.stop="$_onActionDeleteClick(item)"
        >mdi-delete</WsIconBtn>
        <WsIconBtn
          v-show="inRowBtnComplete"
          tooltip="完成"
          tooltipPosition="top"
          class="ml-1 mr-1"
          @click.stop="$_onActionCompleteClick(item)"
        >mdi-check</WsIconBtn>
      </template>
      <template
        v-for="imageItem in _imageItems"
        v-slot:[$_getItemSlotName(imageItem)]="{ item }"
      >
        <v-img
          v-if="item[imageItem]"
          :key="imageItem"
          max-width="100px"
          :src="item[imageItem]"
        />
      </template>
    </v-data-table>
  </div>
</template>

<script>
export default {
  data: () => ({
    expanded: [],
  }),
  methods: {
    $_onOptionsUpdate($event) {
      this.$emit("sort-update", $event);
    },
    $_getModelDataById(id) {
      const modelData = this.items.find((e) => {
        return e.id == id;
      });
      return modelData;
    },
    $_getItemSlotName(item) {
      return "item." + item;
    },
    $_getSpecificItems(type) {
      const items = [];
      for (let displayKey in this.displayFields) {
        const displayField = this.displayFields[displayKey];
        if (displayField.type == type) {
          items.push(displayKey);
        }
      }
      return items;
    },
    $_onPageto(page) {
      this.$emit("pageto", page);
    },
    $_onRowClick(item) {
      if (this.showExpand) {
        const index = this.expanded.indexOf(item);
        if (index === -1) {
          this.expanded.push(item);
        } else {
          this.expanded.splice(index, 1);
        }
      } else if (this.rowClickRead) {
        this.$router.push(`/${this.modelName}/${item.id}`);
      }
    },
    $_onActionReadClick(item) {
      this.$emit("read", item);
    },
    $_onActionUpdateClick(item) {
      this.$emit("update", item);
    },
    $_onActionDeleteClick(item) {
      this.$emit("delete", item);
    },
    $_onActionCompleteClick(item) {
      this.$emit("complete", item);
    },
    $_formatItemVersions(item, itemPre, versionsFields, keyPre = "") {
      for (let versionsFieldKey in versionsFields) {
        const versionsField = versionsFields[versionsFieldKey];
        this.$_formatItem(
          item,
          itemPre.last_version,
          versionsField,
          versionsFieldKey,
          `${keyPre}last_version__`
        );
      }
    },
    $_formatItemLocales(item, itemPre, localesFields, keyPre = "") {
      for (let localesFieldKey in localesFields) {
        item[`${keyPre}locales_main__${localesFieldKey}`] = itemPre
          ? itemPre[localesFieldKey]
          : null;
        const locales = this.$store.state.locale.locales;
        locales.forEach((locale) => {
          item[`${keyPre}locales_${locale.code}__${localesFieldKey}`] =
            itemPre && itemPre.locales && itemPre.locales[locale.code]
              ? itemPre.locales[locale.code][localesFieldKey]
              : null;
        });
      }
    },
    $_formatItemBelongsTo(
      item,
      itemPre,
      fieldKey,
      keyPre,
      textKey = "text",
      selectMode = false
    ) {
      if (!itemPre || !itemPre[fieldKey]) {
        return;
      }
      if (selectMode) {
        return;
      }
      item[`${keyPre}${fieldKey}`] = itemPre[fieldKey][textKey];
    },
    $_formatItemHasMany(
      item,
      itemPre,
      fieldKey,
      keyPre = "",
      textKey = "text",
      selectMode = false
    ) {
      if (!itemPre || !itemPre[fieldKey]) {
        return;
      }
      if (selectMode) {
        return;
      }
      let hasManyValue = "";
      itemPre[fieldKey].forEach((hasmanyItem) => {
        if (hasManyValue != "") {
          hasManyValue += ",";
        }
        hasManyValue += hasmanyItem[textKey];
      });
      item[`${keyPre}${fieldKey}`] = hasManyValue;
    },
    $_formatItemDate(item, itemPre, fieldKey, keyPre = "") {
      if (!itemPre || !itemPre[fieldKey]) {
        return;
      }
      item[`${keyPre}${fieldKey}`] = this.$moment(itemPre[fieldKey]).format(
        "YYYY.MM.DD"
      );
    },
    $_formatItemDatetime(item, itemPre, fieldKey, keyPre = "") {
      if (!itemPre || !itemPre[fieldKey]) {
        return;
      }
      item[`${keyPre}${fieldKey}`] = this.$moment(itemPre[fieldKey]).format(
        "YYYY.MM.DD HH:mm:ss"
      );
    },
    $_formatItemCustom(item, itemPre, fieldKey, keyPre = "", getValue) {
      // if (!itemPre || !itemPre[fieldKey]) {
      //   return;
      // }
      item[`${keyPre}${fieldKey}`] = getValue(item);
    },
    $_formatItemSwitch(
      item,
      itemPre,
      fieldKey,
      keyPre = "",
      activeText = "有",
      inactiveText = "無"
    ) {
      if (!itemPre) {
        return;
      }
      item[`${keyPre}${fieldKey}`] = itemPre[fieldKey]
        ? activeText
        : inactiveText;
    },
    $_formatItemSelect(
      item,
      itemPre,
      fieldKey,
      keyPre = "",
      textKey = "text",
      items = []
    ) {
      if (!itemPre || itemPre[fieldKey] == undefined) {
        return;
      }
      const tarItem = items.find((e) => {
        return e.value == item[`${keyPre}${fieldKey}`];
      });
      if (!tarItem) {
        return;
      }
      item[`${keyPre}${fieldKey}`] = tarItem[textKey];
    },
    $_formatItemOther(item, itemPre, fieldKey, keyPre) {
      if (!itemPre || !itemPre[fieldKey]) {
        return;
      }
      item[`${keyPre}${fieldKey}`] = itemPre ? itemPre[fieldKey] : null;
    },
    $_formatItem(item, itemPre, field, fieldKey, keyPre = "") {
      if (field.type == "last_version") {
        this.$_formatItemVersions(item, itemPre, field.fields, keyPre);
      } else if (field.type == "locales") {
        this.$_formatItemLocales(item, itemPre, field.fields, keyPre);
      } else if (field.type == "select") {
        this.$_formatItemSelect(
          item,
          itemPre,
          fieldKey,
          keyPre,
          field.textKey,
          field.items
        );
      } else if (field.type == "switch") {
        this.$_formatItemSwitch(
          item,
          itemPre,
          fieldKey,
          keyPre,
          field.activeText,
          field.inactiveText
        );
      } else if (field.type == "belongsTo") {
        this.$_formatItemBelongsTo(
          item,
          itemPre,
          fieldKey,
          keyPre,
          field.textKey,
          field.selectMode
        );
      } else if (field.type == "hasMany") {
        this.$_formatItemHasMany(
          item,
          itemPre,
          fieldKey,
          keyPre,
          field.textKey,
          field.selectMode
        );
      } else if (field.type == "date") {
        this.$_formatItemDate(item, itemPre, fieldKey, keyPre);
      } else if (field.type == "datetime") {
        this.$_formatItemDatetime(item, itemPre, fieldKey, keyPre);
      } else if (field.type == "custom") {
        this.$_formatItemCustom(
          item,
          itemPre,
          fieldKey,
          keyPre,
          field.getValue
        );
      } else {
        this.$_formatItemOther(item, itemPre, fieldKey, keyPre);
      }
    },
  },
  computed: {
    _imageItems() {
      return this.$_getSpecificItems("image");
    },
    _items() {
      const _items = JSON.parse(JSON.stringify(this.items));
      _items.forEach((item) => {
        for (let fieldKey in this.fields) {
          const field = this.fields[fieldKey];
          this.$_formatItem(item, item, field, fieldKey);
        }
      });
      return _items;
    },
  },
  props: {
    dataTotalCount: {
      type: Number,
      default: 0,
    },
    sortBy: {
      type: String,
      default: null,
    },
    sortDesc: {
      type: Boolean,
      default: false,
    },
    loading: {
      type: Boolean,
      default: false,
    },
    inRowBtnComplete: {
      type: Boolean,
      default: false,
    },
    rowClickRead: {
      type: Boolean,
      default: false,
    },
    inRowBtnRead: {
      type: Boolean,
      default: true,
    },
    inRowBtnUpdate: {
      type: Boolean,
      default: true,
    },
    inRowBtnDelete: {
      type: Boolean,
      default: true,
    },
    showExpand: {
      type: Boolean,
      default: true,
    },
    currentPage: [Number, String],
    lastPage: Number,
    modelName: String,
    pageMode: Boolean,
    displayFields: Object,
    fields: Object,
    items: {
      type: Array,
      default: () => [],
    },
    itemsPerPage: Number,
    headers: Array,
  },
};
</script>

<style lang="scss">
@import "../assets/scss/ws-data-table.scss";
</style>