import React from 'react';
import { Button, Spin } from 'antd';
import List from 'antd-mobile/lib/list';
import 'antd-mobile/lib/list/style/css'; 
import InputItem from 'antd-mobile/lib/input-item';
import 'antd-mobile/lib/input-item/style/css'; 
import Calendar from 'antd-mobile/lib/calendar';
import 'antd-mobile/lib/calendar/style/css';
import DatePicker from 'antd-mobile/lib/date-picker';
import 'antd-mobile/lib/date-picker/style/css';
import DatePickerView from 'antd-mobile/lib/date-picker-view';
import 'antd-mobile/lib/date-picker-view';
import Menu from 'antd-mobile/lib/menu';
import 'antd-mobile/lib/menu/style/css';
import moment from 'moment';
import calendar_zhCN from 'antd-mobile/lib/calendar/locale/zh_CN';
import datePicker_zhCN from 'antd-mobile/lib/date-picker/locale/zh_CN';
import URLS from '../../constants/url';
import * as service from '../../services/index'
import './mobileFilterList.less';

const ListItem = List.Item;
const now = new Date();
const ranges = [
    { label: '今天', value : [new Date(moment().startOf('day')), new Date(moment().endOf('day'))] },
    { label: '本月', value: [new Date(moment().startOf('month')), new Date(moment().endOf('month'))] },
    { label: '上月', value: [new Date(moment().month(moment().month() - 1).startOf('month')), new Date(moment().month(moment().month() - 1).endOf('month'))] },
    { label: '近半年', value: [new Date(moment().subtract(6, "months").startOf('day')), new Date(moment().endOf('day'))] },
    { label: '本年', value: [new Date(moment().startOf('year')), new Date(moment().endOf('year'))] },
    { label: '上年', value: [new Date(moment().subtract(1, "years").startOf('year')), new Date(moment().subtract(1, "years").endOf('year'))] },
]

class MobileFilterList extends React.Component {
    originbodyScrollY = document.getElementsByTagName('body')[0].style.overflowY;

    state = {
        currentFilter: undefined,
        showCalendar: false,
        showMenu: false,
        calendarConfig: {},
        calendarValue: false,
        showCalendarDatePicker: false,
        calendarStartDate: undefined,
        calendarEndDate: undefined,
        calendarDatePickerStartDate: undefined,
        calendarDatePickerEndDate: undefined,
        menuConfig: {},
        menuData: [{ value: 'nothing', label: '暂无数据', disabled: true }],
        menuSelected: []
    }

    changeFilterValue = (filter, value, index) => {
        const { changeFilterValue: propsChangeFilterValue } = this.props;
        filter['value' + index] = value;
        if(propsChangeFilterValue && typeof propsChangeFilterValue === 'function') {
            propsChangeFilterValue({ ...filter });
        }
    }

    changeFilterValues = (filter, values) => {
        const { changeFilterValue: propsChangeFilterValue } = this.props;
        filter['value1'] = values[0];
        filter['value2'] = values[1];
        if(propsChangeFilterValue && typeof propsChangeFilterValue === 'function') {
            propsChangeFilterValue({ ...filter });
        }
    }

    generateFilterItems = () => {
        const { filters } = this.props;

        return filters.map((filter, index) => {
            let { type, label, operator, operatorLabel, value1, value2 } = filter;
            let filterItem;

            if(['index', 'string'].indexOf(type) !== -1) {
                filterItem = <List key={`filter-value-${index}-${value1}`} renderHeader={() => `${label} (${operatorLabel}) :`}>
                    <InputItem
                        defaultValue={value1}
                        clear
                        onBlur={(value) => {
                            if(value !== value1) {
                                this.changeFilterValue(filter, value, 1)
                            }
                        }}
                    />
                </List>
            }else if(['scale', 'ordinal'].indexOf(type) !== -1) {
                if(operator === 'between') {
                    filterItem = <List className='row' key={`filter-value-${index}-${value1}-${value2}`} renderHeader={() => `${label} (${operatorLabel}) :`}>
                        <InputItem
                            defaultValue={value1}
                            type="digit"
                            clear
                            onBlur={(value) => {
                                if(value !== value1) {
                                    this.changeFilterValue(filter, value, 1)
                                }
                            }}
                        />
                        至
                        <InputItem
                            defaultValue={value2}
                            type="digit"
                            clear
                            onBlur={(value) => {
                                if(value !== value2) {
                                    this.changeFilterValue(filter, value, 2)
                                }
                            }}
                        />
                    </List>
                }else {
                    filterItem = <List key={`filter-value-${index}-${value1}`} renderHeader={() => `${label} (${operatorLabel}) :`}>
                        <InputItem
                            defaultValue={value1}
                            type="digit"
                            clear
                            onBlur={(value) => {
                                if(value !== value1) {
                                    this.changeFilterValue(filter, value, 1)
                                }
                            }}
                        />
                    </List>
                }
            }else if(type === 'time') {
                if(operator === 'between') {
                    filterItem = <List key={Math.random()} renderHeader={() => `${label} (${operatorLabel}) :`}>
                        <ListItem
                            onClick={() => {
                                console.log(value1, value2);
                                document.getElementsByTagName('body')[0].style.overflowY = 'hidden';
                                let obj = {};
                                obj.showCalendar = true;
                                obj.currentFilter = filter;
                                obj.calendarValue = value1 && value2 ? [new Date(value1), new Date(value2)] : false;
                                this.setState(obj);
                            }}
                        >{value1 ? `${moment(value1).format('YYYY-MM-DD')} 至 ${moment(value2).format('YYYY-MM-DD')}` : ''}</ListItem>
                    </List>
                }else {
                    filterItem = <List key={Math.random()} renderHeader={() => `${label} (${operatorLabel}) :`}>
                        <DatePicker
                            mode="date"
                            defaultValue={value1}
                            onChange={(value) => {
                                this.changeFilterValue(filter, value, 1)
                            }}
                            minDate={new Date(moment().subtract(50, 'years'))}
                            maxDate={new Date(moment().add(50, 'years'))}
                            locale={datePicker_zhCN}
                        >
                            <ListItem>{value1 ? moment(value1).format('YYYY-MM-DD') : ''}</ListItem>
                        </DatePicker>
                    </List>
                }
            }else if(type === 'categorical') { // 类别
                if(operator === 'include' || operator==='notInclude') { // 包含/不包含
                    filterItem = <List key={Math.random()} renderHeader={() => `${label} (${operatorLabel}) :`}>
                        <InputItem
                            defaultValue={value1}
                            clear
                            onBlur={(value) => {
                                if(value !== value1) {
                                    this.changeFilterValue(filter, value, 1)
                                }
                            }}
                        />
                    </List>
                }else if(operator === 'contain' || operator === 'notContain') { // 包括/不包括
                    filterItem = <List key={Math.random()} renderHeader={() => `${label} (${operatorLabel}) :`}>
                        <ListItem onClick={() => {
                            this.fetchColumnData(filter);
                            this.setState({
                                currentFilter: filter,
                                menuConfig: {
                                    single: false
                                },
                                menuSelected: value1,
                                showMenu: true,
                            });
                        }}>{value1.join(',')}</ListItem>
                    </List>
                }else { // 等于/不等于
                    filterItem = <List key={Math.random()} renderHeader={() => `${label} (${operatorLabel}) :`}>
                        <ListItem onClick={() => {
                            this.fetchColumnData(filter);
                            this.setState({
                                currentFilter: filter,
                                menuConfig: {
                                    single: true
                                },
                                menuSelected: value1 ? [value1] : [],
                                showMenu: true,
                            });
                        }}>{value1}</ListItem>
                    </List>
                }
            }else {
                filterItem = <List key={`filter-value-${index}-${value1}`} renderHeader={() => `${label} (${operatorLabel}) :`}>
                    <InputItem
                        defaultValue={value1}
                        clear
                        onBlur={(value) => {
                            if(value !== value1) {
                                this.changeFilterValue(filter, value, 1)
                            }
                        }}
                    />
                </List>
            }

            return filterItem;
        });
    }

    onCalendarCancel = () => {
        document.getElementsByTagName('body')[0].style.overflowY = this.originbodyScrollY;
        this.setState({
            showCalendar: false,
        });
    }

    onMenuOk = (value) => {
        this.setState({
            showMenu: false
        });
        this.changeFilterValue(this.state.currentFilter, this.state.menuConfig.single ? value[0] : value, 1)
    }

    onMenuCancel = () => {
        this.setState({
            showMenu: false
        });
    }

    fetchColumnData = (filter, options) => {
        const { keyword, mandatory } = options || {};
        const { key: fkey, combined : isCusMode, dataSource, value1 } = filter;
        const menuData = this.state[`menuData-${fkey}`] || [];
        let columns;
        if(isCusMode) {
            columns = dataSource.map(d => ({
                id: d.dataSource.code,
                columnName: d.column.name,
                keyword,
            }))
        }
        if(!menuData || menuData.length === 0 || mandatory) {
            let obj = {};
            obj[`menuData-${fkey}`] = [];
            this.setState({ ...obj, menuData: [{ value: 'nothing', label: <div><Spin size="small" />加载中...</div>, disabled: true }], fetching: true }, () => {
                const body = isCusMode ? columns : {
                    id: dataSource.code,
                    columnName: filter.name,
                    keyword, 
                };
                service.fetch({
                    url: isCusMode ? URLS.DATASOURCE_QUERY_COLUMNDATA_MUL : URLS.DATASOURCE_QUERY_COLUMNDATA,
                    allow: true,
                    body: body,
                }).then(r => {
                    if(r.code > 0) {
                        return r;
                    }else {
                        let obj = {};
                        throw obj;
                    }
                }).then(r => {
                    const resData = r.data || [];
                    // 需要把已经选择的值作为选项展示出来
                    if(value1) {
                        if(value1 instanceof Array) { // 如果value1是数组
                            value1.forEach(v => {
                                let idx = resData.findIndex(r => r === v);
                                if(idx > -1) {
                                    resData.splice(idx, 1);
                                }
                            });
                            let obj = {},
                                data = value1.concat(resData).map(d => ({
                                    value: d, label: d
                                }));
                            obj[`menuData-${fkey}`] = data;
                            this.setState({
                                ...obj,
                                menuData: data,
                                fetching: false
                            });
                        }else {
                            let idx = resData.findIndex(r => r === value1);
                            let obj = {},
                                data = [value1].concat(resData).map(d => ({
                                    value: d, label: d
                                }));
                            if(idx > -1) {
                                resData.splice(idx, 1);
                            }

                            obj[`menuData-${fkey}`] = data;
                            this.setState({
                                ...obj,
                                menuData: data,
                                fetching: false
                            });
                        }
                    }else {
                        let obj = {},
                        data = resData.map(d => ({ value: d, label: d }));
                        obj[`menuData-${fkey}`] = data;
                        this.setState({
                            ...obj,
                            menuData: data.length > 0 ? data : [{
                                value: 'nothing',
                                label: '暂无数据',
                                disabled: true
                            }],
                            fetching: false
                        });
                    }
                }).catch(ex => {
                    let obj = {};
                    obj[`menuData-${fkey}`] = [];
                    this.setState({
                        ...obj,
                        menuData: [{ value: 'nothing', label: '暂无数据', disabled: true }],
                        fetching: false
                    });
                    console.error('fetch error', ex);
                });
            });
        }else {
            this.setState({
                menuData: menuData,
            });
        }
    }

    renderCalendarHeader = (headerProps) => {
        return <div className="header">
            <span className="left" onClick={() => {
                this.setState({
                    showCalendar: false
                })
            }}>
                <svg className="am-icon am-icon-cross am-icon-md">
                    <svg id="cross" viewBox="0 0 44 44"><path fillRule="evenodd" d="M24.008 21.852l8.97-8.968L31.092 11l-8.97 8.968L13.157 11l-1.884 1.884 8.968 8.968-9.24 9.24 1.884 1.885 9.24-9.24 9.24 9.24 1.885-1.884-9.24-9.24z"></path></svg>
                </svg>
            </span>
            <span className="title" onClick={() => {
                this.setState({
                    showCalendarDatePicker: true,
                    calendarDatePickerStartDate: this.state.calendarStartDate,
                    calendarDatePickerEndDate: this.state.calendarEndDate
                })
            }}>日期选择</span>
            <span className="right" onClick={() => {
                headerProps.onClear();
                this.setState({
                    showCalendar: false,
                })
                this.changeFilterValues(this.state.currentFilter, [undefined, undefined]);
            }}>清除</span>
        </div>
    }

    renderCalendarShortcut = (select) => {
        return <div className="shortcut-panel">
            { ranges.map((r, i) => (
                <div key={i} className="item" onClick={() => {
                    select(r.value[0], r.value[1]);
                    this.setState({
                        calendarStartDate: r.value[0],
                        calendarEndDate: r.value[1]
                    });
                }}>{r.label}</div>
            )) }
            {
                // 下面的元素写在这里只是为了使用select事件给日历面板赋值
            }
            { this.state.showCalendarDatePicker && <div className="menu-mask" onClick={() => {
                this.setState({
                    showCalendarDatePicker: false
                })
            }} /> }
            { this.state.showCalendarDatePicker && <div className='calendar-date-picker'>
                <div className="am-picker-popup-header">
                    <div className="am-picker-popup-item am-picker-popup-header-left" onClick={() => {
                        this.setState({
                            showCalendarDatePicker: false,
                        })
                    }}>取消</div>
                    <div className="am-picker-popup-item am-picker-popup-title"></div>
                    <div className="am-picker-popup-item am-picker-popup-header-right" onClick={() => {
                        select(this.state.calendarDatePickerStartDate, this.state.calendarDatePickerEndDate);
                        this.setState({
                            showCalendarDatePicker: false,
                            calendarStartDate: this.state.calendarDatePickerStartDate,
                            calendarEndDate: this.state.calendarDatePickerEndDate
                        })
                    }}>确定</div>
                </div>
                <div className="sub-title">开始时间</div>
                <DatePickerView
                    mode='date'
                    value={this.state.calendarDatePickerStartDate || (this.state.calendarDatePickerEndDate || now)}
                    minDate={new Date(moment().subtract(50, 'years'))}
                    maxDate={new Date(moment().add(50, 'years'))}
                    onChange={(value) => {
                        let obj = {
                            calendarDatePickerStartDate: value
                        };
                        if(this.state.calendarDatePickerEndDate && moment(value).isAfter(this.state.calendarDatePickerEndDate)) {
                            obj.calendarDatePickerEndDate = value;
                        }
                        this.setState(obj)
                    }}
                />
                <div className="sub-title">结束时间</div>
                <DatePickerView
                    mode='date'
                    value={this.state.calendarDatePickerEndDate || (this.state.calendarDatePickerStartDate || now)}
                    minDate={new Date(moment().subtract(50, 'years'))}
                    maxDate={new Date(moment().add(50, 'years'))}
                    onChange={(value) => {
                        let obj = {
                            calendarDatePickerEndDate: value
                        };
                        if(this.state.calendarDatePickerStartDate && moment(value).isBefore(this.state.calendarDatePickerStartDate)) {
                            obj.calendarDatePickerStartDate = value;
                        }
                        this.setState(obj)
                    }}
                />
            </div>}
        </div>
    }

    render() {
        const { filtersOpened, closeFilters, expandFilters } = this.props;
        const { showMenu, showCalendar, calendarValue, currentFilter, menuData, menuSelected, menuConfig } = this.state;
        console.log(calendarValue);
        return (
            <div className='filter-list-mobile'>
                <List
                    className='list-title'
                    renderHeader={() => <Button className='toggle' type="link" icon='bars' onClick={() => {
                        filtersOpened ? closeFilters() : expandFilters();
                    }}>{filtersOpened ? '收起' : '筛选'}</Button>}
                />
                { this.generateFilterItems() }
                <List>
                    <List.Item>
                        <div
                            style={{ width: '100%', color: '#108ee9', textAlign: 'center' }}
                            onClick={() => {
                                closeFilters();
                            }}
                        >
                            收起
                        </div>
                    </List.Item>
                </List>
                <Calendar
                    ref={node => this.calendarRef = node}
                    // key={`calendar-${hashcode(calendarValue)}`}
                    locale={calendar_zhCN}
                    visible={showCalendar}
                    onCancel={this.onCalendarCancel}
                    defaultValue={calendarValue}
                    onSelect={(date, oldDate) => {
                        let startDate = oldDate[0],
                            endDate = oldDate[1],
                            obj = {};

                        if(!startDate || endDate) {
                            obj.calendarStartDate = date;
                            // obj.calendarValue = [date, date];
                            obj.calendarEndDate = date
                        }else {
                            obj.calendarEndDate = date
                            // obj.calendarValue = [this.state.calendarStartDate, date];
                        }
                        this.setState(obj);
                    }}
                    onConfirm={(start, end) => {
                        this.changeFilterValues(currentFilter, [start, end]);
                        this.setState({
                            showCalendar: false,
                            calendarStartDate: undefined,
                            calendarEndDate: undefined
                        });
                    }}
                    // onSelectHasDisableDate={this.onSelectHasDisableDate}
                    // defaultDate={now}
                    renderHeader={this.renderCalendarHeader}
                    showShortcut={true}
                    renderShortcut={this.renderCalendarShortcut}
                    rowSize='normal'
                />
                
                {showMenu && <div className="menu-mask" onClick={() => {
                    this.setState({
                        showMenu: false
                    })
                }} />}
                {showMenu && <div className='filter-menu-box'>
                    <InputItem
                        clear
                        placeholder='搜索'
                        onChange={(value) => {
                            this.fetchColumnData(currentFilter, { keyword: value, mandatory: true })
                        }}
                    />
                    <Menu
                        multiSelect={true}
                        data={menuData}
                        className='filter-menu'
                        value={menuSelected}
                        level={1}
                        height={document.documentElement.clientHeight * 0.6}
                        onOk={this.onMenuOk}
                        onCancel={this.onMenuCancel}
                        onChange={(item) => {
                            let selected = item;
                            if(menuConfig.single) {
                                selected = item.slice(-1);
                            }
                            this.setState({
                                menuSelected: selected
                            });
                        }}
                    />
                </div>}
            </div>
        )
    }
};

export default MobileFilterList;