import React from 'react';
import {
	Upload,
	Input,
	Button,
	Select,
	Icon,
	Row,
	Col,
	message,
	Tag,
	Tooltip,
	Card,
	Divider,
	Switch,
	InputNumber,
	Form,
} from 'antd';
import AceEditor from 'react-ace';
import 'brace/mode/javascript';
import UUID from 'react-native-uuid';
const FormItem = Form.Item;
const Option = Select.Option;
const types = {
	string: '字符',
	number: '数字',
	boolean: '布尔值',
	method: '公式',
	regexp: '正则表达式',
	integer: '整数',
	float: '浮点数',
	array: '列表',
	object: '对象',
	enum: '枚举',
	date: '日期',
	url: '超链接',
	hex: '16进制数',
	email: '邮箱',
	any: '任意',
};

class Enums extends React.Component {
	state = {
		inputVisible: false,
		inputValue: '',
	};

	handleClose = (removedTag) => {
		const tags = this.props.value.filter((tag) => tag !== removedTag);
		this.props.onChange(tags);
	};

	showInput = () => {
		this.setState({ inputVisible: true }, () => this.input.focus());
	};

	handleInputChange = (e) => {
		this.setState({ inputValue: e.target.value });
	};

	handleInputConfirm = () => {
		const { inputValue } = this.state;
		let tags = this.props.value;
		if (inputValue && tags.indexOf(inputValue) === -1) {
			tags = [...tags, inputValue];
		}

		this.setState({
			inputVisible: false,
			inputValue: '',
		});
		this.props.onChange(tags);
	};

	saveInputRef = (input) => (this.input = input);

	render() {
		const { inputVisible, inputValue } = this.state;
		const tags = this.props.value;
		return (
			<div>
				{tags.map((tag, index) => {
					const isLongTag = tag.length > 20;
					const tagElem = (
						<Tag key={tag} onClose={() => this.handleClose(tag)}>
							{isLongTag ? `${tag.slice(0, 20)}...` : tag}
						</Tag>
					);
					return isLongTag ? (
						<Tooltip title={tag} key={tag}>
							{tagElem}
						</Tooltip>
					) : (
						tagElem
					);
				})}
				{inputVisible && (
					<Input
						ref={this.saveInputRef}
						type="text"
						size="small"
						style={{ width: 78 }}
						value={inputValue}
						onChange={this.handleInputChange}
						onBlur={this.handleInputConfirm}
						onPressEnter={this.handleInputConfirm}
					/>
				)}
				{!inputVisible && (
					<Tag onClick={this.showInput} style={{ background: '#fff', borderStyle: 'dashed' }}>
						<Icon type="plus" /> New Tag
					</Tag>
				)}
			</div>
		);
	}
}

export default class Validator extends React.Component {
	constructor(props) {
		super(props);
		const value = props.value || [];

		this.state = { rules: value };
	}
	triggerChange = (changedValue) => {
		// Should provide an event to pass value to Form.
		const onChange = this.props.onChange;
		if (onChange) {
			onChange(changedValue);
		}
	};
	componentWillReceiveProps(nextProps) {
		// Should be a controlled component.
		if ('value' in nextProps) {
			const value = nextProps.value;
			this.setState(value);
		}
	}
	change = (i, t, e) => {
		const { rules } = this.state;
		if (t == 'message' || t == 'pattern') {
			rules[i][t] = e.target.value;
		} else {
			rules[i][t] = e;
			if (t == 'type' && e == 'date') {
				rules[i].validatorFunc =
					"var errors = [];if (!( typeof value.getTime === 'function' &&typeof value.getMonth === 'function' &&typeof value.getYear === 'function')) {errors.push(new Error('请输入日期!', rule.field));} callback(errors);";
			}
		}

		if (!('value' in this.props)) {
			this.setState({ rules });
		}
		this.triggerChange(rules);
	};
	add = () => {
		const { rules } = this.state;
		rules.push({ id: UUID.v4(), message: '请输入' });
		if (!('value' in this.props)) {
			this.setState({ rules });
		}
		this.triggerChange(rules);
	};
	delete = (i) => {
		const { rules } = this.state;
		rules.splice(i, 1);
		if (!('value' in this.props)) {
			this.setState({ rules });
		}
		this.triggerChange(rules);
	};
	render() {
		const { rules } = this.state;
		return (
			<div>
				<Button size="small" type="primary" style={{ margin: 'auto' }} onClick={this.add}>
					新增
				</Button>
				<div style={{ minHeight: 10 }}>
					{rules.map((r, i) => (
						<div key={r.id}>
							<FormItem label="类型" labelCol={{ span: 8 }} wrapperCol={{ span: 16 }}>
								<Select
									style={{ width: 150 }}
									onChange={this.change.bind(this, i, 'type')}
									value={r.type}>
									{Object.keys(types).map((ty) => (
										<Option key={ty} value={ty}>
											{types[ty]}
										</Option>
									))}
								</Select>
							</FormItem>

							<FormItem label="是否必填" labelCol={{ span: 8 }} wrapperCol={{ span: 16 }}>
								<Switch onChange={this.change.bind(this, i, 'required')} checked={r.required} />
							</FormItem>
							<FormItem label="正则表达式" labelCol={{ span: 8 }} wrapperCol={{ span: 16 }}>
								<Input onChange={this.change.bind(this, i, 'pattern')} value={r.pattern} />
							</FormItem>
							<FormItem label="最小值" labelCol={{ span: 8 }} wrapperCol={{ span: 16 }}>
								<InputNumber onChange={this.change.bind(this, i, 'min')} value={r.min} />
							</FormItem>
							<FormItem label="最大值" labelCol={{ span: 8 }} wrapperCol={{ span: 16 }}>
								<InputNumber onChange={this.change.bind(this, i, 'max')} value={r.max} />
							</FormItem>
							<FormItem label="长度" labelCol={{ span: 8 }} wrapperCol={{ span: 16 }}>
								<InputNumber onChange={this.change.bind(this, i, 'len')} value={r.len} />
							</FormItem>
							<FormItem
								label={
									<span>
										<span style={{ color: 'red' }}> * </span>
										错误提示
									</span>
								}
								labelCol={{ span: 8 }}
								wrapperCol={{ span: 16 }}>
								<Input onChange={this.change.bind(this, i, 'message')} value={r.message} />
							</FormItem>
							<FormItem label="枚举" labelCol={{ span: 8 }} wrapperCol={{ span: 16 }}>
								<Enums onChange={this.change.bind(this, i, 'enum')} value={r.enum || []} />
							</FormItem>
							<FormItem label="自定义验证" labelCol={{ span: 24 }} wrapperCol={{ span: 24 }}>
								<AceEditor
									height={300}
									width="100%"
									onChange={this.change.bind(this, i, 'validatorFunc')}
									placeholder="var errors = [];\n
if (value == 'xxx') {
errors.push(new Error('请输入正确值!', rule.field));
}
callback(errors);
"
									mode={'javascript'}
									theme={'textmate'}
									fontSize={12}
									showPrintMargin={true}
									showGutter={true}
									highlightActiveLine={true}
									value={r.validatorFunc}
									name="UNIQUE_ID_OF_DIV"
									// keyboardHandler="vim"
									setOptions={{
										enableBasicAutocompletion: true,
										enableLiveAutocompletion: true,
										enableSnippets: true,
										showLineNumbers: true,
										tabSize: 2,
									}}
									editorProps={{ $blockScrolling: true }}
								/>
							</FormItem>

							<Button
								type="danger"
								style={{ margin: 'auto' }}
								size="small"
								onClick={this.delete.bind(this, i)}>
								删除
							</Button>
						</div>
					))}
				</div>
			</div>
		);
	}
}
