import React, { Component } from 'react'
import { Divider, Layout, Tabs, Menu, Dropdown } from 'antd'
import NProgress from 'nprogress'
import 'nprogress/nprogress.css'
import AntIcon from 'components/ant-icon'
import { Container } from 'components'

NProgress.configure({
    parent: '.ant-layout-content > .yo-tab-external-mount > .yo-tab-external-mount-content',
})

class ComponentDynamic extends Component {
    state = {
        // 组件内部组件的key,用于刷新
        key: null,
        component: null,
    }

    shouldComponentUpdate() {
        if (this.props.onRef) {
            this.props.onRef(this)
        }
        return true
    }

    componentDidMount() {
        this.loadComponent()
    }

    loadComponent() {
        NProgress.start()

        // 在这里使用setTimeout调用,是防止打开窗口时卡顿
        setTimeout(async () => {
            let component

            try {
                component = await import(`../../../../pages${this.props.path}`)
            } catch {
                component = await import('views/error/404')
            }

            this.setState(
                {
                    key: Math.random().toString(16).slice(2),
                    component: component.default,
                },
                () => {
                    NProgress.done()
                }
            )
        })
    }

    render() {
        if (this.state.component) {
            return (
                <this.state.component
                    key={this.state.key}
                    {...this.props}
                    supportInfo={
                        <Container>
                            <Divider>
                                <span className="h6 text-gray">Ewide Core ©2021 v1.0</span>
                            </Divider>
                        </Container>
                    }
                />
            )
        }
        return <></>
    }
}

class Iframe extends Component {
    shouldComponentUpdate() {
        if (this.props.onRef) {
            this.props.onRef(this)
        }
        return true
    }

    componentDidMount() {
        if (this.props.onRef) {
            this.props.onRef(this)
        }
        this.loadComponent()
    }

    loadComponent() {
        NProgress.start()
        const iframe = this.refs.content
        iframe.onload = () => {
            NProgress.done()
        }
        iframe.onerror = () => {
            NProgress.done()
        }
        iframe.src = this.props.src
    }

    render() {
        const { title } = this.props

        return <iframe ref="content" title={title} />
    }
}

export default class index extends Component {
    state = {
        actived: '',
    }

    panes = []

    componentDidMount() {
        window.reloadContentWindow = this.onReload
    }

    static getDerivedStateFromProps(props) {
        return {
            actived: props.actived,
        }
    }

    onChange(activeKey) {
        this.props.parent.setState({
            actived: activeKey,
        })
    }

    onClose(targetKey, action) {
        if (action === 'remove') {
            window.closeContentWindow(targetKey)
        }
    }

    onReload = key => {
        key = key || this.state.actived
        const pane = this.panes.find(p => p.props.id === key)
        if (pane) {
            pane.loadComponent()
        }
    }

    render() {
        this.panes = []

        const { actived } = this.state

        return (
            <Layout.Content>
                <div className="yo-tab-external-mount">
                    <Tabs
                        type="editable-card"
                        hideAdd
                        activeKey={actived}
                        onChange={activeKey => this.onChange(activeKey)}
                        onEdit={(targetKey, action) => this.onClose(targetKey, action)}
                    >
                        {this.props.panes.map(pane => {
                            return (
                                <Tabs.TabPane
                                    closable={pane.closable}
                                    key={pane.key}
                                    tab={
                                        <Dropdown
                                            trigger={['contextMenu']}
                                            overlay={
                                                <Menu>
                                                    <Menu.Item
                                                        key="0"
                                                        onClick={() => this.onReload(pane.key)}
                                                    >
                                                        重新加载
                                                    </Menu.Item>
                                                    <Menu.Divider />
                                                    <Menu.Item
                                                        key="1"
                                                        onClick={() =>
                                                            window.closeContentWindow(pane.key)
                                                        }
                                                    >
                                                        关闭
                                                    </Menu.Item>
                                                    <Menu.Item
                                                        key="2"
                                                        onClick={() =>
                                                            window.closeOtherContentWindow(pane.key)
                                                        }
                                                    >
                                                        关闭其他标签页
                                                    </Menu.Item>
                                                    <Menu.Item
                                                        key="3"
                                                        onClick={() =>
                                                            window.closeRightContentWindow(pane.key)
                                                        }
                                                    >
                                                        关闭右侧标签页
                                                    </Menu.Item>
                                                </Menu>
                                            }
                                        >
                                            <div>
                                                {pane.icon && <AntIcon type={pane.icon} />}
                                                {pane.title}
                                            </div>
                                        </Dropdown>
                                    }
                                />
                            )
                        })}
                    </Tabs>
                    <div className="yo-tab-external-mount-content">
                        {this.props.panes.map(pane => {
                            return (
                                <div
                                    key={pane.key}
                                    className={
                                        (pane.key === actived
                                            ? 'yo-tab-external-tabpane-active'
                                            : 'yo-tab-external-tabpane-inactive') +
                                        ' yo-tab-external-tabpane'
                                    }
                                >
                                    {pane.openType === 1 ? (
                                        <ComponentDynamic
                                            path={pane.path}
                                            id={pane.key}
                                            key={pane.key}
                                            param={pane.param}
                                            paneActived={pane.key === actived}
                                            onRef={p => this.panes.push(p)}
                                        />
                                    ) : pane.openType === 2 ? (
                                        <Iframe
                                            src={pane.path}
                                            title={pane.key}
                                            id={pane.key}
                                            onRef={p => this.panes.push(p)}
                                        />
                                    ) : null}
                                </div>
                            )
                        })}
                    </div>
                </div>
            </Layout.Content>
        )
    }
}
