import React, { Component } from 'react'
import { Form, Spin, Input, Radio, Select, Upload, Button } from 'antd'
import { api } from 'common/api'
import { AntIcon, BraftEditor } from 'components'
import getDictData from 'util/dic'
import { BlobToBase64, GetFileName, PreviewFile } from 'util/file'
import { cloneDeep } from 'lodash'

const initialValues = {}

export default class form extends Component {
    state = {
        // 加载状态
        loading: true,
        options: {
            userList: [],
        },
        codes: {
            noticeType: [],
            noticeStatus: [],
        },
        funloader: Object,
    }

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

    // 初始化数据
    record = {}

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

    /**
     * 填充数据
     * 可以在设置this.record之后对其作出数据结构调整
     * [异步,必要]
     * @param {*} params
     */
    async fillData(params) {
        this.record = cloneDeep(params.record)
        //#region 从后端转换成前段所需格式,也可以在此处调用获取详细数据接口
        if (params.id) {
            this.record = (await api.sysNoticeDetail({ id: params.id })).data
        }
        const {
            data: { items: userList },
        } = await this.onLoadUser()
        const codes = await getDictData('notice_status', 'notice_type')

        if (this.record) {
            const { attachments } = this.record
            if (attachments) {
                const fileValue = []
                const fileList = attachments.split(',')
                for (const fileId of fileList) {
                    try {
                        const file = await PreviewFile(fileId)
                        const base64 = await BlobToBase64(file)
                        fileValue.push({
                            uid: fileId,
                            response: fileId,
                            name: file.name,
                            url: base64,
                            status: 'done',
                        })
                    } catch {
                        const { data: file } = await api.sysFileInfoDetail({ id: fileId })
                        fileValue.push({
                            uid: fileId,
                            response: '文件已丢失',
                            name: file.fileOriginName,
                            status: 'error',
                        })
                    }
                }
                this.record.attachments = fileValue
            }
        }
        //#endregion
        this.form.current.setFieldsValue(this.record)

        this.setState({
            loading: false,
            options: {
                userList,
            },
            codes,
        })
        //加载 BraftEditor 富文本插件
        this.state.funloader()
    }

    /**
     * 获取数据
     * 可以对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
                postData.status = 0
            } else {
                postData.status = 1
            }
            //#region 从前段转换后端所需格式
            postData.attachments = postData.attachments.map(item =>
                item.uid.startsWith('rc-upload') ? item.response : item.uid
            )
            //#endregion
            return postData
        }
    }

    //#region 自定义方法
    /**
     * 接受子组件传过来的方法
     * 等页面加载完毕后调用
     */
    getChildrenMsg = funLoad => {
        this.setState({
            funloader: funLoad,
        })
    }
    async onLoadUser() {
        const data = await api.getUserPage()
        return data
    }
    async onFileUpload({ file, onProgress, onSuccess, onError }) {
        onProgress({
            percent: 0,
        })
        const fd = new FormData()
        fd.append('file', file)
        try {
            const { data: fileId } = await api.sysFileInfoUpload(fd)
            onSuccess(fileId)
        } catch {
            onError()
        }
    }
    async onFileDownload(file) {
        const { data, headers } = await api.sysFileInfoDownload({ id: file.response })
        const url = window.URL.createObjectURL(data)
        const fileName = GetFileName(headers['content-disposition'])
        const a = document.createElement('a')
        a.href = url
        a.download = fileName
        a.click()
        window.URL.revokeObjectURL(url)
        a.remove()
    }
    //#endregion

    render() {
        const { options, codes } = this.state

        return (
            <Form initialValues={initialValues} ref={this.form} className="yo-form">
                <Spin spinning={this.state.loading} indicator={<AntIcon type="loading" />}>
                    <div className="yo-form-group yo-form--fluid">
                        <Form.Item
                            label="标题"
                            name="title"
                            rules={[{ required: true, message: '请输入标题', trigger: 'blur' }]}
                        >
                            <Input autoComplete="off" placeholder="请输入标题" />
                        </Form.Item>
                        <Form.Item
                            label="类型"
                            name="type"
                            rules={[{ required: true, message: '请选择类型' }]}
                        >
                            <Radio.Group buttonStyle="solid">
                                {codes.noticeType.map(item => (
                                    <Radio.Button key={item.code} value={+item.code}>
                                        {item.value}
                                    </Radio.Button>
                                ))}
                            </Radio.Group>
                        </Form.Item>
                        <Form.Item
                            label="内容"
                            name="content"
                            rules={[
                                { required: true, message: '请输入内容' },
                                {
                                    validator: async (field, value) => {
                                        const v = value.replace(/<\/?.+?\/?>/g, '')
                                        if (!v) {
                                            throw Error('请输入内容')
                                        }
                                    },
                                },
                            ]}
                        >
                            <BraftEditor parent={this} />
                        </Form.Item>
                        <Form.Item
                            label="上传附件"
                            name="attachments"
                            valuePropName="fileList"
                            getValueFromEvent={e => {
                                if (Array.isArray(e)) {
                                    return e
                                }
                                return e && e.fileList
                            }}
                        >
                            <Upload
                                customRequest={e => this.onFileUpload(e)}
                                showUploadList={{
                                    showRemoveIcon: true,
                                    showDownloadIcon: true,
                                }}
                                onPreview={() => false}
                                onDownload={file => this.onFileDownload(file)}
                            >
                                <Button type="dashed" icon={<AntIcon type="upload" />}>
                                    上传附件
                                </Button>
                            </Upload>
                        </Form.Item>
                        <Form.Item label="通知到的人" name="noticeUserIdList">
                            <Select
                                mode="tags"
                                placeholder="请选择通知到的人"
                                tokenSeparators={[',']}
                            >
                                {options.userList.map(item => (
                                    <Select.Option key={item.id} value={item.id}>
                                        {item.name}
                                    </Select.Option>
                                ))}
                            </Select>
                        </Form.Item>
                    </div>
                </Spin>
            </Form>
        )
    }
}
