import React from 'react';
import { Select, Modal, Table, Row, Col, Tag, 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 styles from '../Ability.css';
import FormdataWrapper from '../../utils/object-to-formdata-custom';
import ButtonDiy from '../ButtonDiy/ButtonDiy';
import { nameSpan, nameSpan3, nameSpan2 } from './config';
const Option = Select.Option;

const FormItem = Form.Item;
@connect(({ cms, loading }) => ({
	cms,
	loading: loading.models.cms,
}))
@Form.create()
export default class StatisticsInfo extends React.Component {
	constructor(props) {
		super(props);
		this.state = {
			exportLoading: false,
			visiable: false,
			queryVisiable: false,
			groupVisiable: false,
			sortVisiable: false,
			currentQueryKey: null,
			currentGroupKey: null,
			orderVisiable: false,
			currentOrderKey: null,
			querys: [],
			orders: [],
			groups: [],
			gs: [],
			os: [],
			qs: [],
			x: null,
			y: null,
			z: null,
			currentKey: null,
			XxX: null,
			mockData: [],
			mockXZData: [],
			targetKeys: [],
			sourceSelectedKeys: [],
			targetSelectedKeys: [],
			infos: {},
			columns: [],
			dataSource: [],
			flag: 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: [...groups],
			},
			() => {
				this.finish();
			},
		);
	};
	open = () => {
		const { dispatch } = this.props;
		dispatch({
			type: 'DataObj/getExportInfo',
			payload: {
				objId: this.props.objId,
			},
			callback: (infos) => {
				const filterXZKeys = this.props.filterXZKeys;
				const mockData = [];
				const mockXZData = [];
				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,
						hql: x.hql,
					});
					if (filterXZKeys != null) {
						if (filterXZKeys.includes(key)) {
							mockXZData.push({
								key: x.field,
								title: x.name,
								chosen: false,
								hql: x.hql,
							});
						}
					} else {
						mockXZData.push({
							key: x.field,
							title: x.name,
							chosen: false,
							hql: x.hql,
						});
					}
					if (x.canQuery) {
						qs.push(x);
					}
					if (x.canGroup) {
						gs.push(x);
					}
					if (x.canOrder) {
						os.push(x);
					}
				}

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

	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;
		if (!this.state.currentGroupKey) {
			message.warning('请选择一个聚合条件');
			return false;
		}
		groups.push(this.state.infos[this.state.currentGroupKey]);
		this.setState(
			{
				groups,
				groupVisiable: false,
				currentGroupKey: null,
			},
			() => {
				this.finish();
			},
		);
	};

	addQuery = () => {
		this.setState({ queryVisiable: true });
	};
	okQuery = () => {
		if (!this.state.currentQueryKey) {
			message.warning('请选择一个查询条件');
			return false;
		}
		const querys = this.state.querys;
		querys.push(this.state.infos[this.state.currentQueryKey]);
		this.setState({ querys, queryVisiable: false, currentQueryKey: null });
	};
	finish = () => {
		const { dispatch, objId } = this.props;
		const { x, y, z, infos, XxX, currentKey, groups } = this.state;

		if (x == null) {
			message.warning('请选择第一统计项');
			return;
		}
		if (y == null) {
			message.warning('请选择行数据');
			return;
		}
		this.props.form.validateFields((err, fieldsValue) => {
			if (err) return;
			const qqs = this.props.mustQuerys || [];
			const ggs = [];
			for (var key in fieldsValue) {
				var xx = key.indexOf('__');
				let kk = key.substr(xx + 2);
				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,
				});
			}

			if (groups.length === 0) {
				message.warning('请至少选择一个聚合条件');
				return;
			}

			for (var i = 0; i < groups.length; i++) {
				ggs.push({ hql: groups[i].hql });
			}
			const tx = infos[x];
			const ty = infos[y];
			var ttx;
			var tty;
			var ttz;
			if (tx.notes) {
				if (tx.notes.indexOf('com.') == -1) {
					ttx = infos[x].hql.replace('.id', '.dictName');
				} else {
					ttx = infos[x].hql;
				}
			} else {
				ttx = infos[x].hql;
			}
			if (ty.notes) {
				if (ty.notes.indexOf('com.') == -1) {
					tty = infos[y].hql.replace('.id', '.dictName');
				} else {
					tty = infos[y].hql;
				}
			} else {
				tty = infos[y].hql;
			}
			if (z != null) {
				const tz = infos[z];
				if (tz && tz.notes) {
					if (tz.notes.indexOf('com.') == -1) {
						ttz = infos[z].hql.replace('.id', '.dictName');
					} else {
						ttz = infos[z].hql;
					}
				} else {
					ttz = infos[z].hql;
				}
			}
			dispatch({
				type: 'DataObj/getStatistics',
				payload: {
					x: ttx,
					y: tty,
					z: ttz,
					objId,
					xXx: XxX,
					hql: currentKey && infos[currentKey] ? infos[currentKey].hql : null,
					querys: JSON.stringify(qqs),
					groups: JSON.stringify(ggs),
				},
				callback: (data) => {
					this.setState({ dataSource: data.dataSource, columns: data.columns });
				},
			});
		});
	};

	downloadFile(url, params) {
		this.setState({ exportLoading: true });
		fetch(url, {
			method: 'POST',
			body: FormdataWrapper(params),
		})
			.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({ exportLoading: false });
			});
	}

	export = () => {
		const { dispatch, objId } = this.props;
		const { x, y, z, infos, XxX, currentKey, groups } = this.state;

		if (x == null) {
			message.warning('请选择第一统计项');
			return;
		}
		if (y == null) {
			message.warning('请选择行数据');
			return;
		}
		this.props.form.validateFields((err, fieldsValue) => {
			if (err) return;
			const qqs = this.props.mustQuerys || [];
			const ggs = [];
			for (var key in fieldsValue) {
				var xx = key.indexOf('__');

				let kk = key.substr(xx + 2);

				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,
				});
			}

			if (groups.length === 0) {
				message.warning('请至少选择一个聚合条件');
				return;
			}

			for (var i = 0; i < groups.length; i++) {
				ggs.push({ hql: groups[i].hql });
			}
			const tx = infos[x];
			const ty = infos[y];

			var ttx;
			var tty;
			var ttz;
			if (tx.notes) {
				if (tx.notes.indexOf('com.') == -1) {
					ttx = infos[x].hql.replace('.id', '.dictName');
				} else {
					ttx = infos[x].hql;
				}
			} else {
				ttx = infos[x].hql;
			}
			if (ty.notes) {
				if (ty.notes.indexOf('com.') == -1) {
					tty = infos[y].hql.replace('.id', '.dictName');
				} else {
					tty = infos[y].hql;
				}
			} else {
				tty = infos[y].hql;
			}
			if (z != null) {
				const tz = infos[z];
				if (tz && tz.notes) {
					if (tz.notes.indexOf('com.') == -1) {
						ttz = infos[z].hql.replace('.id', '.dictName');
					} else {
						ttz = infos[z].hql;
					}
				} else {
					ttz = infos[z].hql;
				}
			}
			const param = {
				x: ttx,
				y: tty,
				z: ttz,
				objId,
				xXx: XxX,
				hql: currentKey && infos[currentKey] ? infos[currentKey].hql : null,
				querys: JSON.stringify(qqs),
				groups: JSON.stringify(ggs),
			};
			let downloadUrl = config.httpServer + '/DataObjApi/exportStatistics?';
			const token = getToken() != null && getToken() != 'null' ? getToken() : '0000';
			downloadUrl = `${downloadUrl}token=${token}`;
			this.downloadFile(downloadUrl, param);
		});
	};
	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, flag: !this.state.flag });
	};
	selectGroup = (e) => {
		this.setState({ currentGroupKey: e, flag: !this.state.flag });
	};

	changeX = (x) => {
		this.setState(
			{
				x,
				flag: !this.state.flag,
			},
			() => {
				this.finish();
			},
		);
	};
	changeY = (y) => {
		this.setState(
			{
				y,
				flag: !this.state.flag,
			},
			() => {
				this.finish();
			},
		);
	};
	changeZ = (z) => {
		this.setState({ z, flag: !this.state.flag });
	};
	cancelZ = () => {
		this.setState({ z: null, flag: !this.state.flag });
	};
	selectXxX = (XxX) => {
		this.setState({ XxX, flag: !this.state.flag });
	};
	selectCurrentKey = (currentKey) => {
		this.setState({ currentKey, XxX: null, flag: !this.state.flag });
	};
	cancelCurrentKey = () => {
		this.setState({ currentKey: null, XxX: null, flag: !this.state.flag });
	};

	componentDidMount() {
		// this.open();
	}

	pageConfig = (item = 0) => {
		const {
			querys,
			groups,
			currentKey,
			XxX,
			infos,
			mockData,
			mockXZData,
			qs,
			gs,
			x,
			y,
			z,
			currentQueryKey,
			currentGroupKey,
		} = this.state;
		let xxxs = [];
		if (currentKey != null) {
			if (
				infos[currentKey].type == 'java.lang.Integer' ||
				infos[currentKey].type == 'java.lang.Double' ||
				infos[currentKey].type == 'java.lang.Long'
			) {
				xxxs = [
					{ label: '数量', value: 'count' },
					{ label: '最大值', value: 'max' },
					{
						label: '最小值',
						value: 'min',
					},
					{ label: '平均值', value: 'avg' },
					{ label: '求和', value: 'sum' },
				];
			} else {
				xxxs = [{ label: '数量', value: 'count' }];
			}
		}

		let optionQs = [];

		for (let item of qs) {
			let add = true;
			for (let i = 0; i < querys.length; i++) {
				if (querys[i].field === item.field) {
					add = false;
					break;
				}
			}
			if (add) {
				optionQs.push(item);
			}
		}

		let optionGs = [];
		for (let item of gs) {
			let add = true;
			for (let i = 0; i < groups.length; i++) {
				if (groups[i].field === item.field) {
					add = false;
					break;
				}
			}
			if (add) {
				optionGs.push(item);
			}
		}

		const config = [
			{
				required: true,
				selectConfig: [
					{
						name: '第一统计项',
						value: x,
						onChange: this.changeX,
						options: mockXZData,
						optionKey: 'key',
						optionName: 'title',
					},
				],
			},
			{
				required: false,
				selectConfig: [
					{
						name: '第二统计项',
						value: z,
						onChange: this.changeZ,
						options: mockXZData,
						optionKey: 'key',
						optionName: 'title',
					},
				],
				buttonConfig: [
					{
						name: '取消',
						handleClick: this.cancelZ,
						className: 'defaultRed',
						key: 'cancel',
					},
				],
			},
			{
				required: true,
				selectConfig: [
					{
						name: '行数据',
						value: y,
						onChange: this.changeY,
						options: mockData,
						optionKey: 'key',
						optionName: 'title',
					},
				],
			},
			{
				required: false,
				selectConfig: [
					{
						name: '统计指标',
						value: currentKey,
						onChange: this.selectCurrentKey,
						options: mockData,
						optionKey: 'key',
						optionName: 'title',
					},
					{
						name: '',
						value: XxX,
						onChange: this.selectXxX,
						options: xxxs,
						optionKey: 'value',
						optionName: 'label',
					},
				],
				buttonConfig: [
					{
						name: '取消',
						handleClick: this.cancelCurrentKey,
						className: 'defaultRed',
						key: 'cancel',
					},
				],
			},
			{
				required: false,
				selectConfig: [
					{
						name: '查询条件',
						value: currentQueryKey,
						onChange: this.selectQuery,
						options: optionQs,
						optionKey: 'field',
						optionName: 'name',
					},
				],
				buttonConfig: [
					{
						name: '确定',
						handleClick: this.okQuery,
						className: 'defaultBlue',
						key: 'confirm',
					},
					{
						name: '取消',
						handleClick: this.cancelQuery,
						className: 'defaultRed',
						key: 'cancel',
					},
				],
			},
			{
				required: false,
				selectConfig: [
					{
						name: '聚合条件',
						value: currentGroupKey,
						onChange: this.selectGroup,
						options: optionGs,
						optionKey: 'field',
						optionName: 'name',
					},
				],
				buttonConfig: [
					{
						name: '确定',
						handleClick: this.okGroup,
						className: 'defaultBlue',
						key: 'confirm',
					},
					{
						name: '取消',
						handleClick: this.cancelGroup,
						className: 'defaultRed',
						key: 'cancel',
					},
				],
			},
		];
		return config[item];
	};

	selectDom = (item) => {
		const config = this.pageConfig(item);

		return (
			<Row>
				{config.selectConfig.map((selectConfigItem, dataIndex) => {
					const nameSpanThis = dataIndex > 0 ? nameSpan2 : nameSpan;
					return (
						<Col span={4} style={{ paddingLeft: '15px' }} key={dataIndex}>
							<FormItem
								label={selectConfigItem.name}
								required={config.required || false}
								colon={false}
								labelCol={{
									xl: nameSpanThis.small,
									xxl: nameSpanThis.big,
								}}
								wrapperCol={{
									xl: 24 - nameSpanThis.small,
									xxl: 24 - nameSpanThis.big,
								}}>
								<Select
									style={{ width: '100%' }}
									onChange={selectConfigItem.onChange}
									value={selectConfigItem.value}>
									{selectConfigItem.options.map((r) => {
										return (
											<Option
												key={r[selectConfigItem.optionKey]}
												value={r[selectConfigItem.optionKey]}>
												{r[selectConfigItem.optionName]}
											</Option>
										);
									})}
								</Select>
							</FormItem>
						</Col>
					);
				})}
				{typeof config.buttonConfig !== 'undefined' && config.buttonConfig.length
					? config.buttonConfig.map((buttonDs) => {
							return (
								<Col span={1} key={buttonDs.key} style={{ paddingLeft: '15px' }}>
									<FormItem
										colon={false}
										labelCol={{
											xl: nameSpan.small,
											xxl: nameSpan.big,
										}}
										wrapperCol={{
											xl: 24 - nameSpan.small,
											xxl: 24 - nameSpan.big,
										}}>
										<ButtonDiy
											name={buttonDs.name}
											type="default"
											className={buttonDs.className}
											handleClick={buttonDs.handleClick}
										/>
									</FormItem>
								</Col>
							);
					  })
					: null}
			</Row>
		);
	};

	render() {
		const { form, loading } = this.props;

		const {
			visiable,
			querys,
			groups,
			exportLoading,
			infos,
			columns,
			dataSource,
			x,
			y,
			z,
		} = this.state;
		const loadingxxx = loading || exportLoading;
		let columnsTemp = columns;
		if (columnsTemp.length > 0) {
			if (z == null) {
				columnsTemp[0].title = (
					<div className={styles.out2} style={{ fontSize: 14 }}>
						<span className={styles.title1}>{infos[x] ? infos[x].name : ''}</span>{' '}
						<span className={styles.title3}>{infos[y] ? infos[y].name : ''}</span>
					</div>
				);
				columnsTemp[0].width = 200;
			} else {
				columnsTemp[0].title = (
					<div className={styles.out} style={{ fontSize: 14 }}>
						<span className={styles.title1}>{infos[x] ? infos[x].name : ''}</span>{' '}
						<span className={styles.title2}>{infos[z] ? infos[z].name : ''}</span>{' '}
						<span className={styles.title3}>{infos[y] ? infos[y].name : ''}</span>
					</div>
				);
				columnsTemp[0].width = 200;
			}
		}

		return (
			<span>
				{/* 暂时屏蔽 */}
				<ButtonDiy
					name="自定义统计"
					type="default"
					className="defaultBlue"
					handleClick={this.open}
				/>
				<div id="downloadDiv" style={{ display: 'none' }} />
				<Modal
					width={'95%'}
					maskClosable={false}
					destroyOnClose
					title="自定义统计"
					visible={visiable}
					footer={null}
					onCancel={this.onCancle}>
					{this.selectDom(0)} {/*第一统计项*/}
					{this.selectDom(1)} {/*第二统计项*/}
					{this.selectDom(2)} {/*行数据*/}
					{this.selectDom(3)} {/*统计指标*/}
					{this.selectDom(4)} {/*查询条件*/}
					<div
						style={{
							textAlign: 'left',
							paddingLeft: '25px',
						}}>
						{querys.map((r, i) => (
							<FormItem
								key={i}
								labelCol={{
									xl: nameSpan3.small,
									xxl: nameSpan3.big,
								}}
								wrapperCol={{
									xl: 24 - nameSpan3.small,
									xxl: 24 - nameSpan3.big,
								}}
								label={r.name}>
								{form.getFieldDecorator(i + 'q__', {
									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} deleteQuery={this.deleteQuery.bind(this, i)} />)}
							</FormItem>
						))}
					</div>
					{this.selectDom(5)} {/*聚合条件*/}
					<Row
						style={{
							textAlign: 'left',
							paddingLeft: '80px',
							paddingTop: '8px',
						}}>
						{groups.map((r, i) => (
							<Tag closable={true} key={i + r.field} onClose={this.deleteGroup.bind(this, i)}>
								{'按' + r.name + '聚合'}
							</Tag>
						))}
					</Row>
					<Row style={{ paddingTop: '20px' }}>
						<Col span={24} style={{ textAlign: 'left' }}>
							<ButtonDiy handleClick={this.finish} name={'查询'} loading={loadingxxx} />
							<ButtonDiy handleClick={this.export} name={'导出'} loading={loadingxxx} />
						</Col>
						<Col
							span={24}
							style={{
								overFlow: 'auto',
								minHeight: '500px',
							}}>
							<Table
								size="small"
								bordered
								dataSource={dataSource}
								rowKey={'col0'}
								columns={columnsTemp}
								scroll={{ x: 'max-content' }}
								pagination={false}
							/>
						</Col>
					</Row>
				</Modal>
			</span>
		);
	}
}