import React, { Component } from 'react'
import { Form, Input, InputNumber, Radio, Select, Spin, Switch, TreeSelect } from 'antd'
import { AntIcon, IconSelector } from 'components'
import { cloneDeep } from 'lodash'
import getDictData from 'util/dic'
import { api } from 'common/api'
import { EMPTY_ID } from 'util/global'

const initialValues = {
    type: 1,
    openType: 1,
    weight: '2',
    visible: true,
    sort: 100,
}

export default class form extends Component {
    state = {
        // 加载状态
        loading: true,
        codes: {
            menuType: [],
            openType: [],
            menuWeight: [],
        },
        options: {
            appList: [],
            parentTreeData: [],
        },

        addType: [],
        type: initialValues.type,
        openType: initialValues.openType,
        icon: '',
    }

    // 表单实例
    form = React.createRef()

    iconSelector = React.createRef()

    // 初始化数据
    record = {}

    /**
     * mount后回调
     */
    componentDidMount() {
        this.props.created && this.props.created(this)
    }

    /**
     * 填充数据
     * 可以在设置this.record之后对其作出数据结构调整
     * [异步,必要]
     * @param {*} params
     */
    async fillData(params) {
        const form = this.form.current
        this.record = cloneDeep(params.record)
        //#region 从后端转换成前段所需格式
        const codes = await getDictData('menu_type', 'open_type', 'menu_weight')
        const appList = await this.onLoadSysApplist()
        let parentTreeData = []
        if (params.isParent) {
            parentTreeData = await this.onLoadMenuTree(params.parent.application)
        }

        if (params.record) {
            parentTreeData = await this.onLoadMenuTree(params.record.application)
        } else {
            this.setState({ addType: params.addType })
            if (params.addType.length) {
                form.setFieldsValue({
                    type: params.addType[0],
                })
            }
        }
        const icon = params.record && params.record.icon
        this.setState({
            codes,
            options: {
                appList,
                parentTreeData,
            },
            icon,
        })
        //#endregion
        if (params.isParent) {
            form.setFieldsValue({
                pid: params.parent.id,
                application: params.parent.application,
            })
        } else {
            form.setFieldsValue(this.record)
        }

        this.setState({ loading: false })

        this.onTypeChange()
    }

    /**
     * 获取数据
     * 可以对postData进行数据结构调整
     * [异步,必要]
     * @returns
     */
    async getData() {
        const form = this.form.current

        const valid = await form.validateFields()
        if (valid) {
            const postData = form.getFieldsValue()
            if (this.record) {
                postData.id = this.record.id
            }
            //#region 从前段转换后端所需格式
            // 目录的pic必须为空
            if (!postData.type) {
                postData.pid = EMPTY_ID
            }
            //#endregion
            return postData
        }
    }

    //#region 自定义方法
    async onLoadSysApplist() {
        const { data } = await api.getAppList()
        return data
    }

    async onLoadMenuTree(application) {
        const { data } = await api.getMenuTree({ application })
        return [
            {
                id: EMPTY_ID,
                parentId: undefined,
                title: '顶级',
                value: EMPTY_ID,
                pid: undefined,
                children: data,
            },
        ]
    }

    onTypeChange() {
        this.onTypeChangeGroup()
        // const form = this.form.current
        // const { type } = form.getFieldsValue()
        // if ([0, 2].includes(type)) {
        //     form.setFieldsValue({
        //         openType: 0,
        //     })
        // } else {
        //     form.setFieldsValue({
        //         openType: 1,
        //     })
        // }
    }

    onOpenTypeChange() {
        this.onTypeChangeGroup()
    }

    onTypeChangeGroup() {
        const form = this.form.current
        const { type, openType } = form.getFieldsValue()
        // if (type == 1 && openType == 2) {
        //     form.setFieldsValue({
        //         component: 'iframe'
        //     })
        // } else {
        //     form.setFieldsValue({
        //         component: ''
        //     })
        // }

        this.setState({
            type,
            openType,
        })
    }

    async onApplicationChange(value) {
        this.setState({
            loading: true,
        })
        const parentTreeData = await this.onLoadMenuTree(value)
        this.setState({
            loading: false,
            options: {
                ...this.state.options,
                parentTreeData,
            },
        })
        this.form.current.setFieldsValue({
            pid: undefined,
        })
    }

    onSelectIcon(icon) {
        this.form.current.setFieldsValue({
            icon,
        })
        this.setState({ icon })
    }
    //#endregion

    render() {
        const { loading, codes, options, addType, type, openType, icon } = this.state

        return (
            <Form initialValues={initialValues} ref={this.form} className="yo-form">
                <Spin spinning={loading} indicator={<AntIcon type="loading" />}>
                    <div className="yo-form-group">
                        <h3 className="h3">基本信息</h3>
                        <div className="yo-form-group">
                            <Form.Item
                                label="菜单类型"
                                name="type"
                                tooltip={
                                    <>
                                        目录：一级菜单，默认添加在顶级
                                        <br />
                                        菜单：二级菜单
                                        <br />
                                        按钮：菜单中对应到接口的功能
                                    </>
                                }
                                rules={[{ required: true, message: '请选择菜单类型' }]}
                            >
                                <Radio.Group onChange={e => this.onTypeChange(e)}>
                                    {codes.menuType.map(item => {
                                        return (
                                            <Radio.Button
                                                key={item.code}
                                                value={+item.code}
                                                disabled={!addType.includes(+item.code)}
                                            >
                                                {item.value}
                                            </Radio.Button>
                                        )
                                    })}
                                </Radio.Group>
                            </Form.Item>
                            <Form.Item
                                label="名称"
                                name="name"
                                rules={[{ required: true, message: '请输入名称' }]}
                            >
                                <Input autoComplete="off" placeholder="请输入名称" />
                            </Form.Item>
                            <Form.Item label="唯一编码" name="code">
                                <Input autoComplete="off" placeholder="请输入唯一编码" />
                            </Form.Item>
                            <Form.Item
                                label="所属应用"
                                name="application"
                                rules={[{ required: true, message: '请选择所属应用' }]}
                            >
                                <Select
                                    placeholder="请选择所属应用"
                                    onChange={value => this.onApplicationChange(value)}
                                >
                                    {options.appList.map(item => {
                                        return (
                                            <Select.Option key={item.code} value={item.code}>
                                                {item.name}
                                            </Select.Option>
                                        )
                                    })}
                                </Select>
                            </Form.Item>
                            {type != 0 && (
                                <Form.Item
                                    label="父级菜单"
                                    name="pid"
                                    rules={[{ required: true, message: '请选择父级' }]}
                                >
                                    <TreeSelect
                                        dropdownStyle={{ maxHeight: '300px', overflow: 'auto' }}
                                        treeData={options.parentTreeData}
                                        placeholder="请选择父级菜单"
                                    />
                                </Form.Item>
                            )}
                            <Form.Item
                                label="权重"
                                name="weight"
                                tooltip={
                                    <>
                                        系统权重：菜单/功能任何角色可用
                                        <br />
                                        业务权重：菜单/功能为超级管理员不可用，可防止管理员误操作
                                    </>
                                }
                                rules={[{ required: true, message: '请选择权重' }]}
                            >
                                <Radio.Group>
                                    {codes.menuWeight.map(item => {
                                        return (
                                            <Radio.Button key={item.code} value={item.code}>
                                                {item.value}
                                            </Radio.Button>
                                        )
                                    })}
                                </Radio.Group>
                            </Form.Item>
                        </div>
                        <h3 className="h3">扩展信息</h3>
                        <div className="yo-form-group">
                            {type == 1 && (
                                <Form.Item label="打开方式" name="openType">
                                    <Radio.Group onChange={e => this.onOpenTypeChange(e)}>
                                        {codes.openType.map(item => {
                                            return (
                                                <Radio.Button key={item.code} value={+item.code}>
                                                    {item.value}
                                                </Radio.Button>
                                            )
                                        })}
                                    </Radio.Group>
                                </Form.Item>
                            )}
                            {type == 1 && openType == 1 && (
                                <Form.Item
                                    label="前端组件"
                                    name="component"
                                    tooltip="打开新页签并渲染前端组件"
                                    rules={[{ required: true, message: '请输入前端组件' }]}
                                >
                                    <Input autoComplete="off" placeholder="请输入前端组件" />
                                </Form.Item>
                            )}
                            {type == 1 && openType == 2 && (
                                <Form.Item
                                    label="内链地址"
                                    name="link"
                                    tooltip="打开新页签并使用iframe加载页面"
                                    rules={[{ required: true, message: '请输入内链地址' }]}
                                >
                                    <Input autoComplete="off" placeholder="请输入内链地址" />
                                </Form.Item>
                            )}
                            {type == 1 && openType == 3 && (
                                <Form.Item
                                    label="外链地址"
                                    name="redirect"
                                    tooltip="打开新的浏览器窗口"
                                    rules={[{ required: true, message: '请输入外链地址' }]}
                                >
                                    <Input autoComplete="off" placeholder="请输入外链地址" />
                                </Form.Item>
                            )}
                            {type == 2 && (
                                <Form.Item
                                    label="权限标识"
                                    name="permission"
                                    rules={[{ required: true, message: '请输入权限标识' }]}
                                >
                                    <Input autoComplete="off" placeholder="请输入权限标识" />
                                </Form.Item>
                            )}
                            {type == 2 && (
                                <Form.Item
                                    label="关联上级菜单显示"
                                    name="visibleParent"
                                    valuePropName="checked"
                                >
                                    <Switch />
                                </Form.Item>
                            )}
                            <Form.Item label="可见性" name="visible" valuePropName="checked">
                                <Switch />
                            </Form.Item>
                            {type != 2 && (
                                <Form.Item label="图标" name="icon">
                                    <Input
                                        disabled
                                        placeholder="请选择图标"
                                        addonBefore={icon && <AntIcon type={icon} />}
                                        addonAfter={
                                            <AntIcon
                                                type="setting"
                                                onClick={() =>
                                                    this.iconSelector.current.open(
                                                        this.form.current.getFieldValue('icon')
                                                    )
                                                }
                                            />
                                        }
                                    />
                                </Form.Item>
                            )}
                            <Form.Item label="排序" name="sort">
                                <InputNumber
                                    max={1000}
                                    min={0}
                                    className="w-100-p"
                                    placeholder="请输入排序"
                                />
                            </Form.Item>
                            <Form.Item label="备注信息" name="remark">
                                <Input.TextArea placeholder="请输入备注信息" />
                            </Form.Item>
                        </div>
                    </div>
                </Spin>

                <IconSelector ref={this.iconSelector} onSelect={icon => this.onSelectIcon(icon)} />
            </Form>
        )
    }
}
