import React from 'react'
import { connect } from 'dva'
import { Layout, Card, Row, Col, Table, Input, Checkbox, Button, Switch, Icon, Tag } from 'antd'
import FilterBox from '../common/filterBox/filterBox'
import AccessObjectBox from './accessObjectBox'
import * as moment from 'moment'
import './accessConfig.less'
const { Content } = Layout

const Search = Input.Search;

class DataSourceAccessConfig extends React.Component{

    constructor(props){
        super(props);
        this.state={
            inputRow: -1,
            filterLabel: '',
            visibleAccessObjectBox: false,
            visiblePolicyRuleBox: false, // 显示过滤规则编辑窗口
            currentPolicy: {}, // 选中的策略
            visibleFilterBox: false
        }
    }

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

    showAccessObjectBox = () => {
        this.setState({ visibleAccessObjectBox:true })
    }

    hideAccessObjectBox = () => {
        this.setState({ visibleAccessObjectBox:false })
    }

    showPolicyRuleBox= () => {
        this.setState({ visiblePolicyRuleBox: true })
    }

    hidePolicyRuleBox= () => {
        this.setState({ visiblePolicyRuleBox: false })
    }

    setAccessObject = (group, geren) => {
        const { dispatch } = this.props;
        const { currentPolicy } = this.state;
        let targets = group.map(g => ({
            code: g.code,
            name: g.name,
            isGroup: true
        })).concat(geren.map(g => ({
            code: g.code,
            name: g.name,
            isGroup: false
        })))
        dispatch({ type: 'dataSourcePolicy/remoteSetTarget', policy: currentPolicy, targets });
    }

    createFilters = (filters) => {
        const { dispatch } = this.props;
        let { currentPolicy } = this.state;
        currentPolicy.filters = filters;
        dispatch({ type: 'dataSourcePolicy/remoteModify', policy: currentPolicy });
    }

    /**
     * 生成过滤规则文本
     */
    createFilterLabel = (filter) => {
        let { label, operator, operatorLabel, type, value1, value2 } = filter;
        let filterLabel;

        if(type === 'string' || type === 'index') {
            if(operator === 'null' || operator === 'notNull') {
                filterLabel = `${label} ${operatorLabel}`;
            }else {
                filterLabel = `${label} ${operatorLabel} ${value1}`;
            }
        }else if(type === 'scale') {
            if(operator === 'null' || operator === 'notNull') {
                filterLabel = `${label} ${operatorLabel}`;
            }else if(operator === 'between') {
                filterLabel = `${label} ${operatorLabel} ${value1} ~ ${value2}`; 
            }else {
                filterLabel = `${label} ${operatorLabel} ${value1}`; 
            }
        }else if(type === 'time') {
            value1 = moment(value1).format('YYYY/MM/DD');
            value2 = moment(value2).format('YYYY/MM/DD');
            if(operator === 'null' || operator === 'notNull') {
                filterLabel = `${label} ${operatorLabel}`;
            }else if(operator === 'between') {
                filterLabel = `${label} ${operatorLabel} ${value1} ~ ${value2}`;
            }else {
                filterLabel = `${label} ${operatorLabel} ${value1}`;
            }
        }else if(type === 'categorical') {
            if(operator === 'null' || operator === 'notNull') {
                filterLabel = `${label} ${operatorLabel}`;
            }else {
                filterLabel = `${label} ${operatorLabel} ${value1}`;
            }
        }else {
            filterLabel = '错误条件';
        }
        return filterLabel;
    }
    
    render() {
        const { dataSourcePolicy, dataSource, dispatch } = this.props;
        const { visibleAccessObjectBox, visiblePolicyRuleBox, currentPolicy } = this.state;
        
        const polices = dataSourcePolicy.list;
        const group = currentPolicy ? (currentPolicy.targets ? currentPolicy.targets.filter(t => t.isGroup) : []) : [];
        const geren = currentPolicy ? (currentPolicy.targets ? currentPolicy.targets.filter(t => !t.isGroup) : []) : [];
        const reg = new RegExp('([+ \\- & | ! ( ) { } \\[ \\] ^ \" ~ * ? : ( ) \/])', 'g'); // 需要转义的字符
        let filterLabel = (this.state.filterLabel || '').replace(new RegExp('(\\\\)', 'g'), '\\$1').replace(reg, '\\$1'); // 添加转义符号
        
        // let owner = user.list.find(l => l.code === dataSource.newOne.creator); // 数据源拥有者
        // console.log(owner);
        const columnData = dataSource.newOne.columns ? dataSource.newOne.columns.filter(c => c.using).map(c => ({
            key: c.key,
            label: c.alias,
            name: c.name,
            selection: [],
            type: c.columnType,
            groupable: c.groupable,
            // filterable: c.filterable,
            filterable: true,
            bucketizable: c.bucketizable
        })) : [];
        
        const columns = [{
            title:'启用',
            dataIndex:'enabled',
            render: (v, r) => <Checkbox
                onChange={(e) => {
                    let policy = {
                        ...r,
                        enabled: e.target.checked
                    }
                    console.log(policy);
                    dispatch({ type: 'dataSourcePolicy/remoteModify', policy });
                }}
                checked={v}
            />,
            width: 50
        },{
            title: '策略名',
            dataIndex: 'name',
            render: (value, record, index) => <div key={index}>
                {
                    this.state.inputRow === index ? <Input value={value} suffix={<Icon style={{ cursor: 'pointer', color: '#52C41A' }} type="check-circle" onClick={() => {
                        this.setState({
                            inputRow: -1
                        });
                        dispatch({ type: 'dataSourcePolicy/remoteModify', policy: record });
                    }}/>} onChange={(e) => {
                        dispatch({ type: 'dataSourcePolicy/modify', policy: { ...record, name: e.target.value } });
                    }} onBlur={() => {
                        this.setState({
                            inputRow: -1
                        });
                        dispatch({ type: 'dataSourcePolicy/remoteModify', policy: record });
                    }} onPressEnter={() => {
                        this.setState({
                            inputRow: -1
                        });
                        dispatch({ type: 'dataSourcePolicy/remoteModify', policy: record });
                    }}/> : <span onClick={() => {
                        this.setState({
                            inputRow: index
                        });
                    }}>
                        { filterLabel ?
                            ((value || '').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
                                )
                            }
                            )) : value
                        }
                    </span>
                }
                {
                    this.state.inputRow !== index && <Icon style={{ cursor: 'pointer' }} type='edit' onClick={() => {
                        this.setState({
                            inputRow: index
                        });
                    }} />
                }
            </div>,
            width: 150
        }, {
            title: '行开放策略',
            dataIndex: 'filters',
            render: (filter, record, index) => <div key={index}>
                {filter.length > 0 ? filter.map((f, i) =>
                    <Tag
                        className='filter-tag'
                        key={i}
                        closable={false}
                    >
                        {this.createFilterLabel(f)}
                    </Tag>
                ) : <Tag key='all' className='filter-tag' closable={false}>所有数据</Tag>}
                <Tag
                    key='add'
                    onClick={this.showPolicyRuleBox}
                    className={`filter-tag filter-tag-add`}
                >
                    <Icon type="filter" />
                </Tag>
            </div>,
            width: 500
        }, {
            title: '开放对象',
            dataIndex: 'targets',
            render: (targets, record, index) => <div key={index}>
                {/* {
                    <Tag><Icon type='geren' />{owner ? (owner.name || '拥有者' ) : '拥有者'}</Tag>
                } */}
                {
                    targets.map(item => <Tag className='user-tag' key={item.code}>{item.isGroup ? <Icon type='group' /> : <Icon type='geren' />}{item.name}</Tag>)
                }
                <Tag key='add' onClick={this.showAccessObjectBox}><Icon type="plus" /></Tag>
            </div>,
            width: 300
        }, {
            title: '操作',
            render: (v,r) => <div><span style={{ cursor: 'pointer' }} onClick={() => {
                dispatch({ type: 'dataSourcePolicy/remoteDelete', code: r.code });
            }}>删除</span></div>,
            width: 120
        }];

        return (
            <Layout className='datasource-policy'>
                <Content>
                    <Card className='policy-body' title={
                        <Row className='policy-tools' type='flex' justify='space-between'>
                            <Col className='policy-public' style={{ display: 'flex' }}>
                                完全开放数据源<Switch size="small"/>
                            </Col>
                            <Col className='search'>
                                <Search
                                    placeholder="请输入关键字"
                                    value={this.state.filterLabel}
                                    onChange={e => {
                                        this.setState({
                                            filterLabel: e.target.value
                                        });
                                    }}
                                />
                                <Button className='add-btn' onClick={() => {
                                    dispatch({ type: 'dataSourcePolicy/remoteAdd', policy: {
                                        enabled: false,
                                        name: '新策略',
                                        targets: [],
                                        filters: []
                                    } });
                                }}>
                                    添加策略
                                </Button>
                            </Col>
                        </Row>
                    }>
                        <Table
                            className='policy-table'
                            columns={columns}
                            dataSource={polices ? polices.filter(l => {
                                let reg = new RegExp('(' + filterLabel + '){1}', 'ig');
                                return (l.name || '').search(reg) !== -1;
                             }).map((p, i) => ({ ...p, key: i })) : []}
                            size='small'
                            onRow={(record) => {
                                return {
                                    onClick: () => {this.setState({ currentPolicy:  record})}
                                }
                            }}
                        />
                    </Card>
                    <FilterBox key={Math.random()} type='dataSource' code={dataSource.newOne.code} columns={columnData} filterData={currentPolicy.filters} visibleFilterBox={visiblePolicyRuleBox} hideFilterBox={this.hidePolicyRuleBox} createFilters={this.createFilters} />
                    <AccessObjectBox key={Math.random()} visibleBox={visibleAccessObjectBox} hideBox={this.hideAccessObjectBox} okHandler={this.setAccessObject} group={group} geren={geren} />
                </Content>
            </Layout>
        );
    }
}
        
function mapStateToProps({ present: { user, dataSourcePolicy, dataSource } }) {
    return { user, dataSourcePolicy, dataSource }
}

export default connect(mapStateToProps)(DataSourceAccessConfig);