<script lang="ts">
import { defineComponent } from "vue";
export default defineComponent({
  name: "Table",
});
</script>

<script lang="ts" setup>
import { Button, Pagination, Empty, Checkbox, Spin } from "ant-design-vue";
import { useSlots } from "vue";
import { ref, unref, computed } from "vue";
import { PlusOutlined, MinusOutlined } from "@ant-design/icons-vue";

interface PropsType {
  columns: Record<string, any>[];
  loading?: boolean;
  dataSource: Record<string, any>[];
  rowSelection?: Record<string, any> | null;
  rowKey: string;
  showExpand: boolean;
  pagination?: Record<string, any>;
}

const props = withDefaults(defineProps<PropsType>(), {
  columns: () => [],
  loading: false,
  dataSource: () => [],
  rowKey: "",
  showExpand: false,
  rowSelection: null,
  pagination: () => {
    return {
      showSizeChanger: false,
      total: 0,
      pageSize: 10,
      current: 1,
    };
  },
});

const emits = defineEmits(["expand", "change"]);

const showSelect = computed(() => {
  return !!props.rowSelection?.selectedRowKeys;
});

let expandIndex = 0;
let selectIndex = 0;

const showColumn = computed(() => {
  const showColumn = [];
  const baseColumn = props.columns;
  const selectColumn = {
    label: "",
    type: "selectCol",
    width: "50px",
    dataIndex: "_custom_select",
  };

  console.log("showSelect", !unref(showSelect));

  if (unref(showSelect)) {
    showColumn.push(selectColumn);
    expandIndex = 1;
  }
  showColumn.push(...baseColumn);
  return showColumn;
});

const slots = useSlots();

console.log("slots", slots);

const expandIds = ref<string[]>([]);

const onToggleExpand = (id: string, record: Record<string, any>) => {
  const index = expandIds.value.indexOf(id);
  if (index > -1) {
    expandIds.value.splice(index, 1);
  } else {
    expandIds.value.push(id);
  }
  emits("expand", index == -1, record);
};

const onPageChange = (page: number, pageSize: number) => {
  console.log("onPageChange", page, pageSize);
  emits("change", {
    current: page,
    pageSize: pageSize,
  });
  // if (props.rowSelection?.selectedRowKeys) {
  //   if (props.rowSelection.selectedRowKeys.value) {
  //     props.rowSelection.selectedRowKeys.value = [];
  //   } else {
  //     props.rowSelection.selectedRowKeys = [];
  //   }
  // }
};

const checkIds = ref<string[]>([]);

const useCheckIds = computed(() => {
  if (props.rowSelection?.selectedRowKeys) {
    return unref(props.rowSelection?.selectedRowKeys);
  } else {
    return checkIds.value;
  }
});

const checkAll = computed(() => {
  console.log("useCheckIds", useCheckIds.value);
  return props.dataSource.every((item: Record<string, any>) => {
    return useCheckIds.value.includes(item[props.rowKey]);
  });
});

// select
const onToggleSelectAll = (e: Record<string, any>) => {
  console.log("useCheckIds", useCheckIds.value);
  if (props.rowSelection?.onSelectAll) {
    props.rowSelection?.onSelectAll(e.target.checked);
    return;
  }
  if (e.target.checked) {
    checkIds.value = props.dataSource.map((item: Record<string, any>) => {
      return item[props.rowKey];
    });
  } else {
    checkIds.value = [];
  }
};

const onToggleSelect = (e: Record<string, any>, record: Record<string, any>) => {
  console.log("onToggleSelect", e);
  if (props.rowSelection?.onSelect) {
    props.rowSelection?.onSelect(record, e.target.checked);
    return;
  }
  if (e.target.checked) {
    checkIds.value.push(record[props.rowKey]);
  } else {
    checkIds.value = checkIds.value.filter((item) => item != record[props.rowKey]);
  }
};

// const showColumns = computed(() => {

// })

console.log("slots", slots);

const prefix = "_table-comp";
</script>

<template>
  <div :class="`${prefix}`">
    <Spin :spinning="unref(props.loading)">
      <div :class="`${prefix}-head`">
        <div
          :class="`${prefix}-head-col`"
          v-for="(col, colIndex) in showColumn"
          :style="`width: ${col.width}`"
        >
          <template v-if="showSelect && colIndex == 0">
            <Checkbox :checked="checkAll" @change="onToggleSelectAll" />
          </template>
          <template v-else>
            <slot
              name="headerCell"
              v-bind="{
                column: col,
                title: col.title,
                index: colIndex,
              }"
            >
              {{ col.title }}
            </slot>
          </template>
        </div>
      </div>
      <div :class="`${prefix}-body`">
        <template v-if="!props.dataSource.length">
          <div :class="`${prefix}-empty`">
            <Empty />
          </div>
        </template>
        <!-- 行 -->

        <template v-else>
          <template v-for="(rows, rowIndex) in props.dataSource">
            <div :class="`${prefix}-body-row`">
              <!-- 列 -->
              <div
                :class="`${prefix}-body-col`"
                v-for="(col, colIndex) in showColumn"
                :style="`width: ${col.width}`"
              >
                <template v-if="showSelect && colIndex == selectIndex">
                  <Checkbox
                    :checked="useCheckIds.includes(rows[props.rowKey])"
                    @change="onToggleSelect($event, rows)"
                  />
                </template>
                <template v-else>
                  <template v-if="colIndex == expandIndex && props.showExpand">
                    <Button size="small" ghost type="primary" class="expand-icon">
                      <template #icon>
                        <MinusOutlined
                          v-if="expandIds.includes(rows[props.rowKey])"
                          @click="onToggleExpand(rows[props.rowKey], rows)"
                        />
                        <PlusOutlined v-else @click="onToggleExpand(rows[props.rowKey], rows)" />
                      </template>
                    </Button>
                  </template>
                  <slot
                    name="bodyCell"
                    v-bind="{
                      record: rows,
                      column: col,
                      text: rows[col.dataIndex],
                      index: rowIndex,
                    }"
                  >
                    {{ rows[col.dataIndex] }}
                  </slot>
                </template>
              </div>
            </div>
            <div
              :class="`${prefix}-body-expand`"
              v-if="expandIds.includes(rows[props.rowKey])"
              @click.stop
            >
              <slot
                name="expandedRowRender"
                v-bind="{
                  record: rows,
                  index: rowIndex,
                }"
              ></slot>
            </div>
          </template>
        </template>
      </div>
      <div :class="`${prefix}-pagination`">
        <Pagination v-bind="props.pagination" @change="onPageChange" />
      </div>
    </Spin>
  </div>
</template>

<style lang="scss" scoped>
$prefix: "_table-comp";

.#{$prefix} {
  width: 100%;
  height: 100%;
  :deep(.ant-spin-container) {
    display: flex;
    align-items: start;
    justify-content: start;
    flex-direction: column;
    width: 100%;
    height: 100%;
  }

  &-head {
    width: 100%;
    display: flex;
    align-items: start;
    justify-content: start;
    background-color: #fff;
    overflow: auto;
    &-col {
      padding: 16px;
      font-size: 16px;
      font-weight: 600;
      color: rgba(0, 0, 0, 0.88);
      position: relative;
      height: 60px;
      display: flex;
      align-items: center;
      justify-content: start;
      // line-height: 32px;
      flex-shrink: 0;
      &::after {
        content: "";
        position: absolute;
        height: calc(100% - 32px);
        width: 1px;
        left: 0;
        top: 16px;
        background-color: #d8d8d8 !important;
      }
      &:first-child {
        &::after {
          display: none;
        }
      }
    }
  }
  &-body {
    width: 100%;
    overflow: auto;
    &-row {
      display: flex;
      align-items: start;
      justify-content: start;
      border-bottom: 1px solid #f0f0f0;
    }
    &-col {
      // width: auto;
      padding: 16px;
      display: flex;
      align-items: start;
      justify-content: start;
      align-self: stretch;
      flex-shrink: 0;
      gap: 10px;
    }
  }
  &-empty {
    width: 100%;
    height: 240px;
    display: flex;
    align-items: center;
    justify-content: center;
  }
  &-pagination {
    margin-top: 20px;
    width: 100%;
    display: flex;
    align-items: center;
    justify-content: flex-end;
    :deep(.ant-pagination) {
      display: flex;
      align-items: center;
      justify-content: flex-end;
    }
  }
  .expand-icon {
    font-size: 12px;
  }

  // 隐藏滚动条
}
</style>
