import React from 'react'
import { Form, Select, Tag, Cascader, Dropdown, Menu } from 'antd'
import { connect } from 'dva'
import GAUGE from './gauge.json'
import GRANULARITY from './granularity.json'
const FormItem = Form.Item
const { Option } = Select

const BarConfigForm = ({ autoRefresh, chartDesigner, dispatch, formItemLayout }) => {
	const columns = chartDesigner.columns;

	return (
		<Form hideRequiredMark={true}>
			<FormItem label='横轴' {...formItemLayout}>
				<Cascader
					className='barconfig-yaxis'
					value={[chartDesigner.barConfig.xAxis.column.value, chartDesigner.barConfig.xAxis.granularity.value]}
					allowClear={true}
					showSearch={{
						filter: (inputValue, path) => {
							let p0 = path[0].label.toLowerCase();
							let v = inputValue.toLowerCase();
							return p0.indexOf(v) !== -1;
						},
						sort: (a, b, inputValue) => {
							return a[0].label.localeCompare(b[0].label,"zh");
						},
						render: (inputValue, path) => {
							const reg = new RegExp('([+ \\- & | ! ( ) { } \\[ \\] ^ \" ~ * ? : ( ) \/])', 'g'); // 需要转义的字符
							let v = inputValue.replace(new RegExp('(\\\\)', 'g'), '\\$1').replace(reg, '\\$1'); // 添加转义符号
							let label0 = (path[0].label.split(new RegExp(`(${v})`, 'i')).map((fragment, i) => {
								return (
									fragment.toLowerCase().replace(new RegExp('(\\\\)', 'g'), '\\$1').replace(reg, '\\$1') === v.toLowerCase() ?
									<span key={i} style={{fontWeight: 'bold', color: 'red'}} className="highlight">{fragment}</span> :
									fragment
								)
							}))
							return <div>{label0}>{path[1].label}</div>
						}
					}}
					options={columns.filter(c =>['ordinal', 'categorical', 'time'].indexOf(c.type) !== -1).map((c, i)=>{
						
						return {
							type: c.type,
							value: c.name,
							label: c.label,
							children: GRANULARITY[c.type]
						}
					})}
					onChange={(value, items) => {
						let column = {};
						let granularity = {};
						if(items.length > 0) {
							column = { type: items[0].type, value: items[0].value, label: items[0].label };
						}
						if(items.length > 1) {
							granularity = { value: items[1].value, label: items[1].label };
						}
						dispatch({ type: 'chartDesigner/changeField', name: 'barConfig', value: { ...chartDesigner.barConfig, xAxis: { column, granularity } }, autoRefresh });
					}}
					displayRender={(label, selectedOptions) => {
						let text = '';
						let className = 'cascader-label';
						if(label.length > 0) {
							className += ' full-label';
							text += label[0];
							if(label.length > 1) {
								text += '(' + label[1] + ')';
							}
						}else {
							className += ' empty-label';
							text = '请选择...';
						}
						return <div className={className}>{text}</div>;
					}}
				>
				</Cascader>
			</FormItem>
			<FormItem label='纵轴' {...formItemLayout}>
				<Cascader
					className='gauge-item'
					value={[chartDesigner.barConfig.yAxis.column.value, chartDesigner.barConfig.yAxis.gauge.value]}
					allowClear={true}
					showSearch={{
						filter: (inputValue, path) => {
							let p0 = path[0].label.toLowerCase();
							let v = inputValue.toLowerCase();
							return p0.indexOf(v) !== -1;
						},
						sort: (a, b, inputValue) => {
							return a[0].label.localeCompare(b[0].label,"zh");
						},
						render: (inputValue, path) => {
							const reg = new RegExp('([+ \\- & | ! ( ) { } \\[ \\] ^ \" ~ * ? : ( ) \/])', 'g'); // 需要转义的字符
							let v = inputValue.replace(new RegExp('(\\\\)', 'g'), '\\$1').replace(reg, '\\$1'); // 添加转义符号
							let label0 = (path[0].label.split(new RegExp(`(${v})`, 'i')).map((fragment, i) => {
								return (
									fragment.toLowerCase().replace(new RegExp('(\\\\)', 'g'), '\\$1').replace(reg, '\\$1') === v.toLowerCase() ?
									<span key={i} style={{fontWeight: 'bold', color: 'red'}} className="highlight">{fragment}</span> :
									fragment
								)
							}))
							return <div>{label0}>{path[1].label}</div>
						}
					}}
					options={columns.map((c, i)=>{
						return {
							value: c.name,
							label: c.label,
							children: GAUGE[chartDesigner.baseConfig.viewType].map(g => {
								if(g.columnType.indexOf(c.type) !== -1) {
									return g;
								}else {
									return null;
								}
							}).filter( g => g!==null)
						}
					})}
					onChange={(value, items) => {
						let column = {};
						let gauge = {};
						if(value.length > 0) {
							column = { type: items[0].type, value: items[0].value, label: items[0].label };
							gauge = { value: items[1].value, label: items[1].label };
						}
						dispatch({ type: 'chartDesigner/changeField', name: 'barConfig', value: { ...chartDesigner.barConfig, yAxis: { column, gauge } }, autoRefresh });
					}}
					displayRender={(label, selectedOptions) => {
						let menu = selectedOptions.length > 0 ? <Menu
							selectedKeys={[chartDesigner.barConfig.yAxis.gauge.value]}
							selectable={true}
						>
							{selectedOptions[0].children.map((c, i) => {
								return <Menu.Item  data-value={c.value} data-label={c.label} key={c.value} onClick={(e) => {
									let value = e.domEvent.target.getAttribute('data-value');
									let label = e.domEvent.target.getAttribute('data-label');
									dispatch({ type: 'chartDesigner/changeField', name: 'barConfig', value: { 
										...chartDesigner.barConfig,
										yAxis: {
											column: chartDesigner.barConfig.yAxis.column,
											gauge: { value, label }
										}
									}, autoRefresh });
									e.domEvent.stopPropagation();
								}}>{c.label}</Menu.Item>
							})}
						</Menu>: [];
						let tag = selectedOptions.length > 0 ? <Dropdown
							trigger={['click']}
							overlay={menu}
						>
							<Tag size='small' onClick={(e) => {e.stopPropagation()}}>{label[1]}</Tag>
						</Dropdown>
						: null;

						return <div className={`cascader-label ${tag?'full' : 'empty'}-label`}>
							{tag}
							<span>{label[0] || '请选择...'}</span>
						</div>
					}}
				>
				</Cascader>
			</FormItem>
			<FormItem label='分组' {...formItemLayout}>
				<Select
					labelInValue={true}
					placeholder='请选择...'
					showSearch
					filterOption={(input, option) => option.props.children.toLowerCase().indexOf(input.toLowerCase()) >= 0}
					allowClear={true}
					onChange={(value) => {
						dispatch({ type: 'chartDesigner/changeField', name: 'barConfig', value: { ...chartDesigner.barConfig, groupBy: value }, autoRefresh });
					}}
					value={chartDesigner.barConfig.groupBy}
				>
					{columns.filter(c => c.groupable).map((c, i)=>{
						return (<Option key={i} value={c.name}>{c.label}</Option>)
					})}
				</Select>
			</FormItem>
		</Form>
	);
}

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

export default connect(mapStateToProps)(BarConfigForm);