import { reactive } from 'vue'
import createAxios from '@/utils/request'
import { requestPayload } from '@/utils/request'
import { Method } from 'axios'
import { mainHeight } from '@/utils/layout'
import { filtration } from './tableMethod'

interface TableStoreParams {
    url: string // 请求地址
    pk?: string
    filename?: any // 导出文件名
    column: TableColumn[]
    params?: anyObj
    method?: Method // 请求方式
    isWebPaging?: boolean // 是否前端分页
    showPage?: boolean //是否需要分页
    timeAll?: boolean //是否需要时间全部显示
    paramsPOST?: boolean // post请求 params传参
    publicHeight?: number //计算高度
    resetCallback?: () => void // 重置
    loadCallback?: () => void // 接口调用后的回调
    exportProcessingData?: () => void //导出处理数据
    beforeSearchFun?: () => void // 接口调用前的回调
}

export default class TableStore {
    public url
    public pk
    public filename: any = null
    public method: Method
    public initData: any = null
    public isWebPaging = false
    public paramsPOST = true
    public showPage = true
    public timeAll = true
    public table: CnTable = reactive({
        ref: null,
        selection: [],
        data: [],
        allData: [],
        allFlag: false,
        webPagingData: [],
        total: 0,
        params: {
            pageNum: 1,
            pageSize: 20
        },
        filename: null,
        loading: true,
        exportLoading: false,
        customColumnInHeader: false,
        column: [],
        loadCallback: null,
        exportProcessingData: null,
        resetCallback: null,
        beforeSearchFun: null,
        height: '',
        publicHeight: 0
    })

    constructor(public options: TableStoreParams) {
        this.url = options.url
        this.pk = options.pk || 'id'
        this.paramsPOST = options.paramsPOST || false
        this.isWebPaging = options.isWebPaging || false
        this.method = options.method || 'GET'
        this.table.filename = options.filename || null
        this.table.column = options.column
        this.showPage = options.showPage !== false

        this.table.publicHeight = options.publicHeight || 0
        this.table.resetCallback = options.resetCallback || null
        this.table.loadCallback = options.loadCallback || null
        this.table.exportProcessingData = options.exportProcessingData || null
        this.table.beforeSearchFun = options.beforeSearchFun || null
        Object.assign(this.table.params, options.params)
        this.table.height = mainHeight(20 + (this.showPage ? 58 : 0) + this.table.publicHeight).height as string
    }

    index() {
   
        this.table.beforeSearchFun && this.table.beforeSearchFun()
        this.table.data = []
        this.table.loading = true
        // 重置用的数据数据
        if (!this.initData) {
            this.initData = JSON.parse(JSON.stringify(this.table.params))
        }
        if (!this.timeAll) {
            delete this.table.params.startTime
            delete this.table.params.endTime
            delete this.table.params.searchBeginTime
            delete this.table.params.searchEndTime
            delete this.table.params.timeFlag
        }
        createAxios(
            Object.assign(
                {
                    url: this.url,
                    method: this.method
                },
          
                requestPayload(this.method, this.table.params, this.paramsPOST)
            )
        )
            .then((res: any) => {
              
                if (res.data) {
                    this.table.data = res.data.records || res.data
                    this.table.total = res.data?.total || res.data.length || 0
                } else {
                    this.table.data = []
                    this.table.total = 0
                }
                if (Array.isArray(res)) {
                    this.table.data = res
                }
                if (this.isWebPaging) {
                    this.table.webPagingData = window.XEUtils.chunk(this.table.data, this.table.params.pageSize)
                    this.table.data = this.table.webPagingData[this.table.params.pageNum - 1]
                }
                this.table.loadCallback && this.table.loadCallback()
                this.table.loading = false
            })
            .catch(() => {
                this.table.loading = false
            })
    }

    /**
     * 表格内的事件统一响应
     * @param event 事件:selection-change=选中项改变,page-size-change=每页数量改变,current-page-change=翻页
     * @param data 携带数据
     */
    onTableAction = (event: string, data: anyObj) => {
      
        const actionFun = new Map([
            [
                'search',
                () => {
             
                    this.table.params.pageNum = 1
                    this.index()
                   
                }
            ],
            [
                'reset',
                () => {
                    delete this.initData.pageSize
                    // console.log(this.table.params)
                    // console.log(this.initData)
                    Object.assign(this.table.params, this.initData)
                    this.table.resetCallback && this.table.resetCallback()
                    this.index()
                }
            ],
            [
                'selection-change',
                () => {
                    this.table.selection = data as TableRow[]
                }
            ],
            [
                'page-size-change',
                () => {
                    this.table.params.pageSize = data.size
                    this.table.params.pageNum = 1

                    if (this.isWebPaging) {
                        this.table.webPagingData = window.XEUtils.chunk(
                            window.XEUtils.flatten(this.table.webPagingData),
                            this.table.params.pageSize
                        )
                        this.table.data = this.table.webPagingData[this.table.params.pageNum - 1]
                    } else {
                        this.index()
                    }
                }
            ],
            [
                'current-page-change',
                () => {
                    this.table.params.pageNum = data.page
                    if (this.isWebPaging) {
                        this.table.data = []
                        requestAnimationFrame(() => {
                            this.table.data = this.table.webPagingData[data.page - 1]
                        })
                    } else {
                        this.index()
                    }
                }
            ],
            [
                'field-change',
                () => {
                    console.warn('field-change')
                }
            ],
            [
                'default',
                () => {
                    console.warn('No action defined')
                }
            ],
            [
                'export',
                () => {
                   
                     this.table.exportLoading = true
                    // this.index()
             
                    let params = { ...this.table.params, pageNum: 1, pageSize: this.table.total }
                    createAxios(
                        Object.assign(
                            {
                                url: this.url,
                                method: this.method
                            },
                            requestPayload(this.method, params, this.paramsPOST)
                        )
                    )
                        .then(res => {
                            this.table.allData = filtration(res.data.records || res.data)
                            this.table.exportProcessingData && this.table.exportProcessingData()
                            this.table.allFlag = data.showAllFlag || true
                            this.table.exportLoading = false
                           
                        })
                        .catch(() => {
                            this.table.exportLoading = false
                        })
                }
            ]
        ])
        const action = actionFun.get(event) || actionFun.get('default')
        action!.call(this)
    }
}
