<script setup>
import { twMerge } from "tailwind-merge";
import { computed, defineProps, provide, ref, watch } from "vue";
import Pagination from "@/components/customUI/Pagination.vue";
import Checkbox from "@/components/customUI/Checkbox.vue";
import dayjs from "dayjs";
import { useI18n } from "vue-i18n";
const { t } = useI18n();
/*
column={
	title,key,class, width, filter:Boolean, sort:Boolean
}
*/
const props = defineProps({
  columns: Array,
  dataSource: Array,
  rowKey: String,
  withStyle: {
    type: Boolean,
    default: true,
  },
  pagination: { type: Boolean, default: true } || {
    pageSize: Number,
    totalPages: Number,
    totalItems: Number,
  },
  loading: Boolean,
});

const currentDataSource = ref([]);
const dataSourceStorage = ref([]);

const tableDataSource = computed(() =>
  props.pagination ? currentDataSource.value : dataSourceStorage.value
);

watch(
  () => props.dataSource,
  (newValue) => {
    dataSourceStorage.value = newValue;
    filterItems.value = Object.fromEntries(
      props.columns.map((c, i) => [
        c.key,
        [...new Set(newValue.map((d) => d[c.key]))].map((name) => ({
          name,
          selected: false,
        })),
      ])
    );
  }
);

const updateDataSource = (data) => {
  // console.log("update", data);
  currentDataSource.value = data;
};
provide("current_table_data", {
  updateDataSource,
});

const sortRule = ref({});
const filterColumn = ref({});
const filterItems = ref({});
const selectedFilterItem = ref({});
const searchQuery = ref("");

const toggleFilterModal = (key) => {
  let newFilter = Object.assign(filterColumn.value);

  for (let oKey in newFilter) {
    newFilter[oKey] = key === oKey && !newFilter[key];
  }

  filterColumn.value = newFilter;
};

watch(
  () => props.columns,
  (newValue) => {
    sortRule.value = Object.fromEntries(newValue.map((c) => [c.key, 0]));
    filterColumn.value = Object.fromEntries(
      newValue.map((c, i) => [c.key, false])
    );
    selectedFilterItem.value = Object.fromEntries(
      newValue.map((c, i) => [c.key, []])
    );
  },
  {
    immediate: true,
  }
);

/*
0:取消
1:ascending
2:descending
*/
const toggleSortRule = (key) => {
  let newSort = Object.assign(sortRule.value);

  for (let oKey in newSort) {
    newSort[oKey] = key === oKey ? newSort[key] : 0;
  }

  sortRule.value = newSort;
};

const sort = (column) => {
  toggleSortRule(column);
  const cantSort = ["object", "boolean"];
  console.log(props.dataSource?.[0][column]);
  if (cantSort.includes(typeof props.dataSource?.[0][column])) return;
  // 小->大
  const newArray = Object.assign(props.dataSource, []).sort((a, b) => {
    // if (column === "timestamp") {
    //   return dayjs(a[column]).valueOf() - dayjs(b[column]).valueOf();
    // }
    if (typeof a[column] === "number") return a[column] - b[column];
    else if (typeof a[column] === "string") {
      console.log(a[column], b[column], a[column].localeCompare(b[column]));
      return a[column].localeCompare(b[column]);
    }
    // return parseInt(a[column]) - parseInt(b[column]);
  });
  if (sortRule.value[column] === 0) {
    sortRule.value[column] = 1;
    dataSourceStorage.value = newArray;
  } else if (sortRule.value[column] === 1) {
    sortRule.value[column] = 2;
    dataSourceStorage.value = newArray.reverse();
  } else if (sortRule.value[column] === 2) {
    sortRule.value[column] = 0;
    dataSourceStorage.value = props.dataSource;
  }
};
const form = ref(null);

const onFilter = (key, reset = false) => {
  const formData = new FormData(form.value);
  if (reset) {
    formData.delete(key);
    searchQuery.value = "";
  }
  for (let [name, value] of formData) {
    console.log(name, value);
  }
  selectedFilterItem.value[key] = formData.getAll(key);
  toggleFilterModal(key);
};

watch(
  selectedFilterItem,
  (newVal) => {
    let newData = Object.assign(props.dataSource);
    for (let key in newVal) {
      if (newVal[key].length > 0) {
        newData = newData.filter((d) => newVal[key].includes(d[key]));
      }
    }
    dataSourceStorage.value = newData;
  },
  {
    deep: true,
  }
);
</script>

<template>
  <div :class="withStyle ? 'content-box' : 'py-5'">
    <div class="content-decoration">
      <slot name="beforeTable"></slot>
      <form ref="form" class="overflow-x-auto">
        <table
          :class="
            twMerge(
              withStyle ? 'table' : 'table border',
              currentDataSource.length === 0 ? 'h-28' : ''
            )
          "
        >
          <!-- head -->
          <thead>
            <tr>
              <th
                v-for="column in columns"
                :key="column.key"
                :class="`${column.class ? column.class : ''}`"
                :style="{
                  width: `${
                    column.width
                      ? typeof column.width === 'string'
                        ? column.width
                        : column.width + 'px'
                      : 'auto'
                  }`,
                }"
              >
                <span class="flex justify-center">
                  {{ column.title }}
                  <div
                    v-if="column.sort"
                    class="flex flex-col justify-center w-3 mx-2 relative"
                    @click="() => sort(column.key)"
                  >
                    <font-awesome-icon
                      :icon="['fas', 'sort-up']"
                      :class="
                        twMerge(
                          'absolute top-0',
                          sortRule[column.key] === 1 ? 'text-success' : ''
                        )
                      "
                      size="lg"
                    />
                    <font-awesome-icon
                      :icon="['fas', 'sort-down']"
                      :class="
                        twMerge(
                          'absolute bottom-1',
                          sortRule[column.key] === 2 ? 'text-success' : ''
                        )
                      "
                      size="lg"
                    />
                  </div>
                  <div class="ml-2 relative" v-if="column.filter">
                    <font-awesome-icon
                      :icon="['fas', 'filter']"
                      :class="
                        twMerge(
                          filterColumn[column.key] ||
                            selectedFilterItem[column.key].length > 0
                            ? 'text-success'
                            : ''
                        )
                      "
                      @click="() => toggleFilterModal(column.key)"
                    />
                    <div class="fixed z-50" v-if="filterColumn[column.key]">
                      <div class="card min-w-max bg-body shadow-xl px-10 py-5">
                        <label
                          class="input input-bordered bg-transparent rounded-lg flex items-center px-2 mb-4 border-success focus-within:border-success"
                        >
                          <font-awesome-icon
                            :icon="['fas', 'search']"
                            class="w-6 h-6 mr-2 text-success"
                          />
                          <input
                            type="text"
                            :placeholder="t('operation.enter_text')"
                            class="text-white bg-transparent w-full"
                            v-model="searchQuery"
                          />
                        </label>
                        <div class="max-h-72 overflow-x-auto px-2">
                          <Checkbox
                            v-for="item in filterItems[column.key].filter(
                              (item) =>
                                item.name && item.name.includes(searchQuery)
                            )"
                            :title="item.name"
                            :value="item.name"
                            :key="item.name"
                            :name="column.key"
                            :checked="
                              selectedFilterItem[column.key].includes(item.name)
                            "
                            className="justify-start"
                          />
                        </div>
                        <div class="card-actions mt-4 justify-end">
                          <input
                            type="reset"
                            class="btn btn-sm text-white btn-error"
                            :value="t('button.reset')"
                            @click="() => onFilter(column.key, true)"
                          />
                          <button
                            class="btn btn-sm btn-success"
                            @click.stop.prevent="() => onFilter(column.key)"
                          >
                            {{ $t("button.submit") }}
                          </button>
                        </div>
                      </div>
                    </div>
                  </div>
                </span>
              </th>
            </tr>
          </thead>
          <tbody>
            <tr v-if="loading">
              <td :colspan="columns.length">
                <Loading />
              </td>
            </tr>
            <tr v-else-if="tableDataSource.length == 0">
              <td :colspan="columns.length">{{ $t("table.no_data") }}</td>
            </tr>
            <template v-else :sort="sortRule">
              <tr
                v-for="(data, index) in tableDataSource"
                :key="data.key || data[rowKey]"
              >
                <template
                  v-for="column in columns"
                  :key="`${data.key || data[rowKey]}_${column.key}`"
                >
                  <td
                    :class="column.class"
                    :style="{
                      width: `${
                        column.width
                          ? typeof column.width === 'string'
                            ? column.width
                            : column.width + 'px'
                          : 'auto'
                      }`,
                    }"
                  >
                    <slot
                      name="bodyCell"
                      v-bind="{ record: data, column, index }"
                    >
                      {{ data[column.key] }}</slot
                    >
                  </td>
                </template>
              </tr>
            </template>
          </tbody>
        </table>
      </form>
      <slot name="afterTable"></slot>
      <Pagination
        v-if="pagination"
        :pagination="pagination"
        :dataSource="dataSourceStorage"
        :sort="sortRule"
      />
    </div>
    <div class="content-decoration2"></div>
  </div>
</template>

<style lang="css" scoped>
/**資料框**/
.content-box {
  @apply border border-info p-1 relative mb-4 bg-transparent;
}

.content-box .table {
  @apply rounded-none;
}

.table th {
  @apply bg-cyan-600 bg-opacity-30 border-r border-b border-white text-lg font-semibold text-white text-center px-2 py-3;
}

.table td {
  @apply border-r border-b border-white text-lg font-semibold text-white text-center px-2 py-3;
}

.table tr td:last-child,
.table tr:first-child th:last-child {
  border-right: 0;
}

/* .table tr:last-child td {
  border-bottom: v-bind("withStyle ? '0px': '1px'");
} */

/**資料框裝飾**/
.content-box::before {
  @apply absolute top-1 left-1 h-5 w-5 bg-no-repeat z-10 bg-[url('../../assets/img/table/content-box-background01.svg')] bg-center;
  content: "";
}

.content-box::after {
  @apply absolute bottom-1 right-1 h-5 w-5 bg-no-repeat z-10 bg-[url('../../assets/img/table/content-box-background05.svg')] bg-center;
  content: "";
}
.content-box .content-decoration {
  @apply bg-normal px-8 py-4;
}

/* .content-box .content-decoration::before {
  @apply absolute -top-3 -right-[10px] h-8 w-8 bg-no-repeat z-10 bg-[url('../../assets/img/table/content-box-background02.svg')] bg-center;
  content: "";
} */

.content-box .content-decoration2::before {
  @apply absolute -bottom-1 -left-8 h-14 w-14 bg-no-repeat z-10 bg-[url('../../assets/img/table/content-box-background03.svg')] bg-center;
  content: "";
}

/* .content-box .content-decoration2::after {
  content: "";
  background: url(../../assets/img/table/content-box-background04.svg) center
    center;
  position: absolute;
  right: -27px;
  bottom: -7px;
  height: 65px;
  width: 50px;
  background-repeat: no-repeat;
  z-index: 2;
} */
</style>
