import React from 'react'
import PropTypes from 'prop-types'
import { Modal, Form, Row, Col, Input, Icon, Button, Select, InputNumber, DatePicker, Spin } from 'antd'
import OPERATORS from './filterOperators.json';
import './filterBox.less'
import * as service from '../../../services/index'
import URLS from '../../../constants/url'
import * as moment from 'moment';
const FormItem = Form.Item
const SelectOption = Select.Option

let uuid = 0;
class FilterBox extends React.Component {
    
    constructor(props) {
        uuid = 0;
        super(props);
        this.state = {
            columns: props.columns || [],
            filterData: props.filterData || [],
            fetching: false, // 请求列数据状态
            columnData: [], // 列数据
        }
    }

    static propTypes = {
        columns: PropTypes.array,
        filterData: PropTypes.array
    }

    componentDidMount() {
        // 将原本的过滤条件生成可视化组件
        const { filterData } = this.state;
        this.addFilter(filterData.map(f => {
            return {
                key: uuid++,
                name: f.name,
                label: f.label,
                type: f.type,
                operator: f.operator,
                operatorLabel: f.operatorLabel,
                value1: f.value1,
                value2: f.value2,
                using: f.using
            }
        }));
    }

    removeFilter = (key) => {
        const { form } = this.props;
        const filters = form.getFieldValue('filters');
        form.setFieldsValue({
            filters: filters.filter(filter => filter.key !== key),
        });
    }

    removeAllFilters = () => {
        const { form } = this.props;
        form.setFieldsValue({
            filters: [],
        });
    }

    addFilter = (filtes) => {
        const { form } = this.props;
        const filters = form.getFieldValue('filters');
        const nextFilters = filters.concat(filtes || {
            key: uuid++,
            using: true
        });
        form.setFieldsValue({
            filters: nextFilters,
        });
    }

    /**
     * 改变过滤条件字段
     */
    changeFilterName = (filter, value) => {
        const { form } = this.props;
        const filters = form.getFieldValue('filters');

        this.setState({ columnData: [] });
        const type = this.getFilterType(value.key);
        form.setFieldsValue({
            filters: filters.map((f) => {
                if (f.key === filter.key) {
                    f.key = uuid++; // 每次重设key值以保证界面重现渲染，解决Select数据残留的问题
                    f.name = value.key;
                    f.label = value.label;
                    f.type = type;
                    f.operator = OPERATORS[f.type][0].value;
                    f.operatorLabel = OPERATORS[f.type][0].label;
                    f.value1 = f.value2 = (type === 'time' ? moment() : undefined);
                }
                return f;
            })
        });
    }

    /**
     * 改变过滤条件连接符
     */
    changeFilterOperator = (filter, value) => {
        const { form } = this.props;
        const filters = form.getFieldValue('filters');
        const type = this.getFilterType(filter.name);
        form.setFieldsValue({
            filters: filters.map((f) => {
                if (f.key === filter.key) {
                    f.key = uuid++;
                    f.operator = value.key;
                    f.operatorLabel = value.label;
                    f.value1 = f.value2 = (type === 'time' ? moment() : undefined);
                }
                return f;
            })
        });
    }

    /** 
     * 改变过滤条件的值
     */
    changeFilterValue = (filter, value, index) => {
        const { form } = this.props;
        const filters = form.getFieldValue('filters');

        form.setFieldsValue({
            filters: filters.map((f) => {
                if (f.key === filter.key) {
                    f.key = uuid++;
                    f[`value${index}`] = value;
                }
                return f;
            })
        });
    }

    /**
     * 通过列名从数据列中获得其类型
     */
    getFilterType = (name) => {
        let {
            columns
        } = this.state, i = 0, type;
        for (i; i < columns.length; i++) {
            let column = columns[i];
            if (column.name === name) {
                type = column.type;
                break;
            }
        }
        return type;
    }

    /**
     * 获得设定的过滤条件规则
     */
    getFilters = () => {
        const { form, createFilters, hideFilterBox } = this.props;
        form.validateFields((err, values) => {
            if(!err) {
                let filters = values.filters.map(f => ({
                    ...f,
                    filterLabel: this.createFilterLabel(f)
                }));
                createFilters(filters);
                hideFilterBox();
            }
        })
    }

    fetchColumnData = (column) => {
        const { type, code } = this.props;
        const { columnData } = this.state;
        if(!columnData || columnData.length === 0) {
            this.setState({ columnData: [], fetching: true }, () => {
                const body = {
                    id: code,
                    columnName: column.name
                };
                service.fetch({
                    url: type === 'chart' ? URLS.CHART_QUERY_COLUMNDATA : URLS.DATASOURCE_QUERY_COLUMNDATA,
                    body: body,
                }).then(r => {
                    console.log('获得下拉数据', body, r);
                    if(!r.err && r.data.code > 0) {
                        return r;
                    }else {
                        let obj = {};
                        throw obj;
                    }
                }).then(r => {
                    const resData = r.data.data || [];
                    this.setState({
                        columnData: resData.map(d => d || 'null'),
                        fetching: false
                    });
                }).catch(ex => {
                    this.setState({
                        columnData: [],
                        fetching: false
                    });
                    console.error('fetch error', ex);
                });
            });
        }
    }

    getFilterValueField = (key, type, operator, index) => {
        const { columns, fetching, columnData } = this.state;
        let field;
        const { form } = this.props;
        const filters = form.getFieldValue('filters');
        let filter = filters.filter((f) => {return f.key === key})[0];
        let column = columns.filter((c) => {return c.name === filter.name});
        column = column.length>0?column[0]:{selection:[]};
        column.selection = column.selection || [];
        if(['index', 'string'].indexOf(type) !== -1) {
            field = <Input onBlur={(e) => {this.changeFilterValue(filter, e.target.value, index)}}/>
        }else if(['scale', 'ordinal'].indexOf(type) !== -1) {
            field = <InputNumber onBlur={(e) => {this.changeFilterValue(filter, e.target.value, index)}}/>
        }else if(type === 'time') {
            field = <DatePicker onChange={(value) => {this.changeFilterValue(filter, value, index)}}/>
        }else if(type === 'categorical') {
            field = (<Select 
                mode={(operator==='in' || operator === 'noIn' ) ? 'multiple' : ''}
                showSearch
                notFoundContent={fetching ? <Spin size="small" /> : '无'}
                onFocus={() => {this.fetchColumnData(column)}}
                // onChange={(value) => {this.changeFilterValue(filter, value, index)}}
                onBlur={(value) => {this.changeFilterValue(filter, value, index)}}
            >
                { columnData.map((s, i) => {
                    return <SelectOption key={i} value={s}>{s}</SelectOption>
                }) }
            </Select>)
        }else {
            field = <Input onBlur={(e) => {this.changeFilterValue(filter, e.target.value, index)}}/> 
        }

        return field;
    }

    /**
     * 生成过滤规则文本
     */
    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;
    }

    getFilterItems() {
        const { columns } = this.state;
        const { getFieldDecorator, getFieldValue } = this.props.form;
        getFieldDecorator('filters', { initialValue: [] });
        const filters = getFieldValue('filters');
        const filterItems = filters.map((f, index) => {
            let { key, name, type, operator, value1, value2 } = f;
            return (
                <Row key={`filterDiv[${key}]`}>
                    <Col span={22}>
                        <Col span={7}>
                            <FormItem key={key}>
                                {getFieldDecorator(`filterName${key}`, {
                                    initialValue: name?{key: name}:undefined,
                                    rules: [{ required: true, message: '列名不能为空' }]
                                })(
                                    <Select
                                        showSearch={true}
                                        labelInValue={true}
                                        filterOption={
                                            function (inputValue, option) {
                                                let { value, children } = option.props;
                                                return value.toLowerCase().indexOf(inputValue.toLowerCase()) !== -1 ||
                                                    children.toLowerCase().indexOf(inputValue.toLowerCase()) !== -1;
                                            }
                                        }
                                        onChange={(value) => {this.changeFilterName(f, value)}}
                                    >
                                        {columns.map((c, i) => {
                                            return (
                                                <SelectOption key={i} value={c.name}>{c.label}</SelectOption>
                                            )
                                        })}
                                    </Select>)}
                            </FormItem>
                        </Col>
                        <Col span={5}>
                            <FormItem key={key} className='filterOperator'>
                                {getFieldDecorator(`filterOperator${key}`, {
                                    initialValue: operator?{key: operator}:undefined,
                                    rules: [{ required: true, message: '操作类型不能为空' }]
                                })(
                                    <Select
                                        labelInValue={true}
                                        onChange={(value) => {this.changeFilterOperator(f, value)}}
                                    >
                                        {OPERATORS[type].map((o, i) => {
                                            return <SelectOption key={i} value={o.value}>{o.label}</SelectOption>;
                                        })}
                                    </Select>
                                )}
                            </FormItem>
                        </Col>
                        <Col span={(operator&&operator!=='null'&&operator!=='notNull')?(operator==='between'?6:12):'0'}>
                            <FormItem
                                key={key}
                                className='filterValueOne'
                            >
                                {getFieldDecorator(`filterValueOne${key}`, {
                                    initialValue: type==='time' ? ( value1 ? moment(value1) : null) : value1,
                                    rules: [{ required: true, message: '该值不能为空' }]
                                })(this.getFilterValueField(key, type, operator, 1))}
                            </FormItem>
                        </Col>
                        <Col span={operator==='between'?6:0}>
                            <FormItem
                                key={key}
                                className='filterValueTwo'
                            >
                                {getFieldDecorator(`filterValueTwo${key}`, {
                                    initialValue: type==='time' ? ( value2 ? moment(value2) : null) : value2,
                                    rules: [{ required: operator==='between', message: '该值不能为空' }]
                                })(this.getFilterValueField(key, type, operator, 2))}
                            </FormItem>
                        </Col>
                    </Col>
                    <Col span={2} className='filter-remove-col' >
                        <Icon
                            className="dynamic-delete-button"
                            type="minus-circle"
                            onClick={() => { this.removeFilter(key) }}
                        />
                    </Col>
                </Row>
            );
        });

        return filterItems;
    }

    render() {
        const { visibleFilterBox, hideFilterBox } = this.props;

        return (
            <Modal
                className='filter-box'
                title={<div>筛选条件<div className='clear' onClick={()=>{this.removeAllFilters()}}>清空条件<Icon type='delete'/></div></div>}
                visible={visibleFilterBox}
                onOk={this.getFilters}
                onCancel={hideFilterBox}
                maskClosable={false}
                destroyOnClose={true}
            >
                <Form size='small'>
                    {this.getFilterItems()}
                    <Row>
                        <Col>
                            <FormItem>
                                <Button
                                    className='filter-add-button'
                                    type="dashed"
                                    onClick={() => {this.addFilter()}}
                                >
                                    <Icon type="plus" />
                                    添加
                                </Button>
                            </FormItem>
                        </Col>
                    </Row>
                </Form>
            </Modal>
        );
    }
}

export default Form.create()(FilterBox);