import { Searchs } from '@/utils/searchs';
import { NPagination } from 'naive-ui';
import {
  PropType,
  computed,
  defineComponent,
  onMounted,
  onUnmounted,
  reactive,
  ref,
  watch
} from 'vue';
import { useRoute } from 'vue-router';
import styles from './index.module.less';

export default defineComponent({
  name: 'table-container',
  props: {
    page: {
      type: Number,
      default: 1,
      required: true
    },
    pageSize: {
      type: Number,
      default: 10
    },
    pageTotal: {
      type: Number,
      default: 0
    },
    saveKey: {
      type: String,
      default: ''
    },
    sync: {
      type: Boolean,
      default: false
    },
    checkedRowKeysRef: {
      type: Object
    },
    disabled: {
      type: Boolean,
      default: false
    },
    pageSizes: {
      type: Array as PropType<any>,
      default: () => [10, 20, 30, 40]
    }
  },
  emits: ['update:page', 'update:pageSize', 'list'],
  setup(props, { emit }) {
    const route = useRoute();
    const state = reactive({
      pageInformation: null as any
    });

    const pageCount = ref(0);

    pageCount.value = Math.ceil(props.pageTotal / props.pageSize);

    // 当前页发生改变时的回调函数
    const onUpdatePage = (page: number) => {
      emit('update:page', page);
      emit('list');

      syncStore();
    };
    // 当前分页大小发生改变时的回调函数
    const onUpdatePageSize = (pageSize: number) => {
      emit('update:pageSize', pageSize);
      emit('list');

      syncStore();
    };

    onMounted(() => {
      if (props.sync) {
        const searchs = new Searchs(props.saveKey || route.path);
        const active = searchs.get(props.saveKey || route.path);
        state.pageInformation = active;
        if (active && active.page) {
          for (const key in active.page) {
            if (
              // eslint-disable-next-line no-prototype-builtins
              active.page.hasOwnProperty(key) &&
              ['page', 'pageSize'].includes(key)
            ) {
              const item = active.page[key];
              const tempKey = `update:${key}` as any;
              emit(tempKey, item);
            }
          }
        }
        if (props.saveKey) {
          searchs.update(route.path, undefined, 'bind');
        }
      }
      window.addEventListener('watchStorage', watchStorage);
    });

    onUnmounted(() => {
      window.removeEventListener('watchStorage', watchStorage);
    });

    watch(
      () => props.pageSize,
      () => {
        pageCount.value = Math.ceil(props.pageTotal / props.pageSize);
        syncStore();
      }
    );
    watch(
      () => props.page,
      () => {
        syncStore();
      }
    );
    watch(
      () => props.pageTotal,
      () => {
        pageCount.value = Math.ceil(props.pageTotal / props.pageSize);
        syncStore();
      }
    );

    const currentPage = computed({
      get() {
        return props.page;
      },
      set(val) {
        emit('update:page', val);
      }
    });

    const syncStore = () => {
      if (props.sync) {
        const searchs = new Searchs(props.saveKey || route.path);
        searchs.update(
          {
            page: props.page,
            pageCount: pageCount.value,
            pageSize: props.pageSize,
            saveKey: props.saveKey
          },
          undefined,
          'page'
        );
      }
    };

    const watchStorage = () => {
      const page =
        state.pageInformation && state.pageInformation.page
          ? state.pageInformation.page
          : null;
      currentPage.value = page && page.page ? page.page : 1;
    };

    return () => (
      <NPagination
        disabled={props.disabled}
        class={styles.pagination}
        v-model:page={props.page}
        displayOrder={['quick-jumper', 'pages', 'size-picker']}
        pageCount={pageCount.value}
        showQuickJumper
        showSizePicker
        pageSize={props.pageSize}
        prefix={() => `共 ${props.pageTotal} 条`}
        pageSizes={props.pageSizes}
        onUpdatePage={onUpdatePage}
        onUpdatePageSize={onUpdatePageSize}></NPagination>
    );
  }
});
