import { ref, computed, createVNode, mergeProps } from "vue";
import "./styles/table.scss";
import { makePaperProps, usePaper } from "../../composables/paper/index.mjs";
import { makeScrollbar, useScrollbar } from "../../composables/scrollbar/index.mjs";
import { makeDataIteratorProps, useDataIterator } from "../../composables/data-iterator/index.mjs";
import { useProxiedModel } from "../../composables/proxied-model/index.mjs";
import { TableTh, filterTableThProps } from "./table-th.mjs";
import { TableNoData } from "./table-no-data.mjs";
import { Progress } from "../progress/progress.mjs";
import { Checkbox } from "../checkbox/checkbox.mjs";
import { Pagination } from "../pagination/pagination.mjs";
import { wrapInArray, useRender, throttle, getObjectValueByPath, downloadCSV, convertToUnit } from "../../utils/dist/index.mjs";
import { defineComponent } from "../../utils/define-component.mjs";
const Table = defineComponent({
  name: "VeTable",
  props: {
    hideBorder: Boolean,
    hideHeader: Boolean,
    fixedHeader: Boolean,
    headers: {
      type: Array,
      default: () => []
    },
    selected: {
      type: Array,
      default: () => []
    },
    sortIcon: {
      type: String,
      default: "$sort"
    },
    sortActiveColor: {
      type: String,
      default: "primary"
    },
    loading: Boolean,
    itemKey: {
      type: String,
      default: "id"
    },
    hidePagination: Boolean,
    ...makeDataIteratorProps(),
    ...makePaperProps({
      border: true,
      shape: "rounded-sm"
    }),
    ...makeScrollbar()
  },
  emits: {
    "update:pagination": (_) => true,
    "update:sortBy": (_) => true,
    "update:sortDesc": (_) => true,
    "update:options": (_) => true,
    "update:selected": (_) => true
  },
  setup(props, {
    slots
  }) {
    const containerRef = ref();
    const scrollLeft = ref(0);
    const selected = useProxiedModel(props, "selected");
    const isAllSelected = computed(() => {
      return selected.value.map((v) => v[props.itemKey]).sort().join("") === props.items.map((v) => v[props.itemKey]).sort().join("");
    });
    const {
      paperClasses,
      paperStyles
    } = usePaper(props, "ve-table__table");
    const {
      scrollbarClasses
    } = useScrollbar(props);
    const {
      items,
      pagination,
      sortBy: rawSortBy,
      sortDesc: rawSortDesc,
      sort,
      updateOptions
    } = useDataIterator(props);
    const headers = computed(() => {
      const length = props.headers.length;
      return props.headers.map((header, index) => {
        return {
          ...header,
          fixed: header.fixed === true ? index < (length - 1) / 2 ? "start" : "end" : header.fixed
        };
      });
    });
    const sortBy = computed(() => wrapInArray(rawSortBy.value));
    const sortDesc = computed(() => wrapInArray(rawSortDesc.value));
    const scrollPositionClasses = computed(() => {
      if (containerRef.value && scrollLeft.value === 0) {
        return "ve-table--scroll-position-start";
      } else if (containerRef.value && scrollLeft.value + containerRef.value.offsetWidth >= containerRef.value.scrollWidth) {
        return "ve-table--scroll-position-end";
      } else {
        return "ve-table--scroll-position-center";
      }
    });
    function handleScroll({
      target
    }) {
      scrollLeft.value = target.scrollLeft;
    }
    function genColProps(header) {
      var _a, _b;
      const styles = {
        width: convertToUnit(header.width),
        minWidth: convertToUnit((_a = header.minWidth) != null ? _a : header.width),
        maxWidth: convertToUnit((_b = header.maxWidth) != null ? _b : header.width)
      };
      return {
        style: styles
      };
    }
    function isSortDesc(header) {
      return sortDesc.value[sortBy.value.findIndex((v) => v === header.value)];
    }
    useRender(() => {
      const hasColgroup = !slots.colgroup && props.headers.length > 0;
      const hasThead = !slots.header && !props.hideHeader && props.headers.length > 0;
      const hasTbody = !slots.default;
      const hasPagination = hasTbody && !props.hidePagination;
      return createVNode(props.tag, {
        "class": ["ve-table", {
          "ve-table--fixed-header": props.fixedHeader
        }, scrollPositionClasses.value]
      }, {
        default: () => {
          var _a, _b, _c, _d, _e;
          return [createVNode("div", {
            "ref": containerRef,
            "onScroll": throttle(handleScroll, 128),
            "class": ["ve-table__table", paperClasses.value, scrollbarClasses.value],
            "style": paperStyles.value
          }, [createVNode("table", null, [hasColgroup && createVNode("colgroup", null, [headers.value.map((header) => {
            return createVNode("col", genColProps(header), null);
          })]), (_a = slots.colgroup) == null ? void 0 : _a.call(slots), hasThead && createVNode("thead", null, [props.loading && createVNode("tr", {
            "class": "ve-table__progress"
          }, [createVNode("th", {
            "colspan": props.headers.length
          }, [createVNode(Progress, {
            "color": "primary",
            "indeterminate": true,
            "stroke-width": 3
          }, null)])]), createVNode("tr", null, [headers.value.map((header, index) => {
            return createVNode(TableTh, mergeProps(filterTableThProps(header)[0], {
              "sort-icon": props.sortIcon,
              "sort-active-color": props.sortActiveColor,
              "sort-desc": isSortDesc(header),
              "onClick": () => header.sortable && sort(header.value)
            }), {
              default: () => {
                var _a2, _b2, _c2;
                return [header.$type === "selection" ? createVNode(Checkbox, {
                  "indeterminate": selected.value.length > 0 && !isAllSelected.value,
                  "onUpdate:indeterminate": (val) => {
                    if (!val) {
                      selected.value = props.items;
                    }
                  },
                  "modelValue": isAllSelected.value,
                  "onUpdate:modelValue": (val) => {
                    if (val) {
                      selected.value = props.items;
                    } else {
                      selected.value = [];
                    }
                  }
                }, null) : (_c2 = (_b2 = (_a2 = slots[`header.${header.value}`]) == null ? void 0 : _a2.call(slots, {
                  header,
                  index
                })) != null ? _b2 : header.text) != null ? _c2 : header.value];
              }
            });
          })])]), (_b = slots.header) == null ? void 0 : _b.call(slots), hasTbody && createVNode("tbody", null, [items.value.map((item, index) => {
            var _a2;
            return createVNode("tr", {
              "key": (_a2 = item[props.itemKey]) != null ? _a2 : index
            }, [headers.value.map((header) => {
              var _a3, _b2;
              return createVNode("td", {
                "class": ["ve-table-td", {
                  "ve-table-td--sorted": isSortDesc(header) !== void 0,
                  "ve-table-td--fixed-start": header.fixed === "start",
                  "ve-table-td--fixed-end": header.fixed === "end"
                }]
              }, [header.$type === "selection" ? createVNode(Checkbox, {
                "modelValue": selected.value.findIndex((v) => v[props.itemKey] === item[props.itemKey]) > -1,
                "onUpdate:modelValue": (val) => {
                  if (val) {
                    selected.value.push(item);
                  } else {
                    selected.value = selected.value.filter((v) => v[props.itemKey] !== item[props.itemKey]);
                  }
                }
              }, null) : (_b2 = (_a3 = slots[`item.${header.value}`]) == null ? void 0 : _a3.call(slots, {
                item,
                index
              })) != null ? _b2 : getObjectValueByPath(item, header.value)]);
            })]);
          }), !items.value.length && createVNode("tr", null, [createVNode("td", {
            "colspan": props.headers.length
          }, [(_d = (_c = slots.nodata) == null ? void 0 : _c.call(slots)) != null ? _d : createVNode(TableNoData, null, null)])])]), (_e = slots.default) == null ? void 0 : _e.call(slots)])]), hasPagination && createVNode(Pagination, mergeProps({
            "class": "ve-table__pagination"
          }, pagination.value, {
            "modelValue": pagination.value.page,
            "onUpdate:modelValue": (v) => {
              pagination.value.page = v;
              updateOptions();
            },
            "onUpdate:perPage": (v) => {
              pagination.value.perPage = v;
              updateOptions();
            }
          }), null)];
        }
      });
    });
    return {
      exportCSV(name) {
        downloadCSV(name, props.headers, items.value);
      }
    };
  }
});
export {
  Table
};
//# sourceMappingURL=table.mjs.map
