import React, { Component } from 'react'
import { Button, Table, Card, Popconfirm, message as Message, Row, Col, Tooltip, Tag } from 'antd'
import { isEqual } from 'lodash'
import { AntIcon, Auth, Container, ModalForm, QueryTable, QueryTableActions } from 'components'
import { api } from 'common/api'
import getDictData from 'util/dic'
import auth from 'components/authorized/handler'
import { toCamelCase } from 'util/format'
import FormBody from './form'

// 配置页面所需接口函数
const apiAction = {
    page: api.getMenuList,
    add: api.sysMenuAdd,
    edit: api.sysMenuEdit,
    delete: api.sysMenuDelete,
}

// 用于弹窗标题
const name = '菜单'

export default class index extends Component {
    state = {
        codes: {
            menuType: [],
            menuWeight: [],
            openType: [],
        },
    }

    // 表格实例
    table = React.createRef()

    // 新增窗口实例
    addForm = React.createRef()
    // 编辑窗口实例
    editForm = React.createRef()

    // 表格字段
    columns = [
        {
            title: '菜单名称',
            width: 220,
            dataIndex: 'name',
        },
        {
            title: '菜单类型',
            width: 100,
            dataIndex: 'type',
            render: text => this.bindCodeValue(text, 'menu_type'),
        },
        {
            title: '图标',
            width: 100,
            dataIndex: 'icon',
            render: text => text && <AntIcon type={text} />,
        },
        {
            title: '连接',
            width: 220,
            dataIndex: 'openType',
            render: (text, record) => {
                switch (text) {
                    case 1:
                        return (
                            <>
                                <Tag color="green">{this.bindCodeValue(text, 'open_type')}</Tag>{' '}
                                {record.component}
                            </>
                        )
                    case 2:
                        return (
                            <>
                                <Tag color="orange">{this.bindCodeValue(text, 'open_type')}</Tag>{' '}
                                {record.link}
                            </>
                        )
                    case 3:
                        return (
                            <>
                                <Tag color="red">{this.bindCodeValue(text, 'open_type')}</Tag>{' '}
                                {record.redirect}
                            </>
                        )
                    default:
                        return ''
                }
            },
        },
        {
            title: '排序',
            width: 100,
            dataIndex: 'sort',
        },
    ]

    /**
     * 构造函数,在渲染前动态添加操作字段等
     * @param {*} props
     */
    constructor(props) {
        super(props)

        const flag = auth({ sysApp: [['edit'], ['delete']] })

        if (flag) {
            this.columns.push({
                title: '操作',
                width: 220,
                dataIndex: 'actions',
                render: (text, record) => (
                    <QueryTableActions>
                        <Auth auth="sysMenu:edit">
                            <a onClick={() => this.onOpen({ modal: this.editForm, record })}>
                                编辑
                            </a>
                        </Auth>
                        <Auth auth="sysMenu:delete">
                            <Popconfirm
                                placement="topRight"
                                title="是否确认删除"
                                onConfirm={() => this.onDelete(record)}
                            >
                                <a>删除</a>
                            </Popconfirm>
                        </Auth>
                        {record.type < 2 && (
                            <Auth auth="sysMenu:add">
                                <a
                                    onClick={() =>
                                        this.onOpen({
                                            modal: this.addForm,
                                            record,
                                            isParent: true,
                                            addType: record.type == 0 ? [1] : [2],
                                        })
                                    }
                                >
                                    {record.type == 0 ? '新增子菜单' : '新增功能'}
                                </a>
                            </Auth>
                        )}
                    </QueryTableActions>
                ),
            })
        }
    }

    /**
     * 阻止外部组件引发的渲染,提升性能
     * 可自行添加渲染条件
     * [必要]
     * @param {*} props
     * @param {*} state
     * @returns
     */
    shouldComponentUpdate(props, state) {
        return !isEqual(this.state, state)
    }

    /**
     * 加载字典数据,之后开始加载表格数据
     * 如果必须要加载字典数据,可直接对表格设置autoLoad=true
     */
    componentDidMount() {
        this.table.current.onLoading()
        getDictData('menu_type', 'menu_weight', 'open_type').then(res => {
            this.setState(
                {
                    codes: res,
                },
                () => {
                    this.table.current.onLoadData()
                }
            )
        })
    }

    /**
     * 调用加载数据接口,可在调用前对query进行处理
     * [异步,必要]
     * @param {*} params
     * @param {*} query
     * @returns
     */
    loadData = async (params, query) => {
        const { data } = await apiAction.page({
            ...params,
            ...query,
        })
        return data
    }

    /**
     * 绑定字典数据
     * @param {*} code
     * @param {*} name
     * @returns
     */
    bindCodeValue(code, name) {
        name = toCamelCase(name)
        const codes = this.state.codes[name]
        if (codes) {
            const c = codes.find(p => p.code == code)
            if (c) {
                return c.value
            }
        }
        return null
    }

    /**
     * 打开新增/编辑弹窗
     * @param {*} modal
     * @param {*} record
     */
    onOpen({ modal, record, isParent = false, addType = [] }) {
        const params = isParent
            ? {
                  parent: record,
                  isParent,
                  addType,
              }
            : {
                  record,
                  isParent,
                  addType,
              }

        modal.current.open(params)
    }

    /**
     * 对表格上的操作进行统一处理
     * [异步]
     * @param {*} action
     * @param {*} successMessage
     */
    async onAction(action, successMessage) {
        this.table.current.onLoading()
        try {
            await action
            Message.success(successMessage)
            this.table.current.onReloadData()
        } catch {
            this.table.current.onLoaded()
        }
    }

    /**
     * 删除
     * @param {*} record
     */
    onDelete(record) {
        this.onAction(apiAction.delete(record), '删除成功')
    }

    //#region 自定义方法
    /**
     * 绘制新的扩展行
     * @param {*} record
     */
    onRowRender(record) {
        const grids = []
        let isFunction = false
        record.children.map(item => {
            if (!(item.children && item.children.length) && item.type == 2) {
                isFunction = true
                const grid = (
                    <Card.Grid key={item.id}>
                        <p>
                            {item.visibleParent && (
                                <Tooltip placement="top" title="选中此项才会显示菜单">
                                    <AntIcon
                                        type="eye"
                                        style={{ color: '#1890ff' }}
                                        className="mr-xxs"
                                    />
                                </Tooltip>
                            )}
                            <b>{item.name}</b>
                        </p>
                        <span className="block ellipsis text-gray">{item.permission}</span>
                        <div className="text-right">
                            <QueryTableActions>
                                <Auth auth="sysMenu:edit">
                                    <Tooltip title="编辑">
                                        <a
                                            className="link-gray"
                                            onClick={() =>
                                                this.onOpen({ modal: this.editForm, record: item })
                                            }
                                        >
                                            <AntIcon type="edit" />
                                        </a>
                                    </Tooltip>
                                </Auth>
                                <Auth auth="sysMenu:delete">
                                    <Popconfirm
                                        placement="topRight"
                                        title="是否确认删除"
                                        onConfirm={() => this.onDelete(item)}
                                    >
                                        <Tooltip title="删除">
                                            <a className="link-gray">
                                                <AntIcon type="delete" />
                                            </a>
                                        </Tooltip>
                                    </Popconfirm>
                                </Auth>
                            </QueryTableActions>
                        </div>
                    </Card.Grid>
                )
                grids.push(grid)
            } else if (
                (item.children && item.children.length) ||
                (!(item.children && item.children.length) && item.type == 1)
            ) {
                grids.push(item)
            }
        })
        if (isFunction) {
            grids.push(
                <Card.Grid
                    key={0}
                    style={{ padding: '18px 12px', cursor: 'pointer' }}
                    className="text-center"
                    onClick={() =>
                        this.onOpen({ modal: this.addForm, record, isParent: true, addType: [2] })
                    }
                >
                    <div>
                        <AntIcon type="plus" className="text-normal h2" />
                    </div>
                    <span className="text-gray">新增功能</span>
                </Card.Grid>
            )
            return <Card bordered={false}>{grids}</Card>
        } else {
            return (
                <Table
                    columns={this.columns}
                    showHeader={false}
                    dataSource={grids}
                    rowKey={record => record.id}
                    expandable={{
                        expandedRowRender: record => this.onRowRender(record),
                        rowExpandable: record => record.children && record.children.length,
                    }}
                    childrenColumnName="none"
                    bordered={true}
                    pagination={false}
                />
            )
        }
    }
    //#endregion

    render() {
        return (
            <Container mode="fluid">
                <br />
                <Card bordered={false}>
                    <QueryTable
                        className="yo-menu-table"
                        childrenColumnName="none"
                        ref={this.table}
                        autoLoad={false}
                        loadData={this.loadData}
                        columns={this.columns}
                        expandable={{
                            expandedRowRender: record => this.onRowRender(record),
                            rowExpandable: record => record.children && record.children.length,
                        }}
                        operator={
                            <Auth auth="sysMenu:add">
                                <Button
                                    icon={<AntIcon type="plus" />}
                                    onClick={() =>
                                        this.onOpen({ modal: this.addForm, addType: [0, 1] })
                                    }
                                >
                                    新增目录/菜单
                                </Button>
                            </Auth>
                        }
                    />
                </Card>

                <ModalForm
                    title={`新增${name}`}
                    action={apiAction.add}
                    ref={this.addForm}
                    width={800}
                    type="drawer"
                    onSuccess={() => this.table.current.onReloadData()}
                >
                    <FormBody />
                </ModalForm>

                <ModalForm
                    title={`编辑${name}`}
                    action={apiAction.edit}
                    ref={this.editForm}
                    width={800}
                    type="drawer"
                    onSuccess={() => this.table.current.onReloadData()}
                >
                    <FormBody />
                </ModalForm>
            </Container>
        )
    }
}
