<template>
    <div :style="style">
        <!-- 标题区 -->
        <!-- 表格区 -->
        <ag-grid-vue
            class="table ag-theme-material"
            :class="`ag-theme-${theme}`"
            ref="grid"
            style="width: 100%;"
            :style="gridStyle"
            :gridOptions="gridOptions"
            :onGridReady="onGridReady"
            :columnDefs="formatedColumns"
            :rowData="rowData"
            :frameworkComponents="frameworkComponents"
            :suppressPaginationPanel="true"
            :animateRows="true"
            :localeText="localeText"
            :context="context"
        ></ag-grid-vue>
        <!-- 工具栏区 -->
        <div class="toolbox">
            <div class="tools-item toolbar">
                <Button
                    type="primary"
                    size="small"
                    icon="md-refresh"
                    class="toolbar-item"
                    v-if="tools.indexOf('refresh') > -1"
                    @click="load()"
                ></Button>
                <Button
                    type="primary"
                    size="small"
                    icon="md-print"
                    class="toolbar-item"
                    v-if="tools.indexOf('print') > -1"
                    @click="print"
                ></Button>
                <Button
                    type="primary"
                    size="small"
                    icon="md-document"
                    class="toolbar-item"
                    v-if="tools.indexOf('exportCsv') > -1"
                    @click="exportCsv"
                ></Button>
                <Button
                    type="primary"
                    size="small"
                    icon="md-search"
                    class="toolbar-item"
                    v-if="tools.indexOf('fastquery') > -1 && pagerOpts && pagerOpts.loadUrl"
                    @click="fastQueryShow = true"
                ></Button>
            </div>
            <Page
                class="tools-item"
                v-if="pagerOpts"
                :current="pager.nowPage"
                :page-size="pager.pageSize"
                :total="pager.recordCount"
                show-elevator
                show-sizer
                show-total
                :page-size-opts="pageSizeOpts"
                transfer
                @on-change="pageChange"
                @on-page-size-change="pageSizeChange"
            />
        </div>
        <FastQueryModal
            :columns="flatColumns"
            v-model="fastQueryShow"
            :dicts="dicts"
            @on-search="onFastQuerySearch"
        ></FastQueryModal>
        <Spin fix v-if="loading" size="large">
            <Icon type="ios-loading" size="50" class="demo-spin-icon-load"></Icon>
            <div>Loading</div>
        </Spin>
    </div>
</template>
<script>
// 基于ag-grid开发的组件
// 特点（* 为目标） ：
// 1、能够直接使用ag-grid的大部分特性
// 2、通过简单的设置完成基本的表格展示功能
// 3、*热拔插式表格组件
import { AgGridVue } from "ag-grid-vue";

//单元格组件
import BtnsInCell from './cellComponents/btnsInCell.js';
import TranslateCell from './cellComponents/translateCell.js';
import BooleanCell from './cellComponents/booleanCell.js';
import ImgCell from './cellComponents/imgCell.js';
import QrcodeCell from './cellComponents/qrcodeCell.js';
//过滤组件
import DictFilter from './filter/dictFilter.js';
//编辑组件
import DictCellEditor from './editComponents/dictCellEditor';
//状态栏组件

import toGridColumns from './convert/columnTrans';
import flat from './convert/flat';

import afterLoad from './afterLoad' //读取数据后的处理方法，包括异步翻译与小计
import { tools, http } from 'hq-tools';
import localeText from './options/localeText';//本地化翻译
import columnTypes from './options/columnTypes';
import defaultColDef from './options/defaultColDef';

import FastQueryModal from './fastQuery/fastQueryModal';

import info from './info'
//默认表格被指选项
const gridOptsDefs = {
    defaultColDef,
    columnTypes,
    rowIndex: true,
    rowSelection: null,
    subTotal:false,
    suppressRowClickSelection: true,
    enableCellTextSelection: true,
    enableBrowserTooltips: true,
}
export default {
    name: 'hq-grid',
    components: {
        AgGridVue,
        FastQueryModal
        //按钮
        //图片
        //二维码
    },
    props: {
        //表格名
        name: {
            type: String,
            default() {
                return 'table';
            }
        },
        //主题
        theme: {
            type: String,
            default() {
                return 'material';
            },
            validator(theme) {
                if (['balham', 'material', 'fresh', 'blue', 'dark', 'bootstrap'].indexOf(theme) > -1) {
                    return true;
                };
            },
        },
        //字典
        dicts: {
            type: Object,
            default() {
                return {};
            }
        },
        //列定义
        columns: {
            type: Array,
            default() {
                return [];
            }
        },
        //数据
        data: {
            type: Array,
            default() {
                return [];
            }
        },
        //分页功能设置，包括【远程分页接口url】
        pagerOpts: {
            type: Object,
            default() {
                return {
                    loadUrl: null
                };
            }
        },
        //表格设置
        gridOpts: {
            type: Object,
            default(value) {
                return {};
            }
        },
        //每页尺寸可选列表
        pageSizeOpts: {
            type: Array,
            default() {
                return [10, 50, 100, 500];
            }
        },
        //左下方工具条
        tools: {
            type: Array,
            validator(tools) {
                for (let tool of tools) {
                    if (['exportCsv', 'print', 'exportExcel', 'refresh', 'fastquery'].indexOf(tool) < 0) {
                        return false;
                    }
                }
                return true;
            },
            default() {
                return ['exportExcel', 'refresh', 'fastquery'];
            }
        },
        //扩展组件，当需要使用自定义组件时接入
        extraFrameworkComponents: {
            type: Object,
            validator(extraFrameworkComponents) {
                return extraFrameworkComponents;
            },
            default() {
                return null;
            }
        },
        height: {
            type: String,
            default() {
                return null;
            }
        },
    },
    data() {
        return {
            //实际应用与表格的表格设置选项
            gridOptions: null,
            //表格的api，单独提出方便调用
            gridApi: null,
            //列的api，单独提出方便调用
            columnApi: null,
            //实际应用于表格的列定义
            columnDefs: null,
            //表格用组件
            frameworkComponents: {},
            //表格本地化文件
            localeText: localeText,
            //赋予列id后的列定义，必须赋予列id以便各种组件能准确识别当前列
            idedColumns: [],
            //实际应用与表格的数据，不管是远程获取的分页数据还是本地传入的数据
            rowData: [],
            //分页传输实体，与后端pagerModel对应
            pager: {
                nowPage: 1,
                pageSize: 10,
                pageCount: 0,
                recordCount: 0,
                errorMessage: null,
                exhibitDatas: [],
                externalObj: {},
                externalParameters: [],
                fastQueryParameters: []
            },
            //表格实际使用字典，传入字典与异步翻译的字典都在这里
            gridDicts: {},
            //混合后的表格设置选项，中间变量
            gridmixinedOpts: {},
            //前后文，用于表格内部组件调用等
            context: null,
            //高级查询弹出
            fastQueryShow: false,
            //高级查询输出
            advanceFastQueryParams: [],
            //读取状态
            loading: false
        }
    },
    computed: {
        formatedColumns() {
            return toGridColumns(this.idedColumns, this.gridmixinedOpts, this.pager);
        },
        style() {
            return {
                'height': this.height ? `${this.height}` : null
            }
        },
        gridStyle() {
            return {
                'height': this.height ? `calc(${this.height} - 50px)` : null
            }
        },
        flatColumns() {
            if (this.context && this.context.flatColumns) {
                return this.context.flatColumns
            }
            return [];
        }
    },
    watch: {
        //当字典变化时自动混入
        dicts(to) {
            this.mixinDict();
        },
        //当数据发生变化时自动重载表格
        data(to) {
            this.load(to);
        }
    },
    beforeMount() {
        this.mixinDict();
        this.gridmixinedOpts = Object.assign({}, gridOptsDefs, this.gridOpts);
        //去掉一些ag-grid不使用的属性，避免控制台的警告
        this.gridOptions = Object.assign({}, this.gridmixinedOpts);
        delete this.gridOptions.subTotal;
        delete this.gridOptions.rowIndex;
        delete this.gridOptions.onBtnClick;

        //pager的初始化
        this.pager.pageSize = this.pageSizeOpts[0];
        this.pager.exhibitDatas = this.data;

        //注册使用的组件
        this.frameworkComponents = Object.assign({}, {
            btnsInCell: BtnsInCell,
            dictFilter: DictFilter,
            dictCellEditor: DictCellEditor,
            booleanCell: BooleanCell,
            translateCell: TranslateCell,
            imgCell:ImgCell,
            qrcodeCell:QrcodeCell
        }, this.extraFrameworkComponents)

        const createUUID = (column, list) => {
            list.push(Object.assign({
                colId: `_row_${tools.createUUID()}`
            }, column));
        }
        const createGroupUUID = (columnGroup, list) => {
            let newGroup = Object.assign({
                groupId: `_row_${tools.createUUID()}`
            }, columnGroup, { children: [] });
            if (columnGroup.children) {
                createID(newGroup.children, columnGroup.children);
            }
            list.push(newGroup);
        }

        const createID = (list, columns) => {
            for (let column of columns) {
                if (column.children) {
                    createGroupUUID(column, list);
                } else {
                    createUUID(column, list);
                }
            }
        }
        this.idedColumns = [];
        createID(this.idedColumns, this.columns);
        //注册事件中使用的前后文
        this.context = {
            gridDicts: this.gridDicts,
            originColumns: this.idedColumns,
            flatColumns: flat(this.idedColumns),
            onBtnClick: this.gridOpts.onBtnClick,
            selectedRow: new Map()
        };
    },
    methods: {
        //混合字典
        mixinDict() {
            let dicts = {}
            const setDicts = (list) => {
                for (let column of list) {
                    if (column.children) {
                        setDicts(column.children);
                    } else {
                        if (column.dict && column.colId) {
                            if (this.dicts[column.dict]) {
                                dicts[column.colId] = this.dicts[column.dict];
                            } else {
                                //console.warn(`字典${column.dict}不存在`);
                            }
                        }
                    }
                }
            }
            setDicts(this.idedColumns);
            this.gridDicts = Object.assign(this.gridDicts, dicts);
        },
        //在表格准备完成后调用
        onGridReady(params) {
            // 获取gridApi
            this.gridApi = params.api;
            this.columnApi = params.columnApi;
            // 调整表格列宽大小自适应
            this.gridApi.sizeColumnsToFit();
            this.$emit('grid-ready', this);
            //console.log(this)
        },
        //高级查询
        onFastQuerySearch(advance) {
            this.advanceFastQueryParams = advance;
            this.load();
        },
        //读取数据
        load(data) {
            const afterLoad = () => {
                let { subTotal } = this.afterLoad();
                if (this.gridmixinedOpts.subTotal) {
                    this.rowData.push(subTotal);
                }
                this.gridApi.sizeColumnsToFit();
            }
            if (data) {
                this.rowData = data;
                return afterLoad();
            }
            if (!this.pagerOpts) {
                return this.$Message.error('表格不是分页类型！')
            }
            if (!this.pagerOpts.loadUrl) {
                return this.$Message.error('pagerOpts缺少属性：loadUrl')
            }
            this.pager = Object.assign(this.pager, this.pagerOpts, {
                fastQueryParameters: [].concat(this.pagerOpts.fastQueryParameters ? this.pagerOpts.fastQueryParameters : []).concat(this.advanceFastQueryParams)
            })
            this.loading = true;
            return new Promise((resolve, reject) => {
                this.$http.getByPager(this.pagerOpts.loadUrl, this.pager)
                    .then(pager => {
                        this.pager = pager;
                        this.rowData = pager.exhibitDatas;
                        afterLoad();
                        resolve({
                            gridApi: this.gridApi,
                            columnApi: this.columnApi
                        });
                        this.$emit('on-load-success', pager)
                    })
                    .catch(error => {
                        console.error(error);
                        reject(error)
                    })
                    .then(data => {
                        this.loading = false;
                    })
            })
            
        },
        afterLoad() {
            return afterLoad(this.rowData, this.idedColumns, this);
        },
        pageChange(nowPage) {
            this.pager.nowPage = nowPage;
            this.load();
        },
        pageSizeChange(pageSize) {
            this.pager.pageSize = pageSize;
            this.load();
        },
        exportCsv() {
            this.gridApi.exportDataAsCsv({
                columnGroups: true,
                fileName: this.name + '.csv',
                customHeader: this.name,
                customFooter: `共${this.pager.pageCount}页，${this.pager.recordCount}条；第${this.pager.nowPage}页`
            });
        },
        //效果不好
        print() {
            this.$refs.grid.$el.style.width = "";
            this.$refs.grid.$el.style.height = "";
            this.gridApi.setDomLayout('print');
            setTimeout(() => {
                print();
                this.$refs.grid.$el.style.width = "100%";
                this.$refs.grid.$el.style.height = this.gridStyle.height;
                this.gridApi.setDomLayout(null);
            }, 2000)
        },
        getSelections(withRowIndex = false) {
            if (withRowIndex) {
                return [...this.context.selectedRow];
            } else {
                return [...this.context.selectedRow].map(item => item[1]);
            }

        },
        showInfo() {
            this.$Modal.info({
                title: '注意事项',
                content: info,
                width:600
            });
        }
    }
}
</script>

<style lang="scss" scoped>
@import "~ag-grid-community/dist/styles/ag-grid.css";
@import "~ag-grid-community/dist/styles/ag-theme-material.css";
@import "~ag-grid-community/dist/styles/ag-theme-balham.css";
@import "~ag-grid-community/dist/styles/ag-theme-fresh.css";
@import "~ag-grid-community/dist/styles/ag-theme-blue.css";
@import "~ag-grid-community/dist/styles/ag-theme-dark.css";
@import "~ag-grid-community/dist/styles/ag-theme-bootstrap.css";
@import "./grid.scss";
</style>