import React, { Component } from 'react'
import { Button, Card, Form, Input, Popconfirm, message as Message, InputNumber } 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.sysDictDataPage,
    add: api.sysDictDataAdd,
    edit: api.sysDictDataEdit,
    delete: api.sysDictDataDelete,
    deleteBatch: api.sysDictDataDeleteBatch,
}

// 用于弹窗标题
const name = '字典值'

export default class index extends Component {
    state = {
        codes: {
            commonStatus: [],
        },

        selectedRowKeys: [],
    }

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

    form = React.createRef()

    // JSON编辑窗口实例
    jsonForm = React.createRef()

    // 表格字段
    columns = [
        {
            title: '文本',
            dataIndex: 'value',
            sorter: true,
            width: 200,
            render: (text, record, index) => (
                <Form.Item
                    name={[index, 'value']}
                    rules={[{ required: true, message: '请输入文本' }]}
                    className="mb-none"
                >
                    <Input autoComplete="off" placeholder="请输入文本" />
                </Form.Item>
            ),
        },
        {
            title: '字典值',
            dataIndex: 'code',
            sorter: true,
            width: 200,
            render: (text, record, index) => (
                <Form.Item
                    name={[index, 'code']}
                    rules={[{ required: true, message: '请输入文本' }]}
                    className="mb-none"
                >
                    <Input autoComplete="off" placeholder="请输入字典值" />
                </Form.Item>
            ),
        },
        {
            title: '扩展值',
            dataIndex: 'extCode',
            width: 80,
            align: 'center',
            render: (text, record, index) => (
                <>
                    <Form.Item name={[index, 'extCode']} className="hidden">
                        <Input type="hidden" />
                    </Form.Item>
                    {auth('sysDictData:edit') ? (
                        <a
                            onClick={() => this.onOpen(this.jsonForm, record)}
                            style={{
                                fontWeight: 'bold',
                                display: 'inline-block',
                                transform: 'scaleY(.85)',
                                color: 'transparent',
                                backgroundImage: 'linear-gradient(135deg, #007bff, #52c41a)',
                                WebkitBackgroundClip: 'text',
                            }}
                        >
                            JSON
                        </a>
                    ) : (
                        <>{text}</>
                    )}
                </>
            ),
        },
        {
            title: '排序',
            dataIndex: 'sort',
            sorter: true,
            width: 100,
            render: (text, record, index) => (
                <Form.Item name={[index, 'sort']} className="mb-none">
                    <InputNumber
                        max={1000}
                        min={0}
                        step={1}
                        className="w-100-p"
                        autoComplete="off"
                        placeholder="排序"
                    />
                </Form.Item>
            ),
            defaultSortOrder: 'ascend',
        },
        {
            title: '备注',
            dataIndex: 'remark',
            sorter: true,
            render: (text, record, index) => (
                <Form.Item name={[index, 'remark']} className="mb-none">
                    <Input autoComplete="off" placeholder="请输入备注" />
                </Form.Item>
            ),
        },
        {
            title: '状态',
            dataIndex: 'status',
            sorter: true,
            width: 80,
            render: text => this.bindCodeValue(text, 'common_status'),
        },
    ]

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

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

        if (flag) {
            this.columns.push({
                title: '操作',
                width: 150,
                dataIndex: 'actions',
                render: (text, record, index) => (
                    <QueryTableActions>
                        {record.id !== -1 ? (
                            <Auth auth="sysDictData:edit">
                                <a onClick={() => this.onEdit(index)}>保存编辑</a>
                            </Auth>
                        ) : (
                            <Auth auth="sysDictData:add">
                                <a onClick={() => this.onAdd(index)}>保存新增</a>
                            </Auth>
                        )}
                        <Auth auth="sysDictData:delete">
                            <Popconfirm
                                placement="topRight"
                                title="是否确认删除"
                                onConfirm={() => this.onDelete(record)}
                            >
                                <a>删除</a>
                            </Popconfirm>
                        </Auth>
                    </QueryTableActions>
                ),
            })
        }
    }

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

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

    /**
     * 调用加载数据接口,可在调用前对query进行处理
     * [异步,必要]
     * @param {*} params
     * @param {*} query
     * @returns
     */
    loadData = async (params, query) => {
        query = {
            ...query,
            typeId: this.props.type.id,
        }

        const { data } = await apiAction.page({
            ...params,
            ...query,
        })

        const values = {}
        data.items.forEach((item, index) => {
            values[index] = item
        })

        this.form.current.setFieldsValue(values)

        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) {
        modal.current.open({
            record,
        })
    }

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

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

    //#region 自定义方法
    onAddRow() {
        const record = {
            // 为了正常显示checkbox,默认给id赋予了-1
            id: -1,
            value: '',
            code: '',
            typeId: this.props.type.id,
            sort: 100,
            status: 0,
            remark: null,
        }
        const index = this.table.current.onAddRow(record)
        if (index !== false) {
            this.form.current.setFieldsValue({
                [index]: record,
            })
        }
    }

    async onAdd(index) {
        const form = this.form.current
        try {
            await form.validateFields()
        } catch (err) {
            const e = err.errorFields.filter(item => item.name.includes(index))
            if (e.length) {
                return
            }
        }
        const record = form.getFieldsValue([index])[index]
        // 为了正常显示checkbox,默认给id赋予了-1,在这里删除id以表示新增
        record.id = undefined
        this.onAction(apiAction.add(record), '新增成功')
    }

    async onEdit(index) {
        const form = this.form.current
        try {
            await form.validateFields()
        } catch (err) {
            const e = err.errorFields.filter(item => item.name.includes(index))
            if (e.length) {
                return
            }
        }
        const record = form.getFieldsValue([index])[index]
        this.onAction(apiAction.edit(record), '编辑成功', false)
    }

    async onDeleteBatch() {
        await this.onAction(apiAction.deleteBatch(this.state.selectedRowKeys), '删除成功')

        this.setState({
            selectedRowKeys: [],
        })
    }

    onSaveExtCode = ({ id, extCode }) => {
        const table = this.table.current,
            { dataSource } = table.state,
            data = dataSource.find(item => item.id === id),
            index = dataSource.indexOf(data)
        this.form.current.setFieldsValue({
            [index]: {
                extCode,
            },
        })
        dataSource[index].extCode = extCode
        table.setState({ dataSource })
    }
    //#endregion

    render() {
        const { selectedRowKeys } = this.state

        return (
            <Container mode="fluid">
                <br />
                <Card>
                    <QueryTable
                        ref={this.table}
                        autoLoad={false}
                        loadData={this.loadData}
                        columns={this.columns}
                        editable={true}
                        form={this.form}
                        sticky={false}
                        rowSelection={{
                            selectedRowKeys,
                            onChange: selectedRowKeys => this.setState({ selectedRowKeys }),
                            getCheckboxProps: record => ({
                                disabled: record.id === -1,
                            }),
                        }}
                        query={
                            <Auth auth="sysDictData:page">
                                <Form.Item label="文本" name="value">
                                    <Input autoComplete="off" placeholder="请输入文本" />
                                </Form.Item>
                                <Form.Item label="字典值" name="code">
                                    <Input autoComplete="off" placeholder="请输入字典值" />
                                </Form.Item>
                            </Auth>
                        }
                        operator={
                            <Auth auth="sysDictData:delete">
                                <Popconfirm
                                    disabled={!selectedRowKeys.length}
                                    placement="bottom"
                                    title="是否确认批量删除"
                                    onConfirm={() => this.onDeleteBatch()}
                                >
                                    <Button disabled={!selectedRowKeys.length} danger>
                                        批量删除
                                    </Button>
                                </Popconfirm>
                            </Auth>
                        }
                        footer={() => (
                            <Auth auth="sysDictData:add">
                                <Button
                                    block
                                    icon={<AntIcon type="plus" />}
                                    onClick={() => this.onAddRow()}
                                >
                                    新增{name}
                                </Button>
                            </Auth>
                        )}
                    />
                </Card>

                <ModalForm title="编辑" action={this.onSaveExtCode} ref={this.jsonForm}>
                    <FormBody />
                </ModalForm>
            </Container>
        )
    }
}
