import React from 'react'
import { Layout, Row, Col, Input, Button, Table, Icon, Menu, Dropdown, Card, Breadcrumb, Popover, Tree, Tag } from 'antd'
import { connect } from 'dva'
import './dataSource.less'
import { dateFormat } from '../../utils/baseUtils'
import GroupSelector from './groupSelector'
const { Content } = Layout
const { Search } = Input
const { TreeNode } = Tree

class DataSource extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            selectedRecord: null, // 当前选中的dataSource
            visibleGroupMenu: false, // 显示分组菜单
            visibleSetGroupMenu: false, //
            groupEditing: false, // 是否处于编辑状态
        }
    };

    componentDidMount() {
        const { dispatch } = this.props;
        this.setScrollTableHeight();
        dispatch({ type: 'dataSource/fetchList' });
        dispatch({ type: 'dataSource/remoteGroupList' });
    }

    /**
     * 根据视图设置表格高度以呈现滚动条
     */
    setScrollTableHeight() {
        const mainContent = document.getElementsByClassName('main-content')[0];
        const toolbar = mainContent.getElementsByClassName('datasource-tools')[0];
        const tableHeader = mainContent.getElementsByClassName('ant-table-header')[0];
        const tableBody = mainContent.getElementsByClassName('ant-table-body')[0];
        tableBody.style.maxHeight=`${mainContent.offsetHeight - toolbar.offsetHeight - tableHeader.offsetHeight - 58}px`;
    }

    onGroup() {
        const { dataSource } = this.props;
        const groupList = dataSource.groupList;
        const list = dataSource.list;
        const currentGroup = dataSource.currentGroup;
        
        let groupFilter = groupList.concat({ code: 'all', label: '全部分组' }).filter(g => (
            currentGroup[0].code === 'all' || 
            (
                currentGroup[0].code === 'nogroup' ? g.code === 'all' : (
                    currentGroup[1] ? (g.code === currentGroup[1].code) : 
                    (
                        g.code === currentGroup[0].code ||
                        g.pcode === currentGroup[0].code
                    )
                )
            )
        )).map(g => g.code);

        console.log(list, groupFilter);

        return list.filter(l => groupFilter.indexOf(l.groupCode+'') !== -1);
    }

    onSearch(list, text) {
        return list.map(l => {
            let o = Object.assign({}, l);
            let reg = new RegExp('('+ text +'){1}', 'ig');
            if(o.name.search(reg) !== -1) {
                return o;
            }else if(o.description.search(reg) !== -1) {
                return o;
            }else {
                return null
            }
        }).filter(a => a!==null);
    }

    onSort(list) {
        return list.sort((a, b) => {
            return new Date(b.createTime) - new Date(a.createTime);
        });
    }

    handleVisibleChange = (flag) => {
        this.setState({ visibleGroupMenu: flag });
    }

    createGroupMenu = (selectedRecord) => {

        const { dataSource, dispatch } = this.props;
        const groupList = dataSource.groupList;
        const pGroups = groupList.filter(d => d.pcode === '-1').sort((a, b) => a.index - b.index);
        const cGroups = groupList.filter(d => d.pcode !== '-1');

        let allGroups = selectedRecord ? pGroups : [
            { code: 'all', label: '全部分组' },
            { code: 'nogroup', label: '未分组' }
        ].concat(pGroups);

        return allGroups.map(p => {
            let c = cGroups.filter(c => c.pcode === p.code).sort((a, b) => a.index - b.index);
            return c.length > 0 ? (
                <Menu.SubMenu key={p.code} title={<span style={{ fontWeight: selectedRecord ? (
                    (p.code+'' === selectedRecord.groupCode+'' ? 'bold' : (
                        c.find(ch => ch.code+'' === selectedRecord.groupCode+'') && c.find(ch => ch.code+'' === selectedRecord.groupCode+'').pcode === p.code ? 'bold' : 'normal'
                    ))
                ) : dataSource.currentGroup[0].code === p.code ? 'bold' : 'normal' }}>{p.label}</span>} onTitleClick={(item) => {
                    dispatch({ type: 'dataSource/setCurrentGroup', group1: p });
                    if(selectedRecord) {
                        dispatch({ type: 'dataSource/remoteSetDataSourceGroup', dataSource: selectedRecord, group: p });
                    }
                    this.hideGroupMenu();
                }}>
                    {c.map(c => {
                        return (<Menu.Item key={c.code} onClick={(item) => {
                            dispatch({ type: 'dataSource/setCurrentGroup', group1: p, group2: c });
                            if(selectedRecord) {
                                dispatch({ type: 'dataSource/remoteSetDataSourceGroup', dataSource: selectedRecord, group: c });
                            }
                        }}><span style={{ fontWeight: selectedRecord ? (
                            selectedRecord.groupCode+'' === c.code+'' ? 'bold' : 'normal'
                        ) : (dataSource.currentGroup[1] && (dataSource.currentGroup[1].code === c.code) ? 'bold' : 'normal') }}>{c.label}</span></Menu.Item>)
                    })}
                </Menu.SubMenu>
            ) : (
                <Menu.Item key={p.code} onClick={() => {
                    dispatch({ type: 'dataSource/setCurrentGroup', group1: p });
                    this.hideGroupMenu();
                }}><span className={selectedRecord ? (
                    selectedRecord.groupCode+'' === p.code+'' ? 'selected' : ''
                ) : dataSource.currentGroup[0] && (dataSource.currentGroup[0].code === p.code) ? 'selected' : ''} style={{ fontWeight: selectedRecord ? (
                    selectedRecord.groupCode+'' === p.code+'' ? 'bold' : 'normal'
                ) : dataSource.currentGroup[0] && (dataSource.currentGroup[0].code === p.code) ? 'bold' : 'normal' }}>{p.label}</span></Menu.Item>
            );
        });
    }

    createSubGroupMenu = () => {
        const { dataSource, dispatch } = this.props;
        const groupList = dataSource.groupList;
        const parentGroup = dataSource.currentGroup[0];
        const children = groupList.filter(d => d.pcode === parentGroup.code);
        const subGroup = dataSource.currentGroup[1];

        return children.map(c => {
            return (
                <Menu.Item key={c.code} onClick={() => {
                    dispatch({ type: 'dataSource/setCurrentGroup', group1: parentGroup, group2: c });
                }}><span className={subGroup && (subGroup.code === c.code) ? 'selected' : ''} style={{ fontWeight: subGroup && (subGroup.code === c.code) ? 'bold' : 'normal' }}>{c.label}</span></Menu.Item>
            );
        })
    }

    createGroupTree(modify) {
        const { dispatch, dataSource } = this.props;
        const { groupEditing } = this.state;
        const groupList = dataSource.groupList;

        let parent = groupList.filter(d => d.pcode === '-1').sort((a, b) => a.index - b.index);
        let children = groupList.filter(d => d.pcode !== '-1');

        let groupTree = parent.map(p => {
            return (
                <TreeNode disabled={groupEditing} title={
                modify ? (<div><Icon style={{ cursor: 'move' }} type='drag'/>
                <Input value={p.label} size='small' focus={'true'} onFocus={() => {
                    this.setState({
                        groupEditing: true
                    });
                }} onChange={(e) => {
                    dispatch({ type: 'dataSource/modifyGroup', group: {...p, label:e.target.value} });
                }} onBlur={(e) => {
                    this.setState({
                        groupEditing: false
                    });
                    dispatch({ type: 'dataSource/remoteModifyGroup', group: {...p, label:e.target.value} });
                }} onPressEnter={(e) => {
                    dispatch({ type: 'dataSource/remoteModifyGroup', group: {...p, label:e.target.value} });
                }} /><Icon type='plus-circle-o' onClick={() => {
                    dispatch({ type: 'dataSource/remoteAddGroup', pgroup: p });
                }}/><Icon type='minus-circle' onClick={() => {
                    dispatch({ type: 'dataSource/remoteDeleteGroup', group: p });
                }}/></div>) : p.label} key={p.code}>
                    {
                        children.filter(c => c.pcode === p.code).sort((a, b) => a.index - b.index).map(c => {
                            return (
                                <TreeNode disabled={groupEditing} title={
                                    modify ? (<div><Icon style={{ cursor: 'move' }} type='drag'/>
                                    <Input value={c.label} size='small' onFocus={() => {
                                        this.setState({
                                            groupEditing: true
                                        });
                                    }} onChange={(e) => {
                                        dispatch({ type: 'dataSource/modifyGroup', group: {...c, label:e.target.value} });
                                    }} onBlur={(e) => {
                                        this.setState({
                                            groupEditing: false
                                        });
                                        dispatch({ type: 'dataSource/remoteModifyGroup', group: {...c, label:e.target.value} });
                                    }} onPressEnter={(e) => {
                                        dispatch({ type: 'dataSource/remoteModifyGroup', group: {...c, label:e.target.value} });
                                    }} onCompositionEnd={(e) => {
                                        console.log(e.target.value);
                                    }}/><Icon type='minus-circle' onClick={() => {
                                        dispatch({ type: 'dataSource/remoteDeleteGroup', group: c });
                                    }}/></div>) : p.label
                                } key={c.code} />
                            )
                        })
                    }
                </TreeNode>
            )
        });

        return groupTree;
    }

    hideGroupMenu = () => {
        this.setState({
            visibleGroupMenu: false
        });
    }

    onDrop = (info) => {
        const { dispatch } = this.props;

        const dropCode = info.node.props.eventKey;
        const dragCode = info.dragNode.props.eventKey;
        const dropPos = info.node.props.pos.split('-');
        const dropPosition = info.dropPosition - Number(dropPos[dropPos.length - 1]); // -1/0/1 -> 兄/子/弟
        console.log(dragCode, dropCode, dropPosition);
        dispatch({ type: 'dataSource/remoteMoveGroup', dragCode, dropCode, dropPosition });
    }

    render() {
        
        const { dataSource, dispatch } = this.props;
        const { selectedRecord } = this.state;

        const reg = new RegExp('([+ \\- & | ! ( ) { } \\[ \\] ^ \" ~ * ? : ( ) \/])', 'g'); // 需要转义的字符
        let filterLabel = dataSource.filterLabel.replace(new RegExp('(\\\\)', 'g'), '\\$1').replace(reg, '\\$1'); // 添加转义符号

        const TAG_COLOR = ['blue'];
        // const TAG_COLOR1 = ['magenta', 'red', 'volcano', 'orange', 'gold', 'lime', 'green', 'cyan', 'blue', 'geekblue', 'purple'];

        const moreOperatingMenu = (
            <Menu className='operationmenu' visible={true}>
                <Menu.Item
                    onClick={() => {
                        dispatch({ type: 'chartDesigner/remoteQucikAdd', dataSource: selectedRecord });
                    }}
                >
                    <Icon type="file-add" />创建图表
                </Menu.Item>
                <Menu.Item
                    onClick={(e) => {
                        dispatch({ type: 'dataSource/resetNewModel' });
                        let selectedModel = dataSource.list.find((i) => { return i.code === selectedRecord.code })
                        dispatch({type: 'main/redirect', path: {pathname: '/datasource/'+ selectedModel.type +'/' + selectedModel.code + '/base'}});
                    }}>
                    <Icon type="info-circle-o" />属性设置
                </Menu.Item>
                <Menu.Item><Icon type="search" />预览数据</Menu.Item>
                <Menu.Divider />
                <Menu.SubMenu className='setgroupmenu' title={<div><Icon style={{ marginRight: '6px' }} type='profile' />分组</div>}>
                    {this.createGroupMenu(selectedRecord)}
                </Menu.SubMenu>
                <Menu.Divider />
                <Menu.Item
                    onClick={(e) => {
                        dispatch({ type: 'dataSource/remoteDelete', code: selectedRecord.code });
                    }}
                ><Icon type="delete" />删除</Menu.Item>
            </Menu>
        );
        const dataSourceColumns = [{
            title: '名称',
            dataIndex: 'name',
            key: 'name',
            width: 100,
            render: (text, record) => {
                return <div className='datasource-name'>
                    <div className={`datasource-type type-${record.type.key}`}></div>
                    <div>
                        <span>
                            { filterLabel ?
                                (text.split(new RegExp(`(${filterLabel})`, 'i')).map((fragment, i) => {
                                    return (
                                        fragment.toLowerCase().replace(new RegExp('(\\\\)', 'g'), '\\$1').replace(reg, '\\$1') === filterLabel.toLowerCase() ?
                                        <span key={i} style={{fontWeight: 'bold', color: 'red'}} className="highlight">{fragment}</span> :
                                        fragment
                                    )
                                }
                                )) : text
                            }
                        </span>
                    </div>
                </div>
            }
        }, {
            title: '说明',
            dataIndex: 'description',
            key: 'description',
            width: 200,
            render: (text, record) => {
                return (
                    <span>
                        { filterLabel ?
                            (text.split(new RegExp(`(${filterLabel})`, 'i')).map((fragment, i) => {
                                return (
                                    fragment.toLowerCase().replace(new RegExp('(\\\\)', 'g'), '\\$1').replace(reg, '\\$1') === filterLabel.toLowerCase() ?
                                    <span key={i} style={{fontWeight: 'bold', color: 'red'}} className="highlight">{fragment}</span> :
                                    fragment
                                )
                            }
                            )) : text
                        }
                    </span>
                )
            }
        }, {
            title: '创建人',
            dataIndex: 'creator',
            key: 'creator',
            width: 100
        }, {
            title: '创建时间',
            dataIndex: 'createTime',
            key: 'createTime',
            render: (text, record) => dateFormat(text, 'yyyy-MM-dd hh:mm:ss'),
            width: 100
        }, {
            title: '操作',
            key: 'action',
            render: (text, record, index) => (
                <Dropdown code={record.code} overlay={moreOperatingMenu} trigger={['click']} >
                    <Icon type="setting" />
                </Dropdown>
            ),
            width: 50
        }];

        return ( 
            <Layout className='datasource-view'>
                <Content>
                    <Card className='datasource-body' title={
                        <Row className='datasource-tools' type='flex' justify='space-between'>
                            <Col style={{ display: 'flex' }}>
                                <Popover overlayClassName='popover-group' title={
                                    <Row className='grouptree-title' type='flex' justify='space-between'>
                                        <Col>
                                            分组管理
                                        </Col>
                                        <Col>
                                            <div className='create-group' onClick={() => {
                                                dispatch({ type: 'dataSource/remoteAddGroup' });
                                            }}>添加分组<Icon type="plus-circle-o" /></div>
                                        </Col>
                                    </Row>
                                } trigger="click" placement="bottomLeft" content={(
                                    <Tree
                                        className='tree-group'
                                        showLine
                                        defaultExpandAll
                                        draggable
                                        onDragStart={this.onDragStart}
                                        onDrop={this.onDrop}
                                    >
                                        {
                                            this.createGroupTree(true)
                                        }
                                    </Tree>
                                )}>
                                    <Icon type="bars" />
                                </Popover>
                                <Breadcrumb className='group' separator=">">
                                    <Breadcrumb.Item>
                                        <GroupSelector model={dataSource} modelName='dataSource'>
                                            <Tag color={TAG_COLOR[Math.ceil(Math.random()*TAG_COLOR.length) - 1]} >
                                                {dataSource.currentGroup[0].label}
                                            </Tag>
                                        </GroupSelector>
                                    </Breadcrumb.Item>
                                    {dataSource.currentGroup[1] && (<Breadcrumb.Item>
                                        <GroupSelector model={dataSource} modelName='dataSource'>
                                            <Tag color={TAG_COLOR[Math.ceil(Math.random()*TAG_COLOR.length) - 1]}>
                                                {dataSource.currentGroup[1].label}
                                            </Tag>
                                        </GroupSelector>
                                    </Breadcrumb.Item>)}
                                </Breadcrumb>
                            </Col>
                            <Col className='search'>
                                <Col>
                                    <Search
                                        value={dataSource.filterLabel}
                                        placeholder="请输入关键字"
                                        onChange={e => {
                                            dispatch({ type: 'dataSource/setFilterLabel', label: e.target.value });
                                        }}
                                    />
                                </Col>
                                <Col>
                                    <Dropdown overlay={(
                                        <Menu onClick={(item, key, keyPath) => {
                                            const type = item.key;
                                            dispatch({ type: 'dataSource/resetNewModel' });
                                            dispatch({ type: 'dataSource/setNewModelField', name: 'type', value: type });
                                            dispatch({type: 'main/redirect', path: {pathname: '/datasource/'+ type +'/create/base'}});
                                        }}>
                                            <Menu.Item key='database'>数据库</Menu.Item>
                                            <Menu.Item key='file'>文件</Menu.Item>
                                        </Menu>
                                    )} trigger={['click']}>
                                        <Button>
                                            <Icon type="plus" />添加数据源
                                        </Button>
                                    </Dropdown>
                                </Col>
                            </Col>
                        </Row>
                    }>
                        <Table
                            className='datasource-table datasource-table'
                            columns={dataSourceColumns}
                            dataSource={
                                this.onSort(
                                    this.onSearch(this.onGroup(), dataSource.filterLabel)
                                )
                            }
                            size='small'
                            scroll={{x: false, y: true}}
                            pagination={false}
                            onRow={(record) => {
                                return {
                                    onClick: () => {this.setState({ selectedRecord:  record})}
                                }
                            }}
                        />
                    </Card>
                </Content>
            </Layout>
        )


    }
}

function mapStateToProps({present: {dataSource, dataConnect}}) {
    return { dataSource, dataConnect }
}

export default connect(mapStateToProps)(DataSource)