export default {
    props: {
        loadData: {
            type: Function,
            require: true,
        },

        autoLoad: {
            type: Boolean,
            default: true
        },

        defaultSelectedKeys: {
            type: Array,
            default: []
        }
    },

    data() {
        return {
            loading: false,

            data: [],
            list: []
        }
    },

    created() {
        if (this.autoLoad) {
            this.onLoadData()
        }
    },

    methods: {

        renderDescriptions(data) {
            return data.map(p => {
                return p.children && p.children.length ? this.renderItem(p) : this.renderCheckbox(p)
            })
        },

        renderItem(data) {
            return (
                <a-descriptions bordered column={1}>
                    <a-descriptions-item>
                        <a-checkbox
                            slot="label"
                            value={data.id}
                            checked={data.checked}
                            indeterminate={data.indeterminate}
                            onChange={(e) => this.onChange(e, data)}
                        >{data.title}</a-checkbox>
                        {this.renderDescriptions(data.children)}
                    </a-descriptions-item>
                </a-descriptions>
            )
        },

        renderCheckbox(data) {
            return (
                <div class="yo-authority-view--checkbox">
                    <a-checkbox
                        value={data.id}
                        checked={data.checked}
                        onChange={(e) => this.onChange(e, data)}
                    >{data.title}</a-checkbox>
                </div>
            )
        },

        onLoadData() {
            this.loading = true

            this.loadData().then((res) => {
                this.data = this.generateCheck(res)

                this.list = []
                this.generateList(this.data)

                if (this.defaultSelectedKeys.length) {
                    this.list.map(p => {
                        if (this.defaultSelectedKeys.indexOf(p.id) > -1 && (!p.children || !p.children.length)) {
                            this.onSelect(true, p)
                        }
                    })
                }

                this.loading = false
            })
        },

        onReloadData() {

            this.data = []
            this.onLoadData()

        },

        onChange(e, item) {

            this.onSelect(e.target.checked, item)

            this.$emit('select', this.list.filter(p => p.checked).map(p => p.id), this.list.filter(p => p.checked || p.indeterminate).map(p => p.id))
        },

        onSelect(check, item) {
            item.checked = check
            item.indeterminate = false
            if (item.children && item.children.length) {
                this.onChangeChildren(item.checked, item.children)
            }
            if (item.parentId) {
                this.onChangeParent(item.checked, item.parentId)
            }
        },

        onChangeParent(checked, parentId) {
            const parent = this.list.find(p => p.id === parentId)
            if (parent) {
                const checkedCount = parent.children.filter(p => p.checked).length
                const indeterminateCount = parent.children.filter(p => p.indeterminate).length
                if (checkedCount === parent.children.length) {
                    // 全选
                    parent.checked = true
                    parent.indeterminate = false
                } else if (!checkedCount && !indeterminateCount) {
                    // 全不选
                    parent.checked = false
                    parent.indeterminate = false
                } else {
                    // 半选
                    parent.checked = false
                    parent.indeterminate = true
                }
                this.onChangeParent(checked, parent.parentId)
            }
        },

        onChangeChildren(checked, children) {
            children.forEach(p => {
                p.checked = checked
                p.indeterminate = false
                if (p.children && p.children.length) {
                    this.onChangeChildren(checked, p.children)
                }
            })
        },

        generateCheck(data) {
            data.forEach(p => {
                if (p.children && p.children.length) {
                    p.children = this.generateCheck(p.children)
                }
                p.checked = false
                p.indeterminate = false
            })

            return data
        },

        generateList(data) {
            data.forEach(p => {
                if (p.children && p.children.length) {
                    this.generateList(p.children)
                }
                this.list.push(p)
            })
        },

    },

    render() {
        return (
            <div class="yo-authority-view">
                <a-spin style={{ width: '100%' }} spinning={this.loading}>
                    <a-icon slot="indicator" type="loading" spin />
                    {
                        !this.loading &&
                        <a-descriptions bordered column={1}>
                            {
                                this.data.map(p => {
                                    return (
                                        <a-descriptions-item>
                                            <a-checkbox
                                                slot="label"
                                                value={p.id}
                                                checked={p.checked}
                                                indeterminate={p.indeterminate}
                                                onChange={(e) => this.onChange(e, p)}
                                            >{p.title}</a-checkbox>
                                            {this.renderDescriptions(p.children)}
                                        </a-descriptions-item>
                                    )
                                })
                            }
                        </a-descriptions>
                    }
                </a-spin>
            </div>
        )
    }
}