import React from 'react'
import { Form, Input, Button, Select, Table, Checkbox, Icon, Tooltip, Row } from 'antd'
import { connect } from 'dva'
import COLUMN_TYPE from './columnType.json'
import { Resizable } from 'react-resizable'
import './columnConfig.less'
const FormItem = Form.Item
const SelectOption = Select.Option

const resizeableTitle = (props) => {
    const { onResize, width, ...restProps } = props;

    if (!width) {
        return <th {...restProps} />;
    }

    return (
        <Resizable width={width} height={0} onResize={onResize}>
            <th {...restProps} />
        </Resizable>
    );
}

class DataSourceColumnConfig extends React.Component {

    constructor(props) {
        super(props);
        this.state = {
            widths: [ 80, 300, 200, 100, 100 ],
            pageSize: 10,
            visibleConfirm: false,
            searchText: '',
        }
    }

    componentDidMount() {
        this.resetTablePageSize();
        window.addEventListener('resize', this.resetTablePageSize);
    }
    componentWillUnmount() {
        window.removeEventListener('resize', this.resetTablePageSize);
    }

    resetTablePageSize = () => {
        let el = this.columnConfigRef;
        let parent = el.parentElement;
        let tableHeight = el.getElementsByClassName('ant-table-thead')[0];
        // let tableRow = el.getElementsByClassName('ant-table-row')[0];
        let ph = parent.offsetHeight;
        let padding = el.getBoundingClientRect().top - parent.getBoundingClientRect().top;
        // (可视区域高度 - 上下padding - 分页器高度 - 表头高度 - 容差值) / 行高
        // let pageSize = ~~((ph - padding * 2 - 64 - tableHeight.offsetHeight) / tableRow.offsetHeight) // 数据未加载时拿不到行高
        let pageSize = ~~((ph - padding * 2 - 64 - tableHeight.offsetHeight - 12) / 41)
        this.setState({
            pageSize,
        });
    }

    components = {
        header: {
            cell: resizeableTitle,
        },
    };

    handleVisibleChange = (visible) => {
        const { columns } = this.props.dataSourceDetail;
        this.setState({ visibleConfirm: visible && (columns && columns.length > 0) });
    }

    handleResize = index => (e, { size }) => {
        this.setState(({ widths }) => {
            const nextWidths = [...widths];
            nextWidths[index] = size.width;
            return { widths: nextWidths };
        });
    };

    handleSearch = (dataIndex, selectedKeys, confirm) => {
        confirm();
        let obj = {};
        obj[`searchText${dataIndex}`] = selectedKeys[0];
        this.setState(obj);
    };

    handleReset = (dataIndex, clearFilters) => {
        clearFilters();
        let obj = {};
        obj[`searchText${dataIndex}`] = '';
        this.setState(obj);
    };

    getColumnSearchProps = dataIndex => ({
        filterDropdown: ({ setSelectedKeys, selectedKeys, confirm, clearFilters }) => (
            <div style={{ padding: 8 }}>
                <Input
                    ref={node => { this.searchInput = node; }}
                    placeholder={`请输入关键字`}
                    value={selectedKeys[0]}
                    onChange={e => setSelectedKeys(e.target.value ? [e.target.value] : [])}
                    onPressEnter={() => this.handleSearch(dataIndex, selectedKeys, confirm)}
                    style={{ width: 188, marginBottom: 8, display: 'block' }}
                />
                <Button
                    type="primary"
                    onClick={() => this.handleSearch(dataIndex, selectedKeys, confirm)}
                    icon="search"
                    size="small"
                    style={{ width: 90, marginRight: 8 }}
                >
                    搜索
                </Button>
                <Button onClick={() => this.handleReset(dataIndex, clearFilters)} size="small" style={{ width: 90 }}>
                    重置
                </Button>
            </div>
        ),
        filterIcon: filtered => (
            <span ><a className='label'>{this.state[`searchText${dataIndex}`]}</a><Icon type="search" style={{ color: filtered ? '#1890ff' : undefined }} /></span>
        ),
        onFilter: (value, record) =>
            record[dataIndex]
            .toString()
            .toLowerCase()
            .includes(value.toLowerCase()),
        onFilterDropdownVisibleChange: visible => {
            if (visible) {
                setTimeout(() => this.searchInput.select());
            }
        },
        render: text => {
            const { searchText } = this.state;
            return (searchText) ?
                ((text || '').split(new RegExp(`(${searchText})`, 'i')).map((fragment, i) => {
                    return (
                        fragment.toLowerCase().replace(new RegExp('(\\\\)', 'g'), '\\$1').replace(new RegExp('([+ \\- & | ! ( ) { } \\[ \\] ^ \" ~ * ? : ( ) \/])', 'g'), '\\$1') === searchText.toLowerCase() ?
                        <span key={i} style={{fontWeight: 'bold', color: 'red'}} className="highlight">{fragment}</span> :
                        fragment
                    )
                }
            )) : text
        }
    });

    render() {

        const { dataSourceDetail, dispatch, fetching } = this.props;
        const { widths, pageSize } = this.state;

        const columns = [{
            title: <div><Checkbox
                style={{ margin: '0 8px 0 0', display: dataSourceDetail.columns ? (dataSourceDetail.columns.length > 0 ? 'inline-block' : 'none') : 'none'}}
                indeterminate={dataSourceDetail.columns ? (dataSourceDetail.columns.filter(c => c.using).length > 0 && dataSourceDetail.columns.filter(c => c.using).length < dataSourceDetail.columns.length) : false}
                checked={dataSourceDetail.columns ? (dataSourceDetail.columns.filter(c => c.using).length === dataSourceDetail.columns.length) : false}
                onChange={(e) => {
                    let target = e.target;
                    let columns = dataSourceDetail.columns ? dataSourceDetail.columns.map(c => {
                        c.using = target.checked;
                        return c;
                    }) : [];

                    dispatch({ type: 'dataSourceDetail/setField', name: 'columns', value: columns });
                }}
            />启用</div>,
            dataIndex: 'using',
            key: 'using',
            width: widths[0],
            render: (v, r) => <Checkbox
                dataKey={r.key}
                onChange={(e) => {
                    let target = e.target;
                    let key = target.dataKey;
                    let columns = dataSourceDetail.columns.map(c => {
                        if(c.key === key) {
                            c.using = target.checked;
                        }
                        return c;
                    });

                    dispatch({ type: 'dataSourceDetail/setField', name: 'columns', value: columns });
                }}
                checked={v}
            />
        }, {
            title: '列名',
            dataIndex: 'name',
            key: 'name',
            width: widths[1],
            ...this.getColumnSearchProps('name'),
        // }, {
        //     title: '备注',
        //     dataIndex: 'description',
        //     key: 'description',
        //     width: widths[2],
        // }, {
        //     title: '数据类型',
        //     dataIndex: 'dataType',
        //     key: 'dataType',
        //     width: widths[3]
        }, {
            title: '分析类型',
            dataIndex: 'columnType',
            key: 'columnType',
            width: widths[2],
            render: (text, record) => {
                return (
                    <Select
                        style={{ width: '100%' }}
                        value={text}
                        onChange={(value) => {
                            let columns = dataSourceDetail.columns.map(c => {
                                if(c.key === record.key) {
                                    c.columnType = value;
                                    c.groupable = c.columnType === 'categorical';
                                    c.bucketizable = ['time', 'scale', 'ordinal'].indexOf(record.columnType) !== -1;
                                }
                                return c;
                            });
                            dispatch({ type: 'dataSourceDetail/setField', name: 'columns', value: columns });
                        }}
                    >
                    {
                        COLUMN_TYPE.map( c => {
                            let dataType = record.dataType;
                            if(c.dataType.indexOf(dataType) !== -1) {
                                return <SelectOption value={c.columnType} key={c.columnType}>{c.label}</SelectOption>
                            }else {
                                return null
                            }
                            
                        }).filter((s)=>s!==null)
                    }
                    </Select>
                )
            }
        }, {
            title: <div><Checkbox
                style={{ margin: '0 8px 0 0', display: dataSourceDetail.columns ? (dataSourceDetail.columns.length > 0 ? 'inline-block' : 'none') : 'none'}}
                indeterminate={dataSourceDetail.columns ? (dataSourceDetail.columns.filter(c => c.groupable).length > 0 && dataSourceDetail.columns.filter(c => c.groupable).length < dataSourceDetail.columns.length) : false}
                checked={dataSourceDetail.columns ? (dataSourceDetail.columns.filter(c => c.groupable).length === dataSourceDetail.columns.length) : false}
                onChange={(e) => {
                    let target = e.target;
                    let columns = dataSourceDetail.columns ? dataSourceDetail.columns.map(c => {
                        c.groupable = target.checked;
                        return c;
                    }) : [];

                    dispatch({ type: 'dataSourceDetail/setField', name: 'columns', value: columns });
                }}
            />允许分组</div>,
            dataIndex: 'groupable',
            key: 'groupable',
            width: widths[3],
            render: (v, r) => <Checkbox
                dataKey={r.key}
                onChange={(e) => {
                    let target = e.target;
                    let key = target.dataKey;
                    let columns = dataSourceDetail.columns.map(c => {
                        if(c.key === key) {
                            c.groupable = target.checked;
                        }
                        return c;
                    });

                    dispatch({ type: 'dataSourceDetail/setField', name: 'columns', value: columns });
                }}
                checked={v}
            />
        }, {
            title: <div><Checkbox
                style={{ margin: '0 8px 0 0', display: dataSourceDetail.columns ? (dataSourceDetail.columns.length > 0 ? 'inline-block' : 'none') : 'none'}}
                indeterminate={dataSourceDetail.columns ? (dataSourceDetail.columns.filter(c => c.filterable).length > 0 && dataSourceDetail.columns.filter(c => c.filterable).length < dataSourceDetail.columns.length) : false}
                checked={dataSourceDetail.columns ? (dataSourceDetail.columns.filter(c => c.filterable).length === dataSourceDetail.columns.length) : false}
                onChange={(e) => {
                    let target = e.target;
                    let columns = dataSourceDetail.columns ? dataSourceDetail.columns.map(c => {
                        c.filterable = target.checked;
                        return c;
                    }) : [];

                    dispatch({ type: 'dataSourceDetail/setField', name: 'columns', value: columns });
                }}
            />允许过滤</div>,
            dataIndex: 'filterable',
            key: 'filterable',
            width: widths[4],
            render: (v, r) => <Checkbox
                dataKey={r.key}
                onChange={(e) => {
                    let target = e.target;
                    let key = target.dataKey;
                    let columns = dataSourceDetail.columns.map(c => {
                        if(c.key === key) {
                            c.filterable = target.checked;
                        }
                        return c;
                    });

                    dispatch({ type: 'dataSourceDetail/setField', name: 'columns', value: columns });
                }}
                checked={v}
            />
        // }, {
        //     title: '允许分组',
        //     dataIndex: 'groupable',
        //     key: 'groupable',
        //     width: 50,
        //     className: 'column-groupable',
        //     render: (value, record) => <Switch disabled={record.columnType!=='categorical'} checked={value} onChange={(checked) => {
        //         let columns = dataSourceDetail.columns.map(c => {
        //             if(c.key === record.key) {
        //                 c.groupable = checked;
        //             }
        //             return c;
        //         });
        //         dispatch({ type: 'dataSourceDetail/setField', name: 'columns', value: columns });
        //     }}/>
        // }, {
        //     title: '允许分段',
        //     dataIndex: 'bucketizable',
        //     key: 'bucketizable',
        //     width: 50,
        //     className: 'column-bucketizable',
        //     render: (value, record) => <Switch
        //         disabled={['time', 'scale', 'ordinal'].indexOf(record.columnType)===-1}
        //         checked={value}
        //         defaultChecked={true}
        //         onChange={(checked) => {
        //             let columns = dataSourceDetail.columns.map(c => {
        //                 if(c.key === record.key) {
        //                     c.bucketizable = checked;
        //                 }
        //                 return c;
        //             });
        //             dispatch({ type: 'dataSourceDetail/setField', name: 'columns', value: columns });
        //         }}
        //     />
        }, {
            title: '别名',
            dataIndex: 'alias',
            key: 'alias',
            // width: widths[5],
            ...this.getColumnSearchProps('alias'),
            render: (text, record) => {
                return(
                    <Input
                        key={text}
                        defaultValue={text}
                        placeholder={record.description ? record.description.substring(0, 10) : record.name}
                        onBlur={(e) => {
                            const value = e.target.value;
                            let columns = dataSourceDetail.columns.map(c => {
                                if(c.key === record.key) {
                                    c['alias'] = value;
                                }
                                return c;
                            });
                            
                            dispatch({ type: 'dataSourceDetail/setField', name: 'columns', value: columns });
                        }}
                    >
                    </Input>
                )
            }
        // }, {
        //     title: '允许过滤',
        //     dataIndex: 'filterable',
        //     key: 'filterable',
        //     render: (value, record) => <Switch />
        }].map((col, index) => ({
            ...col,
            onHeaderCell: column => ({
                width: column.width,
                onResize: this.handleResize(index),
            }),
        }));

        return (
            <div ref={node => this.columnConfigRef = node}className='column-config'>
                {
                    dataSourceDetail.type==='database'?(
                        <div className='sql-area'>
                            <Row className='divider'>数据对象</Row>
                            <Form size='small'>
                                <FormItem className='textarea-target'>
                                    <Input.TextArea
                                        disabled={!dataSourceDetail.address}
                                        placeholder={dataSourceDetail.address ? '输入表名或查询SQL，注意不能以分号结尾' : '请先返回上一步选择数据库连接'}
                                        autosize={{ minRows: 3 }}
                                        // value={dataSourceDetail.target}
                                        defaultValue={dataSourceDetail.target}
                                        onBlur={(e) => {
                                            if(e.target.value !== dataSourceDetail.target) {
                                                dispatch({ type: 'dataSourceDetail/setFields', fields: [
                                                    { name: 'target', value: e.target.value },
                                                    { name: 'notice', value: '' },
                                                    { name: 'targetDirty', value: true }
                                                ] });
                                            }
                                        }}
                                        // onChange={(e) => {
                                        //     dispatch({ type: 'dataSourceDetail/setFields', fields: [
                                        //         { name: 'target', value: e.target.value },
                                        //         { name: 'notice', value: '' }
                                        //     ] });
                                        // }}
                                    />
                                </FormItem>
                                <div className='buttons'>
                                    <div className='errormessage'>{dataSourceDetail.notice}</div>
                                    <Tooltip
                                        title={
                                            <div>
                                                <div className="ant-popover-message">
                                                    <Icon type="exclamation-circle" theme="filled" style={{ color: '#faad14' }} />
                                                    <div className="ant-popover-message-title">已存在列数据，确定要覆盖吗？</div>
                                                </div>
                                                <div className="ant-popover-buttons">
                                                    <button type="button" className="ant-btn ant-btn-sm" onClick={() => {
                                                        this.setState({
                                                            visibleConfirm: false
                                                        });
                                                    }}>
                                                        <span>取 消</span>
                                                    </button>
                                                    <button type="button" className="ant-btn ant-btn-primary ant-btn-sm" onClick={() => {
                                                        this.setState({
                                                            visibleConfirm: false
                                                        });
                                                        dispatch({ type: 'dataSourceDetail/importColumns', cover: true });
                                                    }}>
                                                        <span>全部覆盖</span>
                                                    </button>
                                                    <button type="button" className="ant-btn ant-btn-primary ant-btn-sm" onClick={() => {
                                                        this.setState({
                                                            visibleConfirm: false
                                                        });
                                                        dispatch({ type: 'dataSourceDetail/importColumns', cover: false });
                                                    }}>
                                                        <span>保留重复</span>
                                                    </button>
                                                </div>
                                            </div>
                                        }
                                        visible={this.state.visibleConfirm}
                                        onVisibleChange={this.handleVisibleChange}
                                        trigger='click'
                                    >
                                        <Button type={!fetching && dataSourceDetail.targetDirty ? 'danger' : null} disabled={!dataSourceDetail.address || fetching} onClick={() => {
                                            if(!dataSourceDetail.columns || dataSourceDetail.columns.length === 0) {
                                                dispatch({ type: 'dataSourceDetail/importColumns', cover: true });
                                            }
                                        }}>
                                        {fetching && <Icon type="loading" theme="outlined" />}
                                        {!fetching && dataSourceDetail.targetDirty ? '重新获取数据列' : '获取数据列'}
                                        </Button>
                                    </Tooltip>
                                </div>
                            </Form>
                            <Row className='divider'>数据列</Row>
                        </div>
                    ):null
                }
                <Table
                    className='table-columnconfig'
                    bordered
                    components={this.components}
                    dataSource={dataSourceDetail.columns}
                    columns={columns}
                    locale={{
                        emptyText: '未连接到数据对象'
                    }}
                    pagination={{
                        pageSize,
                    }}
                />
            </div>
        );
    }
}

function mapStateToProps({ present: { dataSourceDetail, loading } }) {
    const fetching = loading.effects['dataSourceDetail/importColumns'];
    return {
        fetching,
        dataSourceDetail
    }
}

export default connect(mapStateToProps)(DataSourceColumnConfig);