import React from 'react'
import { Layout, Row, Col, Button, Icon, Card, Select, Menu, Dropdown } from 'antd'
import { connect } from 'dva'
import DeleteBox from '../common/deleteBox/deleteBox'
import EmptyContent from '../common/emptyContent/index'
import DataConnectBox from '../dataSourceDetail/dataConnectBox'
import ListFilter from '../common/listFilter/index'
import Loading from '../common/loading/index'
import './list.less'
const CardGrid = Card.Grid
const { Content } = Layout
const { Option } = Select

class DataConnect extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            visibleDeleteBox: false,
        }
        this.bodyRef = React.createRef();
    };
    componentDidMount() {
        const { dispatch } = this.props;
        this.setBodyWidth();
        dispatch({ type: 'dataConnect/fetchList' });
        window.addEventListener('resize', this.setBodyWidth);
    }

    componentWillUnmount() {
        window.removeEventListener('resize', this.setBodyWidth)
    }

    /**
     * 设置卡片容器宽度 = 每行最大卡片数量 * 卡片宽度
     */
    setBodyWidth = () => {
        const cardBody = this.bodyRef.current; // 卡片容器
        const parent = cardBody.parentNode; // 父级容器
        const pWidth = parent.offsetWidth; // 父级容器宽度
        const pPadding = 10 + 10; // 父级容器左右padding
        const cWidth = 160; // 每个卡片宽度
        const cMargin = 8 + 8; // 每个卡片左右margin
        const pTrueWidth = pWidth - pPadding; // 父容器实际可用宽度
        const cTrueWidth = cWidth + cMargin; // 卡片实际占用宽度
        const count = Math.floor(pTrueWidth/cTrueWidth); // 每行最大卡片数量
        const cardBodyWidth = (count - 1) * cTrueWidth; // 可能有滚动条，减少一个

        cardBodyWidth > 0 ? cardBody.style.width = cardBodyWidth + 'px' : void(0);
    }

    onSearch(list, text) {
        const reg = new RegExp('([+ \\- & | ! ( ) { } \\[ \\] ^ \" ~ * ? : ( ) \/])', 'g'); // 需要转义的字符
        let filterLabel = (text || '').replace(new RegExp('(\\\\)', 'g'), '\\$1').replace(reg, '\\$1'); // 添加转义符号
        return list.map(l => {
            let o = Object.assign({}, l);
            let reg = new RegExp('('+ filterLabel +'){1}', 'ig');
            if(o.name && o.name.search(reg) !== -1) {
                return o;
            }else if(o.description && 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.createDate) - new Date(a.createDate);
        });
    }

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

    generateOperationMenu = (l) => {
        const { dispatch } = this.props;

        return (
            <Menu className='menu-operation'>
                <Menu.Item onClick={()=>{
                    dispatch({ type: 'dataConnect/setSelected', selected: l });
                    dispatch({ type: 'dataConnect/setNewModel', model: l });
                    dispatch({ type: 'dataConnect/setNewModelFields', fields: [
                        { name: 'visibleBox', value: true },
                        { name: 'boxOperation', value: 'modify' }
                    ] });
                }}>
                    <Icon type="info-circle-o" />属性设置
                </Menu.Item>
                <Menu.Item onClick={(e) => {
                    dispatch({ type: 'dataConnect/setSelected', selected: l });
                    dispatch({ type: 'dataConnect/setNewModel', model: { ...l, code: null } });
                    dispatch({ type: 'dataConnect/setNewModelFields', fields: [
                        { name: 'visibleBox', value: true },
                        { name: 'boxOperation', value: 'create' }
                    ] });
                }}>
                    <Icon type="copy" />复制新增
                    
                </Menu.Item>
                <Menu.Item onClick={(e) => {
                    dispatch({ type: 'dataConnect/setSelected', selected: l });
                    this.setState({ visibleDeleteBox: true})
                }}>
                    <Icon type="delete" />删除
                    
                </Menu.Item>
            </Menu>
        )
    }

    generateCard() {
        const { dataConnect, dispatch } = this.props;
        const reg = new RegExp('([+ \\- & | ! ( ) { } \\[ \\] ^ \" ~ * ? : ( ) \/])', 'g'); // 需要转义的字符
        let filterLabel = dataConnect.filterLabel ? (dataConnect.filterLabel + '').replace(new RegExp('(\\\\)', 'g'), '\\$1').replace(reg, '\\$1') : ''; // 添加转义符号
        let filterItem = dataConnect.filterItem
        let filterReg = new RegExp('(' + filterLabel + '){1}', 'ig');
        let cards = dataConnect.list.map(l => {
            let o = Object.assign({}, l);

            if(filterItem.type === 'date') {
                if(filterLabel===""){
                    return o;
                }else if(filterLabel.indexOf('#')>-1){
                    let start = filterLabel.split('#')[0]
                    let end = filterLabel.split('#')[1]
                    let nowTime = o[filterItem.name].getTime();
                    if(nowTime>=start && nowTime<=end){
                        return o;
                    }
                    return null 
                }else{
                    return null 
                }
            }else {
                return ((o[filterItem.name] + '').search(filterReg) > -1) ? o : null
            }
        }).filter(a => a!==null).map( (l, i) => (
            <CardGrid className='dataconnect-card' key={i}>
                <Card
                    bordered={false}
                    hoverable={true}
                    title={
                        <Row type='flex' justify='start'
                            onClick={() => {
                                // 选中项设置
                                dispatch({ type: 'dataConnect/setSelected', selected: l });
                                dispatch({ type: 'dataConnect/setNewModel', model: l });
                                dispatch({ type: 'dataConnect/setNewModelFields', fields: [
                                    { name: 'visibleBox', value: true },
                                    { name: 'boxOperation', value: 'modify' }
                                ] });
                            }}
                        >
                            <Col className='label' title={l.name}>
                                { (filterItem.name === 'name' && filterLabel) ?
                                    ((l.name || '').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
                                        )
                                    }
                                    )) : l.name
                                }
                            </Col>
                        </Row>
                    }
                    actions={[
                        <div>
                            {l.dbType === 'file' ? <Icon type='file' /> : <div><Icon type='database' />{l.dbType[0].toUpperCase() + l.dbType.slice(1)}</div>}
                        </div>,
                        <Dropdown overlay={this.generateOperationMenu(l)} trigger={['click']}>
                            <Icon style={{ fontSize: '24px' }} type="ellipsis" theme="outlined" />
                        </Dropdown>
                    ]}
                >
                    <div className='content'
                        onClick={() => {
                            // 选中项设置
                            dispatch({ type: 'dataConnect/setSelected', selected: l });
                            dispatch({ type: 'dataConnect/setNewModel', model: l });
                            dispatch({ type: 'dataConnect/setNewModelFields', fields: [
                                { name: 'visibleBox', value: true },
                                { name: 'boxOperation', value: 'modify' }
                            ] });
                        }}
                    >
                        { /** TODO 这里只考虑了数据库的展示情况，需要兼容展示文件类型的数据链接 */ }
                        <Row className='address'>
                            { filterLabel && filterItem.name === 'address' ?
                                ((l.address || '').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
                                    )
                                }
                                )) : l.address
                            }
                        </Row>
                        <Row className='username'>
                            { filterLabel && filterItem.name === 'userName' ?
                                ((l.userName || '').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
                                    )
                                }
                                )) : l.userName
                            }
                        </Row>
                    </div>
                </Card>
            </CardGrid>
        ))

        if(cards.length === 0) {
            return <EmptyContent />
        }
        
        return cards;
    }

    generateFilterItems = () => {
        const { filterItems } = this.props.dataConnect;
        return filterItems.map(t => <Option key={t.name} value={t.name}>{t.label}</Option>);
    }

    render() {
        const { dataConnect, dispatch } = this.props;
        const { listLoading, selected } = dataConnect;
        const { visibleDeleteBox } = this.state;

        return (
            <Layout className='layout-dataconnect'>
                <Loading visible={listLoading} />
                <Content>
                    <Card bordered={false} title={
                        <Row className='tools' type='flex' justify='space-between'>
                            <Col style={{ display: 'flex' }}>
                            </Col>
                            <Col className='search'>
                                <Col>
                                    <Button className='btn-refresh' onClick={() => {
                                        dispatch({ type: 'dataConnect/setFilterLabel', label: '' });
                                        dispatch({ type: 'dataConnect/fetchList', mandatory: true });
                                    }}>
                                        {/* <CusIcon type='bi-refresh'/> */}
                                        <Icon type='sync'/>
                                    </Button>
                                </Col>
                                <Col>
                                    <ListFilter modelName='dataConnect' model={dataConnect} />
                                </Col>
                                <Col>
                                    <Button className='btn-add' onClick={() => {
                                        // 设置新增默认值
                                        dispatch({ type: 'dataConnect/setNewModel', model: { dbType: 'oracle', dbName: 'orcl' } });
                                        dispatch({ type: 'dataConnect/setNewModelFields', fields: [
                                            { name: 'visibleBox', value: true },
                                            { name: 'boxOperation', value: 'create' }
                                        ] });
                                    }}>
                                        添加数据链接
                                    </Button>
                                </Col>
                            </Col>
                        </Row>
                    }>
                        <div ref={this.bodyRef} className='body'>
                            { this.generateCard() }
                        </div>
                    </Card>
                </Content>
                {visibleDeleteBox && <DeleteBox
                    visibleBox={visibleDeleteBox}
                    text={<div><span>确定要删除数据链接【{selected.name}】吗？</span></div>}
                    hideBox={() => {
                        this.setState({
                            visibleDeleteBox: false
                        })
                    }}
                    okHandler={() =>{
                        dispatch({ type: 'dataConnect/remoteDelete', code: selected.code })
                    }} 
                />}
                {dataConnect.newOne.visibleBox && <DataConnectBox />}
            </Layout>
        )
    }
}

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

export default connect(mapStateToProps)(DataConnect)