import React, { Component } from 'react'
import { Spin, Layout } from 'antd'
import { api } from 'common/api'
import { cloneDeep, groupBy, findIndex, last } from 'lodash'
import store from 'store'
import { EMPTY_ID, SIDER_BREAK_POINT } from 'util/global'

import Header from './_layout/header'
import Sider from './_layout/sider'
import Content from './_layout/content'

const { dispatch } = store

const serializeMenu = menus => {
    const menu = cloneDeep(menus)
    const children = groupBy(menu, 'pid')

    const serialize = m => {
        m.forEach(p => {
            if (children[p.id]) {
                p.children = serialize(children[p.id])
            }
        })
        return m
    }

    return children[EMPTY_ID] ? serialize(children[EMPTY_ID]) : []
}

const setNav = async nav => {
    const getNav = []
    nav.apps.forEach(app => {
        const menu = serializeMenu(nav.menus.filter(p => p.application === app.code))

        getNav.push({
            app,
            menu,
        })
    })
    return getNav
}

const getNewID = () => {
    return Math.random().toString(16).slice(2)
}

export default class index extends Component {
    state = {
        loading: true,
        panes: [],
        actived: '',
        test: 0,
    }

    componentDidMount() {
        window.openContentWindow = this.onOpenContentWindow
        window.closeContentWindow = this.onCloseContentWindow
        window.closeOtherContentWindow = this.onCloseOtherContentWindow
        window.closeRightContentWindow = this.onCloseRightContentWindow

        api.getLoginUser().then(async ({ data }) => {
            const nav = await setNav(data)

            dispatch({
                type: 'SET_USER_ACCOUNT',
                user: data,
            })

            dispatch({
                type: 'SET_NAV',
                nav,
            })

            this.setState({ loading: false }, () => {
                this.onOpenContentWindow({
                    title: '工作台',
                    path: '/home',
                    icon: 'home',
                    closable: false,
                })
            })
        })

        window.addEventListener('resize', this.onResizeSider)
        this.onResizeSider()
    }

    /**
     * 打开窗口
     * @param {*} settings
     * @returns
     */
    onOpenContentWindow = settings => {
        if (settings.path) {
            const key = settings.key || getNewID()

            /**
             * 如果当前标签页已打开,则只需要选中
             */
            const pane = this.state.panes.find(p => p.key === key)
            if (pane) {
                this.onChangeContentWindow(key)
                return
            }

            let path = (p => {
                if (p.startsWith('http')) return p
                if (p.startsWith('/')) return p
                else return `/${p}`
            })(settings.path)

            if ([2, 3].includes(settings.openType)) {
                const param = (p => {
                    const arr = []
                    if (p && p.constructor === Object) {
                        Object.keys(p).forEach(key => {
                            arr.push(`${key}=${(p[key] || '').toString()}`)
                        })
                    }
                    return arr.join('&')
                })(settings.param)

                path += param ? `?${param}` : ''

                if (settings.openType === 3) {
                    // 打开新的浏览器窗口
                    window.open(path)
                    return
                }
            }

            /**
             * 向标签页队列中添加一个新的标签页
             */
            const newPane = {
                key,
                closable: settings.closable === undefined ? true : settings.closable,
                icon: settings.icon,
                title: settings.title || '新建窗口',
                subTitle: settings.subTitle,
                component: null,
                path,
                param: settings.param,
                loaded: false,
                openType: settings.openType || 1,
            }

            this.setState({
                panes: [...this.state.panes, newPane],
            })

            this.onChangeContentWindow(key)

            //this.$refs.content.onLoadContentWindow(key);
        } else {
            console.warn('wrong component path')
        }
    }

    /**
     * 关闭窗口
     * @param {*} key
     */
    onCloseContentWindow = key => {
        key = key || this.state.actived
        const panes = this.state.panes
        const i = findIndex(panes, p => p.key === key)
        panes.splice(i, 1)

        this.setState(
            {
                panes,
            },
            () => {
                if (panes.length) {
                    if (key === this.state.actived) {
                        const pane = panes[i]
                        if (pane) {
                            this.onChangeContentWindow(pane.key)
                        } else {
                            this.onChangeContentWindow(panes[i - 1].key)
                        }
                    }
                }
            }
        )
    }

    onCloseOtherContentWindow = key => {
        if (!key) return

        const panes = this.state.panes
        let flag = false
        for (let i = panes.length - 1; i >= 0; i--) {
            const p = panes[i]
            if (p.key !== key && p.closable) {
                if (p.key === this.state.actived) {
                    flag = true
                }
                panes.splice(i, 1)
            }
        }

        this.setState(
            {
                panes,
            },
            () => {
                if (flag) {
                    this.onChangeContentWindow(last(panes).key)
                }
            }
        )
    }

    onCloseRightContentWindow = key => {
        if (!key) return

        const panes = this.state.panes
        let flag = false
        for (let i = panes.length - 1; i >= 0; i--) {
            const p = panes[i]
            if (p.key !== key && p.closable) {
                if (p.key === this.tabActived) {
                    flag = true
                }
                panes.splice(i, 1)
            } else if (p.key === key) {
                break
            }
        }

        this.setState(
            {
                panes,
            },
            () => {
                if (flag) {
                    this.onChangeContentWindow(last(panes).key)
                }
            }
        )
    }

    onReloadContentWindow = key => {
        if (!key) key = this.state.actived
        //this.$refs.content.onLoadContentWindow(key);
    }

    /**
     * 选中窗口
     * @param {*} key
     */
    onChangeContentWindow = key => {
        this.setState({
            actived: key,
        })
    }

    onResizeSider = () => {
        dispatch({
            type: 'AUTO_TOGGLE_COLLAPSED',
            siderCollapsed: window.innerWidth <= SIDER_BREAK_POINT,
        })
    }

    render() {
        const { loading, panes, actived } = this.state

        return (
            <section className="yo-layout--spin">
                <Spin
                    spinning={loading}
                    indicator={
                        <div className="loader-container">
                            <p>Loading</p>
                        </div>
                    }
                >
                    <Layout className="yo-layout--top-nav--container-fluid yo-layout--top-nav">
                        <Layout>
                            <Header />
                            <Layout className="yo-nav-theme--light">
                                <Sider />
                                <Content parent={this} panes={panes} actived={actived} />
                            </Layout>
                        </Layout>
                    </Layout>
                </Spin>
            </section>
        )
    }
}
