import fetch from 'dva/fetch';
import React from 'react';
import ReactDOM from 'react-dom';
import {
	Select,
	Button,
	Modal,
	Input,
	Transfer,
	Row,
	Col,
	Form,
	message,
	notification,
} from 'antd';
import { connect } from 'dva';
import { getToken } from '../utils/token';
import config from '@/webPublic/one_stop_public/config';

import QueryItem from './QueryItem';
import OrderItem from './OrderItem';

import FormdataWrapper from '../utils/object-to-formdata-custom';
import ButtonDiy from './ButtonDiy/ButtonDiy';
import { getHeaders } from '@/webPublic/zyd_public/utils/utils';
const Option = Select.Option;
var keyX = 1;

function swapArray(arr, index1, index2) {
	arr[index1] = arr.splice(index2, 1, arr[index1])[0];
	return arr;
}

/**
 *
 * 2019/02/21  修改导出方式为fetch
 * 增加 props.fileName 设置导出文件名称
 * mustQuerys 设置搜索条件 demo :
 *  mustQuerys={[{
                hql: 'bean.adminStatus',
                x: '=',
                v: "pass",
                c: 'com.zysoft.app.zydxl.entity.base.BaseImportantWatch$Status',
                notes: 'com.zysoft.app.zydxl.entity.base.BaseImportantWatch$Status',
              }]}
 */

const FormItem = Form.Item;
@connect(({ DataObj, loading }) => ({
	DataObj,
	loading: loading.models.DataObj,
}))
@Form.create()
export default class ExportInfo extends React.Component {
	constructor(props) {
		super(props);
		this.state = {
			visiable: false,

			queryVisiable: false,
			groupVisiable: false,
			sortVisiable: false,
			currentQueryKey: null,
			currentGroupKey: null,
			orderVisiable: false,
			currentOrderKey: null,
			querys: [],
			orders: [],
			groups: [],
			gs: [],
			os: [],
			qs: [],
			mockData: [],
			targetKeys: [],
			sourceSelectedKeys: [],
			targetSelectedKeys: [],
			infos: {},
			confirmLoading: false,
		};
	}

	onSelectChange = (sourceSelectedKeys, targetSelectedKeys) => {
		this.setState({ sourceSelectedKeys, targetSelectedKeys });
	};
	deleteQuery = (i) => {
		const querys = this.state.querys;
		querys.splice(i, 1);
		this.setState({ querys });
	};
	deleteOrder = (i) => {
		const orders = this.state.orders;
		orders.splice(i, 1);
		this.setState({ orders });
	};
	deleteGroup = (i) => {
		const groups = this.state.groups;
		groups.splice(i, 1);
		this.setState({ groups });
	};
	open = () => {
		const { dispatch } = this.props;
		dispatch({
			type: 'DataObj/getExportInfo',
			payload: {
				objId: this.props.objId,
			},
			callback: (infos) => {
				const mockData = [];
				const qs = [];
				const gs = [];
				const os = [];
				for (var key in infos) {
					const x = infos[key];
					mockData.push({
						key: x.field,
						title: x.name,
						chosen: false,
					});
					if (x.canQuery) {
						qs.push(x);
					}
					if (x.canGroup) {
						gs.push(x);
					}
					if (x.canOrder) {
						os.push(x);
					}
				}

				this.setState({
					mockData,
					infos,
					visiable: true,
					qs,
					gs,
					os,
				});
			},
		});
	};
	onCancle = () => {
		this.setState({ visiable: false });
	};
	handleChange = (targetKeys, direction, moveKeys) => {
		this.setState({ targetKeys });
	};

	up = () => {
		keyX = keyX + 1;
		var { targetKeys, targetSelectedKeys } = this.state;
		for (var i = 0; i < targetKeys.length; i++) {
			if (targetKeys[i] === targetSelectedKeys[0]) {
				if (i === 0) return;
				targetKeys = swapArray(targetKeys, i, i - 1);

				break;
			}
		}

		this.setState({ targetKeys });
	};
	down = () => {
		keyX = keyX + 1;
		var { targetKeys, targetSelectedKeys } = this.state;
		for (var i = 0; i < targetKeys.length; i++) {
			if (targetKeys[i] === targetSelectedKeys[0]) {
				if (i === targetKeys.length - 1) return;
				targetKeys = swapArray(targetKeys, i, i + 1);

				break;
			}
		}

		this.setState({ targetKeys });
	};
	bottom = () => {
		keyX = keyX + 1;
		const { targetKeys, targetSelectedKeys } = this.state;
		var x = [];
		for (var i = 0; i < targetKeys.length; i++) {
			if (!targetSelectedKeys.includes(targetKeys[i])) {
				x.push(targetKeys[i]);
			}
		}
		x = [...x, ...targetSelectedKeys];
		this.setState({ targetKeys: x });
	};
	top = () => {
		keyX = keyX + 1;
		const { targetKeys, targetSelectedKeys } = this.state;
		const x = [...targetSelectedKeys];
		for (var i = 0; i < targetKeys.length; i++) {
			if (!targetSelectedKeys.includes(targetKeys[i])) {
				x.push(targetKeys[i]);
			}
		}

		this.setState({ targetKeys: x });
	};
	renderItem = (item) => {
		if (this.state.targetKeys.includes(item.key)) {
			const customLabel = (
				<span className="custom-item" key={item.key}>
					{item.title}
				</span>
			);
			return {
				label: customLabel, // for displayed item
				value: item.title, // for title and filter matching
			};
		} else {
			const customLabel = (
				<span className="custom-item" key={item.key}>
					{item.title}
				</span>
			);
			return {
				label: customLabel, // for displayed item
				value: item.title, // for title and filter matching
			};
		}
	};
	addOrder = () => {
		this.setState({ orderVisiable: true });
	};
	okOrder = () => {
		const orders = this.state.orders;
		orders.push(this.state.infos[this.state.currentOrderKey]);
		this.setState({ orders, orderVisiable: false, currentOrderKey: null });
	};
	okGroup = () => {
		const groups = this.state.groups;
		groups.push(this.state.infos[this.state.currentGroupKey]);
		this.setState({ groups, groupVisiable: false, currentGroupKey: null });
	};
	addGroup = () => {
		this.setState({ groupVisiable: true });
	};

	addQuery = () => {
		this.setState({ queryVisiable: true });
	};
	okQuery = () => {
		const querys = this.state.querys;
		querys.push(this.state.infos[this.state.currentQueryKey]);
		this.setState({ querys, queryVisiable: false, currentQueryKey: null });
	};
	export = () => {
		this.props.form.validateFields((err, fieldsValue) => {
			if (err) return;
			//form.resetFields();
			var qqs;
			if (this.props.mustQuerys != null) {
				qqs = [...this.props.mustQuerys];
			} else {
				qqs = [];
			}

			const oos = [];
			const ggs = [];
			for (let key in fieldsValue) {
				var x = key.indexOf('__');
				let kk = key.substr(x + 2);
				if (key.indexOf('q__') > -1) {
					qqs.push({
						notes: this.state.infos[kk].notes,
						hql: this.state.infos[kk].hql,
						c: this.state.infos[kk].type,
						x: fieldsValue[key].stringX,
						v: fieldsValue[key].string,
					});
				} else if (key.indexOf('o__') > -1) {
					oos.push({ hql: this.state.infos[kk].hql, x: fieldsValue[key].stringX });
				} else if (key.indexOf('g__') > -1) {
					ggs.push({ hql: this.state.infos[kk].hql });
				}
			}

			if (this.props.voClass && ggs.length === 0) {
				message.error('请至少选择一个聚合条件');
				return;
			}
			if (this.state.targetKeys.length === 0) {
				message.error('请至少选择一个导出字段');
				return;
			}
			const names = [];
			for (let i = 0; i < this.state.targetKeys.length; i++) {
				names.push(this.state.infos[this.state.targetKeys[i]].name);
			}
			let divElement = document.getElementById('downloadDiv');
			let downloadUrl = config.httpServer + '/DataObjApi/exportFormData?';
			const token = getToken() != null && getToken() != 'null' ? getToken() : '0000';
			downloadUrl = `${downloadUrl}token=${token}`;
			let param = {
				fields: this.state.targetKeys,
				names: names,
				beanName: this.props.beanName,
				querys: JSON.stringify(qqs),
				orders: JSON.stringify(oos),
				groups: JSON.stringify(ggs),
				voClass: this.props.voClass,
				objId: this.props.objId,
				modelClass: this.props.modelClass,
				preHandleClass: this.props.preHandleClass,
				hqlHandleClass: this.props.hqlHandleClass,
			};
			param = { ...param, ...(this.props.params || {}) };
			// ReactDOM.render(
			//   <form action={downloadUrl} method="post" target="_blank">
			//
			//     {this.state.targetKeys.map((r, i) => <input key={r + i}
			//                                                 name="fields"
			//                                                 readOnly={true}
			//                                                 type="text"
			//                                                 value={r}/>)}
			//     {names.map((r, i) => <input key={r + i}
			//                                 name="names"
			//                                 type="text"
			//                                 readOnly={true}
			//                                 value={r}/>)}
			//     <input name="beanName"
			//            type="text"
			//            value={this.props.beanName}
			//            readOnly={true}
			//
			//     />
			//     <input name="querys"
			//            type="text"
			//            readOnly={true}
			//            value={JSON.stringify(qqs)}/>
			//     <input name="orders"
			//            type="text"
			//            readOnly={true}
			//            value={JSON.stringify(oos)}/>
			//     <input name="groups"
			//            type="text"
			//            readOnly={true}
			//            value={JSON.stringify(ggs)}/>
			//     <input name="voClass"
			//            type="text"
			//            readOnly={true}
			//            value={this.props.voClass}/>
			//     <input name="daoClass"
			//            type="text"
			//            readOnly={true}
			//            value={this.props.daoClass}/>
			//     <input name="modelClass"
			//            type="text"
			//            readOnly={true}
			//            value={this.props.modelClass}/>
			//   </form>,
			//   divElement,
			// );
			//
			// ReactDOM.findDOMNode(divElement).querySelector('form').submit();
			// ReactDOM.unmountComponentAtNode(divElement);
			//this.setState({loading:false})

			this.downloadFile(downloadUrl, param);
		});
	};

	downloadFile(url, params) {
		this.setState({ confirmLoading: true });

		fetch(url, {
			method: 'POST',
			body: FormdataWrapper(params),
      ...getHeaders()
		})
			.then((res) => {
				if (res.status != '200') {
					return res.json();
				} else {
					return res.blob();
				}
			})
			.then((data) => {
				if (data instanceof Blob) {
					let a = document.createElement('a');
					let url = window.URL.createObjectURL(data);
					let filename = (this.props.fileName ? this.props.fileName : '导出文件') + '.xlsx';
					a.href = url;
					a.download = filename;
					a.click();
					window.URL.revokeObjectURL(url);
					a = null;
				} else {
					notification.error({
						message: `文件导出错误`,
						description: data.errMsg,
					});
				}
			})
			.catch((err) => {
				notification.error({
					message: `网络请求超时`,
				});
			})
			.finally(() => {
				this.setState({ confirmLoading: false });
			});
	}

	cancelGroup = () => {
		this.setState({ currentGroupKey: null, groupVisiable: false });
	};
	cancelQuery = () => {
		this.setState({ currentQueryKey: null, queryVisiable: false });
	};
	cancelOrder = () => {
		this.setState({ currentOrderKey: null, orderVisiable: false });
	};
	selectOrder = (e) => {
		this.setState({ currentOrderKey: e });
	};
	selectQuery = (e) => {
		this.setState({ currentQueryKey: e });
	};
	selectGroup = (e) => {
		this.setState({ currentGroupKey: e });
	};

	render() {
		const { form } = this.props;
		const {
			visiable,
			targetKeys,
			sourceSelectedKeys,
			queryVisiable,
			querys,
			orders,
			groups,
			confirmLoading,
			targetSelectedKeys,
			mockData,
			qs,
			os,
			gs,
			currentQueryKey,
			currentOrderKey,
			orderVisiable,
			currentGroupKey,
			groupVisiable,
		} = this.state;

		return (
			<span data-com-name={'自定义导出ExportInfo.js'}>
				<ButtonDiy
					name="自定义导出"
          type="primary"
					handleClick={this.open}
				/>
				<div id="downloadDiv" style={{ display: 'none' }} />
				<Modal
					width={670}
					maskClosable={false}
					destroyOnClose
					title="自定义查询、排序、导出"
					style={{ textAlign: 'center' }}
					visible={visiable}
					onOk={this.export}
					onCancel={this.onCancle}
					confirmLoading={confirmLoading}>
					<div style={{ overflowY: 'auto', maxHeight: '500px', height: '500px' }}>
						<div style={{ textAlign: 'left' }}>
							<ButtonDiy type="primary" name="新增查询条件" />

							<Select
								style={{ width: 200, paddingRight: '10px' }}
								value={currentQueryKey}
								onChange={this.selectQuery}>
								{qs.map((r) => {
									return (
										<Option key={r.field} value={r.field}>
											{r.name}
										</Option>
									);
								})}
							</Select>
							{currentQueryKey ? (
								<span style={{ paddingLeft: '0' }}>
									<ButtonDiy type="primary" name="确定" handleClick={this.okQuery} />
								</span>
							) : (
								''
							)}
							<div style={{ height: '12px' }} />
							{querys.map((r, i) => (
								<FormItem
									key={r.name + i}
									labelCol={{ span: 4 }}
									wrapperCol={{ span: 20 }}
									colon={false}
									label={r.name}>
									{form.getFieldDecorator(i + 'q__' + r.field, {
										initialValue: { stringX: '=' },
										rules: [
											{
												validator: (rule, value, callback) => {
													var errors = [];
													if (value == null) {
														errors.push(new Error('请输入查询值!', rule.field));
													} else {
														if (
															value.stringX != 'IS NOT NULL' &&
															value.stringX != 'IS NULL' &&
															value.string == null
														) {
															errors.push(new Error('请输入查询值!', rule.field));
														}
													}
													callback(errors);
												},
											},
										],
									})(
										<QueryItem
											obj={r}
											key={r.name + i}
											deleteQuery={this.deleteQuery.bind(this, i)}
										/>,
									)}
								</FormItem>
							))}
						</div>
						<div style={{ textAlign: 'left', paddingTop: '15px' }}>
							<ButtonDiy type="primary" name="新增排序条件" />
							<Select
								style={{ width: 200, paddingRight: '10px' }}
								value={currentOrderKey}
								onChange={this.selectOrder}>
								{os.map((r) => {
									for (let j = 0; j < orders.length; j++) {
										if (orders[j].field === r.field) return;
									}
									return (
										<Option key={r.field} value={r.field}>
											{r.name}
										</Option>
									);
								})}
							</Select>
							{currentOrderKey ? (
								<span style={{ paddingLeft: '0' }}>
									<ButtonDiy type="primary" name="确定" handleClick={this.okOrder} />
								</span>
							) : (
								''
							)}
							<div style={{ height: '12px' }} />
							{orders.map((r, i) => (
								<FormItem
									key={r.name + i}
									labelCol={{ span: 4 }}
									wrapperCol={{ span: 20 }}
									colon={false}
									label={'按' + r.name}>
									{form.getFieldDecorator(i + 'o__' + r.field, {
										initialValue: { stringX: 'desc' },
									})(<OrderItem deleteOrder={this.deleteOrder.bind(this, i)} />)}
								</FormItem>
							))}
						</div>
						{this.props.voClass ? (
							<div style={{ textAlign: 'left', paddingTop: '15px' }}>
								<span style={{ paddingRight: '10px' }}>聚合条件:</span>
								{!groupVisiable ? (
									<ButtonDiy type="primary" name="新增" handleClick={this.addGroup} />
								) : (
									<span>
										<Select
											style={{ width: 100 }}
											value={currentGroupKey}
											onChange={this.selectGroup}>
											{gs.map((r) => {
												for (var j = 0; j < groups.length; j++) {
													if (groups[j].field == r.field) return;
												}
												return (
													<Option key={r.field} value={r.field}>
														{r.name}
													</Option>
												);
											})}
										</Select>
										{currentGroupKey ? (
											<ButtonDiy type="primary" name="确定" handleClick={this.okGroup} />
										) : (
											''
										)}
										<ButtonDiy type="primary" name="取消" handleClick={this.cancelGroup} />
									</span>
								)}
								{groups.map((r, i) => (
									<FormItem
										key={i + r.name}
										labelCol={{ span: 5 }}
										wrapperCol={{ span: 15 }}
										label={'按' + r.name + '聚合'}>
										{form.getFieldDecorator(i + 'g__' + r.field)(
											<Input style={{ display: 'none' }} value="" />,
										)}
										<ButtonDiy
                      type="danger"
											name="删除"
											handleClick={this.deleteGroup.bind(this, i)}
										/>
									</FormItem>
								))}
							</div>
						) : (
							''
						)}
						<Row>
							<Col span={24} style={{ textAlign: 'left', paddingTop: '15px' }}>
								<span style={{ paddingRight: '10px' }}>导出项:</span>
								{/*<Select>*/}
								{/*{*/}

								{/*}*/}
								{/*</Select>*/}
							</Col>
							<Col span={18}>
								<Transfer
									key={keyX}
									style={{ textAlign: 'left' }}
									dataSource={mockData}
									listStyle={{
										width: 200,
										height: 300,
									}}
									onSelectChange={this.onSelectChange}
									selectedKeys={[...sourceSelectedKeys, ...targetSelectedKeys]}
									rowKey={(record) => record.key}
									targetKeys={targetKeys}
									onChange={this.handleChange}
									render={this.renderItem}
								/>
							</Col>
							<Col span={2}>
								<div style={{ marginTop: 100 }}>
									<Button
										size="small"
										disabled={targetSelectedKeys.length === 0}
										onClick={this.top}>
										批量置顶
									</Button>
									<Button
										size="small"
										style={{ marginTop: 10 }}
										disabled={targetSelectedKeys.length !== 1}
										onClick={this.up}>
										单项上移
									</Button>
									<Button
										size="small"
										style={{ marginTop: 10 }}
										disabled={targetSelectedKeys.length !== 1}
										onClick={this.down}>
										单项下移
									</Button>
									<Button
										size="small"
										style={{ marginTop: 10 }}
										disabled={targetSelectedKeys.length === 0}
										onClick={this.bottom}>
										批量置底
									</Button>
								</div>
							</Col>
						</Row>
					</div>
				</Modal>
			</span>
		);
	}
}
