import React from 'react';
import styles from './DraftEditor.less';
import { Modal, Form, Input, Button, message, Upload, Icon } from 'antd';
import b from '../assets/专家经验系统切图/智能报告/B.png';
import ii from '../assets/专家经验系统切图/智能报告/_.png';
import it from '../assets/专家经验系统切图/智能报告/I.png';
import h from '../assets/专家经验系统切图/智能报告/H.png';
import blockQu from '../assets/专家经验系统切图/智能报告/blockQu.png';
import code from '../assets/专家经验系统切图/智能报告/___.png';
import prjectNum from '../assets/专家经验系统切图/智能报告/prjectNum.png';
import num from '../assets/专家经验系统切图/智能报告/num.png';
import t from '../assets/专家经验系统切图/智能报告/T.png';
import lk from '../assets/专家经验系统切图/智能报告/lk.png';
import pic from '../assets/专家经验系统切图/智能报告/pic.png';
import video from '../assets/专家经验系统切图/智能报告/video.png';
import sum from '../assets/专家经验系统切图/智能报告/sum.png';
import attrs from '../assets/专家经验系统切图/智能报告/attr.png';
import config from '@/webPublic/one_stop_public/config';
import MyBlockRender from './MyBlockRender';
import { changeToDraftState2, changeFromDraftState2 } from '../utils/myutils';
import {
	Editor,
	EditorState,
	AtomicBlockUtils,
	convertFromRaw,
	convertToRaw,
	CompositeDecorator,
	RichUtils,
} from 'draft-js';
import { getToken } from '@/webPublic/one_stop_public/utils/token';
import { queryFileUrl } from '@/webPublic/one_stop_public/utils/queryConfig';
import { getSysCode } from '@/webPublic/one_stop_public/2023yunshangguizhou/utils';
const FormItem = Form.Item;

function getBlockStyle(block) {
	switch (block.getType()) {
		case 'blockquote':
			return 'RichEditor-blockquote';
		default:
			return null;
	}
}

const StyleControls = (props) => {
	const { editorState } = props;
	const selection = editorState.getSelection();
	const blockType = editorState
		.getCurrentContent()
		.getBlockForKey(selection.getStartKey())
		.getType();
	var currentStyle = props.editorState.getCurrentInlineStyle();

	return (
		<div
			style={{
				borderBottom: '1px solid gray',
				borderTop: '1px solid gray',
				height: 50,
				paddingTop: 10,
			}}>
			{props.btns.map((fn) => (
				<StyleButton
					key={fn.label}
					active={fn.type == 'block' ? fn.style === blockType : currentStyle.has(fn.style)}
					label={fn}
					onToggle={fn.type == 'block' ? props.toggleBlockType : props.toggleInlineStyle}
					style={fn.style}
				/>
			))}
		</div>
	);
};

export default class DraftEditor extends React.Component {
	constructor(props) {
		super(props);
		const value = props.value || {};
		this.state = {
			editorState: value.editorState,
			modalVisible: false,
			fnKey: '',
			styleMap: {
				RED: {
					color: 'red',
				},
			},
		};

		this.setEditor = (editor) => {
			this.editor = editor;
		};
		this.onChange = (editorState, callback) => {
			if (!('value' in this.props)) {
				this.setState({ editorState }, () => {
					if (callback) callback();
				});
			}
			this.triggerChange({ editorState }, () => {
				if (callback) callback();
			});
		};

		this.focusEditor = () => {
			if (this.editor) {
				this.editor.focus();
			}
		};
		this.triggerChange = (changedValue, callback) => {
			// Should provide an event to pass value to Form.
			const onChange = this.props.onChange;
			if (onChange) {
				onChange(Object.assign({}, this.state, changedValue));
			}
			if (callback) callback();
		};
	}
	exchange = (data, editKey, callback) => {
		const blocks = changeFromDraftState2(this.state.editorState);

		const bs = blocks.blocks;

		var b;
		for (var i = 0; i < bs.length; i++) {
			if (bs[i].key == editKey) {
				b = bs[i];
				break;
			}
		}
		const entityKey = b.entityRanges[0].key + '';

		blocks.entityMap[entityKey].data = data;
		const editorState = changeToDraftState2(blocks);
		this.onChange(editorState, callback);
	};
	extends = (data, type, text, callback) => {
		var editorState = this.state.editorState;

		const contentState = editorState.getCurrentContent();
		const contentStateWithEntity = contentState.createEntity(type, 'IMMUTABLE', data);
		const entityKey = contentStateWithEntity.getLastCreatedEntityKey();

		const newEditorState = EditorState.set(editorState, { currentContent: contentStateWithEntity });
		const xx = AtomicBlockUtils.insertAtomicBlock(newEditorState, entityKey, text);

		if (!('value' in this.props)) {
			this.setState({ editorState: xx }, () => {
				callback();
			});
		}
		this.triggerChange({ editorState: xx }, () => {
			callback();
		});
	};
	urlChange(event) {
		const target = event.target;
		this.setState({
			url: target.value,
		});
	}
	toggleBlockType = (blockType) => {
		this.onChange(RichUtils.toggleBlockType(this.state.editorState, blockType));
	};
	toggleInlineStyle = (inlineStyle) => {
		this.onChange(RichUtils.toggleInlineStyle(this.state.editorState, inlineStyle));
	};

	componentWillReceiveProps(nextProps) {
		// Should be a controlled component.
		if ('value' in nextProps) {
			const value = nextProps.value;
			this.setState(value);
		}
	}

	okHandle = () => {};
	insertAttr = () => {
		if (!('value' in this.props)) {
			this.setState({ modalVisible: true, fnKey: 'attr' });
		}
		this.triggerChange({ modalVisible: true, fnKey: 'attr' });
	};
	insertPic = () => {
		if (!('value' in this.props)) {
			this.setState({ modalVisible: true, fnKey: 'image' });
		}
		this.triggerChange({ modalVisible: true, fnKey: 'image' });
	};
	insertFormula = () => {
		if (!('value' in this.props)) {
			this.setState({ modalVisible: true, fnKey: 'formula' });
		}
		this.triggerChange({ modalVisible: true, fnKey: 'formula' });
	};
	insertVideo = () => {
		if (!('value' in this.props)) {
			this.setState({ modalVisible: true, fnKey: 'video' });
		}
		this.triggerChange({ modalVisible: true, fnKey: 'video' });
	};
	insertLink = () => {
		const x = this.state.editorState.getSelection().getStartOffset();
		const y = this.state.editorState.getSelection().getEndOffset();
		if (y - x == 0) {
			message.error('请选择需要插入链接的内容');
			return;
		}
		if (!('value' in this.props)) {
			this.setState({ modalVisible: true, fnKey: 'link' });
		}
		this.triggerChange({ modalVisible: true, fnKey: 'link' });
	};
	callback3 = (content) => {
		const { editorState } = this.state;

		const contentState = editorState.getCurrentContent();
		const contentStateWithEntity = contentState.createEntity('video', 'IMMUTABLE', content);
		const entityKey = contentStateWithEntity.getLastCreatedEntityKey();
		const newEditorState = EditorState.set(editorState, { currentContent: contentStateWithEntity });
		const xx = AtomicBlockUtils.insertAtomicBlock(newEditorState, entityKey, '[视频]');

		if (!('value' in this.props)) {
			this.setState({ editorState: xx, modalVisible: false });
		}
		this.triggerChange({ editorState: xx, modalVisible: false });
	};
	callback4 = (content) => {
		const { editorState } = this.state;

		const contentState = editorState.getCurrentContent();
		const contentStateWithEntity = contentState.createEntity('attr', 'IMMUTABLE', content);
		const entityKey = contentStateWithEntity.getLastCreatedEntityKey();
		const newEditorState = EditorState.set(editorState, { currentContent: contentStateWithEntity });
		const xx = AtomicBlockUtils.insertAtomicBlock(newEditorState, entityKey, '[附件]');

		if (!('value' in this.props)) {
			this.setState({ editorState: xx, modalVisible: false });
		}
		this.triggerChange({ editorState: xx, modalVisible: false });
	};
	callback2 = (content) => {
		const { editorState } = this.state;

		const contentState = editorState.getCurrentContent();
		const contentStateWithEntity = contentState.createEntity('image', 'IMMUTABLE', content);
		const entityKey = contentStateWithEntity.getLastCreatedEntityKey();
		const newEditorState = EditorState.set(editorState, { currentContent: contentStateWithEntity });
		const xx = AtomicBlockUtils.insertAtomicBlock(newEditorState, entityKey, '[图片]');

		if (!('value' in this.props)) {
			this.setState({ editorState: xx, modalVisible: false });
		}
		this.triggerChange({ editorState: xx, modalVisible: false });
	};
	callback = (content) => {
		const { editorState } = this.state;

		// 获取contentState
		const contentState = editorState.getCurrentContent();
		// 在contentState上新建entity
		const contentStateWithEntity = contentState.createEntity(
			'LINK',
			// 'MUTABLE',
			// 'IMMUTABLE',
			'SEGMENTED',
			{ url: content.url },
		);
		// 获取到刚才新建的entity
		const entityKey = contentStateWithEntity.getLastCreatedEntityKey();
		// 把带有entity的contentState设置到editorState上
		const newEditorState = EditorState.set(editorState, { currentContent: contentStateWithEntity });
		// 把entity和选中的内容对应
		const xx = RichUtils.toggleLink(newEditorState, newEditorState.getSelection(), entityKey);

		if (!('value' in this.props)) {
			this.setState({ editorState: xx, modalVisible: false });
		}
		this.triggerChange({ editorState: xx, modalVisible: false });
	};
	modelContent = () => {
		if (this.state.fnKey == 'link') {
			return <LinkForm callback={this.callback} />;
		} else if (this.state.fnKey == 'image') {
			return <PicForm callback={this.callback2} />;
		} else if (this.state.fnKey == 'video') {
			return <VideoForm callback={this.callback3} />;
		} else if (this.state.fnKey == 'formula') {
			return <FormulaForm callback={this.callback2} />;
		} else if (this.state.fnKey == 'attr') {
			return <AttrForm callback={this.callback4} />;
		}
	};
	deleteBlock = (editKey) => {
		const oldObj = changeFromDraftState2(this.state.editorState);

		const blocks = JSON.parse(JSON.stringify(oldObj));
		const bs = blocks.blocks;

		var b;
		var j;
		for (var i = 0; i < bs.length; i++) {
			if (bs[i].key == editKey) {
				b = bs[i];
				j = i;
				break;
			}
		}
		const entityKey = b.entityRanges[0].key + '';
		delete blocks.entityMap[entityKey];
		blocks.blocks.splice(j, 1);

		const editorState = changeToDraftState2(blocks);
		if (!('value' in this.props)) {
			this.setState({ editorState });
		}
		this.triggerChange({ editorState });
	};
	render() {
		const btns = [
			{ label: 'Bold', style: 'BOLD', type: 'inline', icon: b },
			{ label: 'Italic', style: 'ITALIC', type: 'inline', icon: it },

			{ label: 'line1', type: 'line', icon: ii },
			{ label: 'H1', style: 'header-one', type: 'block', icon: h },
			/*  {label: 'H2', style: 'header-two',type:"block",icon:b},
       {label: 'H3', style: 'header-three',type:"block",icon:b},
       {label: 'H4', style: 'header-four',type:"block",icon:b},
       {label: 'H5', style: 'header-five',type:"block",icon:b},
       {label: 'H6', style: 'header-six',type:"block",icon:b}, */
			{ label: 'Blockquote', style: 'blockquote', type: 'block', icon: blockQu },
			{ label: 'Code Block', style: 'code-block', type: 'block', icon: code },
			{ label: 'UL', style: 'unordered-list-item', type: 'block', icon: prjectNum },
			{ label: 'OL', style: 'ordered-list-item', type: 'block', icon: num },
			{ label: 'line2', type: 'line', icon: ii },
			{ label: 'lk', type: 'fn', icon: lk, fn: this.insertLink },
			{ label: 'pic', type: 'fn', icon: pic, fn: this.insertPic },
			{ label: 'video', type: 'fn', icon: video, fn: this.insertVideo },
			/*   { label: 'sum', type: "fn", icon: sum, fn: this.insertFormula }, */
			{ label: 'att', type: 'fn', icon: attrs, fn: this.insertAttr },
			{ label: 'line3', type: 'line', icon: ii },
			{ label: 'Del', style: 'STRIKETHROUGH', type: 'inline', icon: t },
		];
		const { modalVisible } = this.state;

		return (
			<div>
				<StyleControls
					btns={btns}
					editorState={this.state.editorState}
					toggleInlineStyle={this.toggleInlineStyle}
					toggleBlockType={this.toggleBlockType}
				/>
				<div
					className={styles.basic}
					style={{
						height: '400px',

						overflowY: 'auto',
					}}
					onClick={this.focusEditor}>
					<Editor
						ref={this.setEditor}
						blockStyleFn={getBlockStyle}
						customStyleMap={this.state.styleMap}
						blockRendererFn={MyBlockRender.bind(
							this,
							false,
							null,
							this.props.editBlock,
							this.deleteBlock,
						)}
						editorState={this.state.editorState}
						placeholder={this.props.placeholder || '请输入'}
						onChange={this.onChange}
					/>
				</div>
				<Modal
					width="700px"
					maskClosable={false}
					destroyOnClose
					title={'插入对象'}
					visible={modalVisible}
					footer={null}
					onCancel={() => this.setState({ modalVisible: false })}>
					{this.modelContent()}
				</Modal>
			</div>
		);
	}
}
class StyleButton extends React.Component {
	constructor() {
		super();
		this.onToggle = (e) => {
			e.preventDefault();
			this.props.onToggle(this.props.style);
		};
	}
	render() {
		const { label } = this.props;
		return (
			<a
				key={label.label}
				onMouseDown={this.onToggle}
				onClick={label.fn}
				style={{ marginLeft: 20 }}>
				<img src={label.icon} />
			</a>
		);
	}
}

@Form.create()
class LinkForm extends React.Component {
	constructor(props) {
		super(props);
	}
	submit = (e) => {
		e.preventDefault();

		const { form } = this.props;

		form.validateFields((err, fieldsValue) => {
			if (err) return;

			this.props.callback(fieldsValue);
		});
	};
	render() {
		const { form } = this.props;
		return (
			<Form onSubmit={this.submit}>
				<FormItem labelCol={{ span: 5 }} wrapperCol={{ span: 15 }} label="链接地址">
					{form.getFieldDecorator('url', {
						rules: [{ required: true, message: '请输入链接名称' }],
					})(<Input placeholder="请输入链接名称" />)}
				</FormItem>

				<Button type="primary" htmlType="submit">
					确定
				</Button>
			</Form>
		);
	}
}
@Form.create()
class AttrForm extends React.Component {
	constructor(props) {
		super(props);
		this.state = {
			url: null,
			name: null,
		};
	}
	submit = (e) => {
		e.preventDefault();

		const { form } = this.props;

		form.validateFields((err, fieldsValue) => {
			if (err) return;
			var src = fieldsValue.src;

			src = src[src.length - 1].response;
			const params = {
				...fieldsValue,
				src,
				name: this.state.name,
			};

			this.props.callback(params);
		});
	};
	normFile = (e) => {
		if (Array.isArray(e)) {
			return e;
		}
		return e && e.fileList;
	};

	onChange = (info) => {
		if (info.file.status === 'done') {
			message.success(`文件上传成功`);
			this.setState({ url: info.file.response, name: info.file.name });
		} else if (info.file.status === 'error') {
			message.error(`文件上传失败`);
		}
	};
	render() {
		const { form } = this.props;
		const { url, name } = this.state;
		return (
			<Form onSubmit={this.submit}>
				<FormItem labelCol={{ span: 5 }} wrapperCol={{ span: 15 }} label="上传附件">
					{form.getFieldDecorator('src', {
						valuePropName: 'fileList',
						getValueFromEvent: this.normFile,
					})(
						<Upload.Dragger
							onChange={this.onChange}
							showUploadList={false}
							name="file"
							action={config.uploadUrl}
              headers={{
                Authorization: `bearer ${getToken()}`,
                sysCode: getSysCode(),
              }}
              data={{
                token: getToken(),
              }}
							onChangemultiple={false}
							style={{ padding: 0 }}>
							{url ? (
								<a href={queryFileUrl(url)} target="_blank">
									{name}
								</a>
							) : (
								<p className="ant-upload-drag-icon" style={{ marginBottom: 0, height: 400 }}>
									<Icon type="video" />
								</p>
							)}
						</Upload.Dragger>,
					)}
				</FormItem>

				<Button type="primary" htmlType="submit">
					确定
				</Button>
			</Form>
		);
	}
}
@Form.create()
class VideoForm extends React.Component {
	constructor(props) {
		super(props);
		this.state = {
			url: null,
		};
	}
	submit = (e) => {
		e.preventDefault();

		const { form } = this.props;

		form.validateFields((err, fieldsValue) => {
			if (err) return;
			var src = fieldsValue.src;

			src = src[src.length - 1].response;
			const params = {
				...fieldsValue,
				src,
			};

			this.props.callback(params);
		});
	};
	normFile = (e) => {
		if (Array.isArray(e)) {
			return e;
		}
		return e && e.fileList;
	};
	beforeUpload = (file) => {
		const isJPG = file.type === 'video/mp4';
		if (!isJPG) {
			message.error('请上传mp4格式文件!');
		}

		return isJPG;
	};

	onChange = (info) => {
		if (info.file.status === 'done') {
			message.success(`视频上传成功`);
			this.setState({ url: info.file.response });
		} else if (info.file.status === 'error') {
			message.error(`视频上传失败`);
		}
	};
	render() {
		const { form } = this.props;
		const { url } = this.state;
		return (
			<Form onSubmit={this.submit}>
				<FormItem labelCol={{ span: 5 }} wrapperCol={{ span: 15 }} label="上传视频">
					{form.getFieldDecorator('src', {
						valuePropName: 'fileList',
						getValueFromEvent: this.normFile,
					})(
						<Upload.Dragger
							beforeUpload={this.beforeUpload}
							onChange={this.onChange}
							showUploadList={false}
							name="file"
							action={config.uploadUrl}
              headers={{
                Authorization: `bearer ${getToken()}`,
                sysCode: getSysCode(),
              }}
              data={{
                token: getToken(),
              }}
							onChangemultiple={false}
							style={{ padding: 0 }}>
							{url ? (
								<video src={queryFileUrl(url)} controls="controls">
									您的浏览器不支持 video 标签。
								</video>
							) : (
								<p className="ant-upload-drag-icon" style={{ marginBottom: 0, height: 400 }}>
									<Icon type="video" />
								</p>
							)}
						</Upload.Dragger>,
					)}
				</FormItem>

				<Button type="primary" htmlType="submit">
					确定
				</Button>
			</Form>
		);
	}
}
@Form.create()
class PicForm extends React.Component {
	constructor(props) {
		super(props);
		this.state = {
			url: null,
		};
	}
	beforeUpload = (file) => {
		const isJPG = file.type === 'image/jpeg' || file.type === 'image/png';
		if (!isJPG) {
			message.error('请上传jpg或者png格式文件!');
		}

		return isJPG;
	};
	submit = (e) => {
		e.preventDefault();

		const { form } = this.props;

		form.validateFields((err, fieldsValue) => {
			if (err) return;
			var src = fieldsValue.src;

			src = src[src.length - 1].response;
			const params = {
				...fieldsValue,
				src,
			};

			this.props.callback(params);
		});
	};
	normFile = (e) => {
		if (Array.isArray(e)) {
			return e;
		}
		return e && e.fileList;
	};
	onChange = (info) => {
		if (info.file.status === 'done') {
			message.success(`图片上传成功`);
			this.setState({ url: info.file.response });
		} else if (info.file.status === 'error') {
			message.error(`图片上传失败`);
		}
	};
	render() {
		const { form } = this.props;
		const { url } = this.state;
		return (
			<Form onSubmit={this.submit}>
				<FormItem labelCol={{ span: 5 }} wrapperCol={{ span: 15 }} label="上传图片">
					{form.getFieldDecorator('src', {
						valuePropName: 'fileList',
						getValueFromEvent: this.normFile,
					})(
						<Upload.Dragger
							beforeUpload={this.beforeUpload}
							showUploadList={false}
							name="file"
							action={config.uploadUrl}
							onChange={this.onChange}
              headers={{
                Authorization: `bearer ${getToken()}`,
                sysCode: getSysCode(),
              }}
              data={{
                token: getToken(),
              }}
							multiple={false}
							style={{ padding: 0 }}>
							{url ? (
								<img src={queryFileUrl(url)} style={{ height: 400, width: '100%' }} />
							) : (
								<p className="ant-upload-drag-icon" style={{ marginBottom: 0, height: 400 }}>
									<Icon type="video" />
								</p>
							)}
						</Upload.Dragger>,
					)}
				</FormItem>

				<Button type="primary" htmlType="submit">
					确定
				</Button>
			</Form>
		);
	}
}

@Form.create()
class FormulaForm extends React.Component {
	constructor(props) {
		super(props);
		window.latex = (gs) => {
			this.props.callback({ src: '/latex?code=' + encodeURI(gs), description: '' });
		};
	}

	render() {
		const { form } = this.props;
		return (
			<iframe
				src="/gongshi/gongshi.html"
				style={{ width: '100%', minHeight: '400px', border: 'solid 1px #0062d5' }}
			/>
		);
	}
}
