<script setup lang="ts">
  import { ref, onMounted, reactive, computed } from 'vue';
  import { message } from 'ant-design-vue';
  import {
    Card,
    Tooltip,
    Popover,
    Checkbox,
    Button,
    List,
    ListItem,
    Table,
    Empty,
  } from 'ant-design-vue';
  import {
    LoadingOutlined,
    ReloadOutlined,
    VerticalAlignTopOutlined,
    VerticalAlignBottomOutlined,
    SettingOutlined,
    FullscreenExitOutlined,
    FullscreenOutlined,
  } from '@ant-design/icons-vue';

  const props = defineProps({
    // 表格的列
    columns: {
      // type: Array,
      default: () => [],
    },
    // 表格的数据
    tableData: {
      // type: Array,
      default: () => [],
    },
    // 表格懒加载
    loading: {
      // type: Boolean,
      default: false,
    },
    // 是否显示右侧按钮
    rightBtn: {
      type: Boolean,
      default: true,
    },
    // 是否显示左侧数量统计
    leftTitle: {
      type: Boolean,
      default: true,
    },
    // 表格的rowSelection（多选）
    rowSelection: {
      default: undefined,
    },
    // 表格的分页
    pagination: {
      default: () => ({}),
    },
    name: {
      type: String,
      default: '',
    },
    // 表格的主键
    rowKey: {
      type: String,
      default: 'id',
    },
    scroll: {},
  });

  const emit = defineEmits(['refresh']);

  const scopedSlots = computed(() => {
    return columns1.value
      .filter((el: any) => el.slots?.customRender)
      .map((el) => el.slots?.customRender);
  });

  onMounted(() => {
    if (props.name && props.name !== '') {
      initColumns();
    } else {
      columns1.value = props.columns;
    }
    handleCheckBox();
  });

  const columns1 = ref<any[]>([]);
  const fullScreen = ref(false);
  const checkAll = ref(false);
  const indeterminate = ref(false);
  const table = ref();
  const fun = reactive({
    index: (text: any, record: any, index: any) => {
      return index + 1;
    },
  });

  const initColumns = () => {
    const columns = sessionStorage.getItem(props.name);
    if (columns) {
      return (columns1.value = JSON.parse(columns).map((el: any) => {
        let obj = { ...el };
        if (obj.customRender) {
          // 解决JSON.stringify后，方法丢失的问题
          obj.customRender = fun[obj.customRender as keyof typeof fun];
        }
        return obj;
      }));
    }
    resetTableColumuns();
  };
  const resetTableColumuns = () => {
    columns1.value = props.columns.map((el: any) => {
      let obj = { ...el };
      if (obj.customRender) {
        // 解决JSON.stringify后，方法丢失的问题
        obj.customRender = fun[obj.customRender as keyof typeof fun];
      }
      return obj;
    });
    sessionStorage.setItem(props.name, JSON.stringify(props.columns));
  };

  // 全屏
  const toggleScreen = () => {
    if (fullScreen.value) {
      outFullScreen();
    } else {
      inFullScreen();
    }
    fullScreen.value = !fullScreen.value;
  };

  const inFullScreen = () => {
    const el = table.value;
    el.classList.add('beauty-scroll');
    if (el.requestFullscreen) {
      el.requestFullscreen();
      return true;
    } else if (el.webkitRequestFullScreen) {
      el.webkitRequestFullScreen();
      return true;
    } else if (el.mozRequestFullScreen) {
      el.mozRequestFullScreen();
      return true;
    } else if (el.msRequestFullscreen) {
      el.msRequestFullscreen();
      return true;
    }
    message.warn('对不起，您的浏览器不支持全屏模式');
    el.classList.remove('beauty-scroll');
    return false;
  };

  const outFullScreen = () => {
    const doc: any = document;
    if (doc.exitFullscreen) {
      doc.exitFullscreen();
    } else if (doc.webkitCancelFullScreen) {
      doc.webkitCancelFullScreen();
    } else if (doc.mozCancelFullScreen) {
      doc.mozCancelFullScreen();
    } else if (doc.msExitFullscreen) {
      doc.msExitFullscreen();
    }
    table.value.classList.remove('beauty-scroll');
  };

  // 刷新
  const refresh = () => {
    emit('refresh');
  };

  const handleCheckBox = () => {
    const list = columns1.value.filter((el) => el.visible);
    indeterminate.value = !!list.length && list.length < columns1.value.length;
    checkAll.value = list.length === columns1.value.length;
  };

  const saveConfig = () => {
    sessionStorage.setItem(props.name, JSON.stringify(columns1.value));
  };

  const onCheckAllChange = (e: any) => {
    if (e.target.checked) {
      columns1.value.forEach((col) => (col.visible = true));
    } else {
      columns1.value.forEach((col) => (col.visible = false));
    }
    handleCheckBox();
    saveConfig();
  };

  const onCheckChange = () => {
    handleCheckBox();
    saveConfig();
  };

  const fixColumn = (fixed: 'left' | 'right', col: any) => {
    if (col.fixed === fixed) {
      col.fixed = '';
    } else {
      col.fixed = fixed;
    }
    saveConfig();
  };

  initColumns();
</script>

<template>
  <Card style="border-radius: 10px">
    <slot name="searchForm"></slot>
    <div ref="table" class="all-table component-background">
      <div class="table-content">
        <div class="count">
          <span v-if="leftTitle">
            共&nbsp;&nbsp;“{{ pagination.total || tableData.length }}”&nbsp;&nbsp;条相关信息
          </span>
        </div>
        <div class="btns">
          <slot name="controls"></slot>
          <template v-if="rightBtn">
            <Tooltip title="刷新" style="margin-right: 10px">
              <loading-outlined
                style="margin-right: 10px"
                v-if="loading"
                @click="refresh"
                class="action"
              />
              <reload-outlined style="margin-right: 10px" v-else @click="refresh" class="action" />
            </Tooltip>
            <Tooltip title="列配置">
              <Popover trigger="click" placement="bottomRight">
                <template #title>
                  <Checkbox
                    :indeterminate="indeterminate"
                    v-model:checked="checkAll"
                    @change="onCheckAllChange"
                    class="check-all"
                  />
                  列展示
                  <Button @click="resetTableColumuns" style="float: right" type="link" size="small"
                    >重置</Button
                  >
                </template>
                <template #content>
                  <List style="width: 100%" size="small" :key="i" v-for="(col, i) in columns1">
                    <ListItem>
                      <Checkbox v-model:checked="col.visible" @change="onCheckChange">
                        <template v-if="col.title"> {{ col.title }}: </template>
                      </Checkbox>
                      <template #actions>
                        <Tooltip
                          title="固定在列头"
                          :mouseEnterDelay="0.5"
                          :get-popup-container="() => $refs.root"
                        >
                          <vertical-align-top-outlined
                            :class="['left', { active: col.fixed === 'left' }]"
                            @click="fixColumn('left', col)"
                          />
                        </Tooltip>
                        <Tooltip
                          title="固定在列尾"
                          :mouseEnterDelay="0.5"
                          :get-popup-container="() => $refs.root"
                        >
                          <vertical-align-bottom-outlined
                            :class="['right', { active: col.fixed === 'right' }]"
                            @click="fixColumn('right', col)"
                          />
                        </Tooltip>
                      </template>
                    </ListItem>
                  </List>
                </template>
                <setting-outlined style="margin-right: 10px" class="action" />
              </Popover>
            </Tooltip>
            <Tooltip title="全屏">
              <!--              <a-icon @click="toggleScreen" class="action" :type="fullScreen ? 'fullscreen-exit' : 'fullscreen'"/>-->
              <fullscreen-exit-outlined
                style="margin-right: 10px"
                @click="toggleScreen"
                class="action"
                v-if="fullScreen"
              />
              <fullscreen-outlined
                style="margin-right: 10px"
                @click="toggleScreen"
                class="action"
                v-else
              />
            </Tooltip>
          </template>
        </div>
      </div>
      <slot name="table">
        <Table
          v-if="columns1.filter((el) => el.visible).length"
          v-bind="{ ...$props }"
          :columns="columns1.filter((el) => el.visible)"
          :data-source="tableData"
          :loading="loading"
          :row-key="rowKey"
        >
          <template #expandedRowRender="{ record }" v-if="$slots.expandedRowRender">
            <slot name="expandedRowRender" v-bind="{ record }"></slot>
          </template>
          <template v-slot:bodyCell="{ column, record, index }">
            <slot name="bodyCell" v-bind="{ column, record, index }"></slot>
          </template>
        </Table>
        <Empty style="margin: 20px" v-else description="请勾选展示的列" />
      </slot>
    </div>
  </Card>
</template>

<style lang="less" scoped>
  @import 'index';
</style>
