import React from 'react';
import { Spin } from 'antd';
import isEqual from 'lodash/isEqual';
import { isComponentClass } from './Secured'; // eslint-disable-next-line import/no-cycle

export default class PromiseRender extends React.Component {
	state = {
		component: () => null,
	};

	componentDidMount() {
		this.setRenderComponent(this.props);
	}

	shouldComponentUpdate = (nextProps, nextState) => {
		const { component } = this.state;

		if (!isEqual(nextProps, this.props)) {
			this.setRenderComponent(nextProps);
		}

		if (nextState.component !== component) return true;
		return false;
	}; // set render Component : ok or error

	setRenderComponent(props) {
		const ok = this.checkIsInstantiation(props.ok);
		const error = this.checkIsInstantiation(props.error);
		props.promise
			.then(() => {
				this.setState({
					component: ok,
				});
				return true;
			})
			.catch(() => {
				this.setState({
					component: error,
				});
			});
	} // Determine whether the incoming component has been instantiated
	// AuthorizedRoute is already instantiated
	// Authorized  render is already instantiated, children is no instantiated
	// Secured is not instantiated

	checkIsInstantiation = (target) => {
		if (isComponentClass(target)) {
			const Target = target;
			return (props) => <Target {...props} />;
		}

		if (React.isValidElement(target)) {
			return (props) => React.cloneElement(target, props);
		}

		return () => target;
	};

	render() {
		const { component: Component } = this.state;
		const { ok, error, promise, ...rest } = this.props;
		return Component ? (
			<Component {...rest} />
		) : (
			<div
				style={{
					width: '100%',
					height: '100%',
					margin: 'auto',
					paddingTop: 50,
					textAlign: 'center',
				}}>
				<Spin size="large" />
			</div>
		);
	}
}
