import React from "react";
import { connect } from "react-redux";
import moment from "moment";
import { SpinnerCircular } from "spinners-react";
import { concatSeries } from "async";
import { eachSeries } from 'async';
import Select from 'react-select';

import { createEDOProject, signCheckCreatePrintForm, signCheckPowerAttorneyClient, signDownloadFile, signGetGUIDEntity, signGetPowerAttorneyClient, signGetWMDoc, docEDOSign, docEDOStatus, docEDOConnect, getFile, signGetFileContractProject, signCheckCancelDocument, signCancelDocument } from "../../../actions";

class DealContractsSignEDO extends React.Component 
{
	constructor(props) 
	{
		super(props)
		this.state = {
			finished: false, 
			operators: null, 
			edo_message: null, 
			loading: false, 
			disabled: false, 
			documents: [], 
			operator_selected: {}, 
			statuses: {}, 
			step: 0, 
		}
	}

	static getDerivedStateFromProps(nextProps, prevState) 
	{
		return {
			operators: nextProps.operators, 
			edo_message: nextProps.edo_message, 
		}
	}

	componentDidMount()
	{
		const docs = [];
		for(let i in this.props.documents)
		{
			docs.push({ ...this.props.documents[i], ...{ index: i, loading: true, ready: false, attorney: false } });
		}
		this.setState({ documents: docs });

		if(this.state.operator_selected.box_id === undefined)
		{
			this.setState({ operator_selected: this.state.operators !== null && this.state.operators[0] !== undefined ? this.state.operators[0] : {} });
		}
	}

	_updateDocs = (id, update) => 
	{
		return new Promise((resolve) => 
		{
			const docs = [ ...this.state.documents ];
			docs[ id ] = { ...docs[id], ...update };

			this.setState({ documents: docs }, () => 
			{
				resolve();
			});
		});
	}

	_checkDocumentsCompleted = () => 
	{
		const { documents } = this.state;
		let completed = true;

		for(let i in documents)
		{
			if(!documents[i].error && !documents[i].completed)
			{
				completed = false;
				break;
			}
		}

		return completed;
	}

	_sign = () => 
	{
		const { operator_selected, step } = this.state;
		const documents = [ ...this.state.documents ];

		this.setState({ loading: true }, () => 
		{
			eachSeries(documents, async (document, callback) => 
			{
				if(document.completed)
				{
					callback();
				}
				else if(document.signing)
				{
					await this._updateDocs(document.index, { loading: true, });
					const status_result = await docEDOStatus({ contract_number: document.id });

					if(status_result.status === 3)
					{
						await this._updateDocs(document.index, { loading: false, signing: false, ready: false, completed: true, });
					}
					else
					{
						await this._updateDocs(document.index, { loading: false, signing: true, ready: false, });
					}

					callback();
				}
				else if(document.ready)
				{
					await this._updateDocs(document.index, { loading: true, });
					const status_result = await docEDOStatus({ contract_number: document.id });

					if(status_result.status > 0)
					{
						const sign_result = await docEDOSign({ edoid: status_result.edoid });
					}

					await this._updateDocs(document.index, { loading: false, signing: true, ready: false, error: false, });
					callback();
				}
				else
				{
					await this._updateDocs(document.index, { loading: true });

					if(document.attorney && document.attorney_selected !== undefined)
					{
						const create_edo_project_result = await createEDOProject({
							contract_number: document.id, 
							power_attorney: document.attorney_selected.value, 
							power_attorney_number: document.attorney_selected.label, 
							edo_box: operator_selected.edo_box, 
						});

						const get_guid_entity_result = await signGetGUIDEntity({
							contract_number: document.id, 
						});

						const wmdoc_result = await signGetWMDoc({ 
							entity_name: "evo_contract", 
							entity_id: get_guid_entity_result.entityid, 
							sign_type: "EDO", 
							evo_id: "144", 
							code: "Leas_Contract", 
						});

						const connect_result = await docEDOConnect({ contract_number: document.id });

						await this._updateDocs(document.index, {
							entity_id: get_guid_entity_result.entityid, 
							ready: true, 
							loading: false, 
							attorney: false, 
						});

						callback();
					}
					else
					{
						const create_print_form_result = await signCheckCreatePrintForm({ contract_number: document.id, sign_type: "EDO" });
						const docs = { status: create_print_form_result.status };

						if(create_print_form_result.status !== "success")
						{
							docs.loading = false;
							docs.error = true;
							docs.ready = true;
							docs.message = create_print_form_result.message;
						}

						await this._updateDocs(document.index, docs);

						if(create_print_form_result.status === "success")
						{
							const check_attorney_client_result = await signCheckPowerAttorneyClient({ contract_number: document.id })

							await this._updateDocs(document.index, { attorney: check_attorney_client_result.power_attorney_required, });

							if(check_attorney_client_result.power_attorney_required)
							{
								const get_attorney_client_result = await signGetPowerAttorneyClient({ contract_number: document.id });

								if(get_attorney_client_result === null)
								{
									await this._updateDocs(document.index, { loading: false, error: true, ready: true, message: "Возникла ошибка при создании документа для подписания." });
									callback();
								}
								else
								{
									if(get_attorney_client_result.length === null)
									{
										await this._updateDocs(document.index, { loading: false, error: true, ready: true, message: "Не обнаружена доверенность на подписанта. Для продолжения подписания обратитесь к своему персональному менеджеру" });
										callback();
									}
									else
									{
										const attorneys = [];
										for(let i in get_attorney_client_result)
										{
											attorneys.push({
												value: get_attorney_client_result[i].power_attorney, 
												label: get_attorney_client_result[i].power_attorney_number, 
											});
										}

										await this._updateDocs(document.index, { loading: false, error: false, attorneys, attorney_selected: undefined });

										callback();
									}
								}
							}
							else
							{
								const create_edo_project_result = await createEDOProject({
									contract_number: document.id, 
									edo_box: operator_selected.edo_box, 
								});

								const get_guid_entity_result = await signGetGUIDEntity({
									contract_number: document.id, 
								});

								const wmdoc_result = await signGetWMDoc({ 
									entity_name: "evo_contract", 
									entity_id: get_guid_entity_result.entityid, 
									sign_type: "EDO", 
									evo_id: "144", 
								});

								const connect_result = await docEDOConnect({ contract_number: document.id });

								await this._updateDocs(document.index, {
									entity_id: get_guid_entity_result.entityid, 
									ready: true, 
									loading: false, 
									attorney: false, 
								});

								callback();
							}
						}
						else
						{
							await this._updateDocs(document.index, { 
								loading: false, 
								error: true, 
								ready: true, 
								message: create_print_form_result.message !== undefined && create_print_form_result.message !== null ? create_print_form_result.message : "Возникла ошибка при создании документа для подписания.", 
							});
							callback();
						}
					}
				}
			}, () => 
			{
				if(this._checkDocumentsCompleted())
				{
					this.setState({ loading: false, disabled: false, finished: true, });
				}
				else
				{
					this.setState({ loading: false, disabled: false, finished: false, });
				}
			});
		});
	}

	_handle_onFormSubmit = (event) => 
	{
		event.preventDefault();

		const { onFinish, onGoToEDOInvites } = this.props;
		const { operators, operator_selected, step, finished } = this.state;

		if(operators !== null && operators.length === 0)
		{
			onGoToEDOInvites();
		}
		else
		{
			if(finished)
			{
				onFinish();
			}
			else
			{
				switch(step)
				{
					case 0:
					{
						this.setState({ step: 1 }, () => 
						{
							this._sign();
						});
					}
					break;

					case 1:
					{
						this._sign();
					}
					break;
				}
			}
		}
	}

	_handle_onSelectOperator = (operator) => 
	{
		this.setState({ operator_selected: operator });
	}

	_handle_onAttorneyChange = (index, attorney) => 
	{
		this._updateDocs(index, { attorney_selected: attorney });
	}

	_handle_onDownloadFile = (index) => 
	{
		const { documents } = this.state;

		this.setState({ loading: true, disabled: true, }, async () => 
		{
			await this._updateDocs(index, { loading: true });

			const link_result = await signGetFileContractProject({
				contract_number: documents[index].id, 
			});

			await getFile({ id: link_result.url, filename: `ЛК ЭВОЛЮЦИЯ ${ documents[index].id }.${ link_result.extension }` });

			await this._updateDocs(index, { loading: false, disabled: false, });
			this.setState({ loading: false, disabled: false, });
		});
	}

	_handle_onCancelFile = async (index) => 
	{
		const { onCancel } = this.props;
		const { documents } = this.state;
		await this._updateDocs(index, { loading: true });

		this.setState({ loading: true, disabled: true }, async () => 
		{
			const check_result = await signCheckCancelDocument({ contract_number: documents[index].id, doc_type_id: "144" });
			if(check_result.status === "success")
			{
				await signCancelDocument({ contract_number: documents[index].id, doc_type_id: "144" });
				const docs = [ ...this.state.documents ];
				docs.splice(index, 1);

				if(docs.length > 0)
				{
					this.setState({ documents: docs, loading: false, disabled: false, });
				}
				else
				{
					onCancel(true);
				}
			}
			else
			{
				await this._updateDocs(index, { 
					loading: false, 
					error: true, 
					message: check_result.message !== undefined && check_result.message !== null ? check_result.message : "Возникла ошибка при отмене подписания через ЭДО", 
				});
			}
		});
	}

	_handle_onCancel = () => 
	{
		const { onCancel } = this.props;
		const { documents } = this.state;

		var clean = false;
		if(documents.length === 0)
		{
			clean = true;
		}

		onCancel(clean);
	}

	_handle_onCheckEDOStatus = async (index) => 
	{
		const { documents } = this.state;

		await this._updateDocs(index, { loading: true });

		this.setState({ loading: true, disabled: true }, async () => 
		{
			const status_result = await docEDOStatus({ contract_number: documents[index].id });

			if(status_result.status >= 2)
			{
				await this._updateDocs(index, { loading: false, disabled: false, signing: false, completed: true, url: status_result.url_edo, });
			}
			else
			{
				await this._updateDocs(index, { loading: false, disabled: false, signing: true, completed: false, url: status_result.url_edo, });
			}

			if(this._checkDocumentsCompleted())
			{
				this.setState({ loading: false, disabled: false, finished: true, });
			}
			else
			{
				this.setState({ loading: false, disabled: false, finished: false, });
			}
		});
	}

	_handle_onGoToEDO = (index) => 
	{
		const { documents } = this.state;

		if(documents[index].url !== undefined && documents[index].url !== null)
		{
			window.open(documents[index].url, "_blank");
		}
	}

	render()
	{
		const { step, operators, edo_message, documents, loading, disabled, finished, operator_selected } = this.state;
		const { onCancel, } = this.props;

		return (
			<div className="edo_detail">
				<div className="docs_list medium-icon">
					<p className="list_title">Подписание через ЭДО</p>
				</div>
				{ step === 0 && (
					<div className="form_field edo_list_field">
						<label>Выберите оператора для отправки пакета документов</label>
						<div className="edo_list_selection edo_sign_documents_document" style={{ flexDirection: "column", border: "none", padding: "0px 0px 0px 15px", }}>
							{ operators !== undefined && operators !== null && (
								<>
									{ operators.length === 0 ? (
										<div className="edo_sign_documents_document_right" style={{ border: "none", }}>
											<div className="status_icon await"></div>
											<div className="status_title">
												<i>{ edo_message }</i>
											</div>
										</div>
									) : (
										operators.map((operator, index) => (
											<div className="form_field checkbox item" key={ index }>
												<input type="radio" 
													checked={ operator.box_id === operator_selected.box_id } 
													hidden="" 
													id={ `operator_${ index }` } 
													name={ `operator_${ index }` } 
													onChange={ (event) => this._handle_onSelectOperator(operator) } 
													disabled={ false } 
												/>
												<label htmlFor={ `operator_${ index }` } className="unselectable">{ operator.provider_edo }</label>
											</div>
										) )	
									)}
								</>
							) }
						</div>
					</div>
				) }
				{ step === 1 && (
					<div className="docs_list medium-icon edo_sign_documents_list">
						{ documents.map((document, index) => 
						{
							return (
								<div className="edo_sign_documents_document" key={ index }>
									<div className="edo_sign_documents_document_left">
										<p className="doc_name i-pdf extension edo_sign_document" data-format={ document.extension }>
											{ document.name } от { moment(document.date).format("DD.MM.YYYY") }
											{ document.type !== undefined && (<span>{ document.type }</span>) }
										</p>
									</div>
									<div className="edo_sign_documents_document_right">
										{ document.loading ? (
											<>
												{ loading && (
													<SpinnerCircular size={ 22 } thickness={ 100 } speed={ 100 } color="rgba(236, 239, 244, 1)" secondaryColor="rgba(28, 1, 169, 1)" />
												) }
											</>
										) : (
											<>
												{ document.error ? (
													<>
														<div className="status_icon error"></div>
														<i>{ document.message !== undefined && document.message !== null ? document.message : "" }</i>
													</>
												) : (
													<>
														{ document.attorney && (
															<>
																<div className="status_icon await"></div>
																<div className="edo_sign_status_attorney_select">
																	<Select 
																		id="edo_attorneys_list" 
																		name="edo_attorneys_list" 
																		options={ document.attorneys } 
																		placeholder="Выберите доверенность" 
																		noOptionsMessage={ ({ inputValue }) => !inputValue ? "" :"Ничего не найдено" } 
																		isSearchable={ true } 
																		className="autocomplete autocomplete_with_indicators" 
																		classNamePrefix="react-select" 
																		value={ document.attorney_selected } 
																		onChange={ (element) => { this._handle_onAttorneyChange(document.index, element) } } 
																		required={ true } 
																	/>
																</div>
															</>
														) }
														{ document.ready && (
															<>
																<div className="status_icon success"></div>
																{ document.entity_id !== undefined && (
																	<>	
																		<button className="button" disabled={ disabled } onClick={ () => this._handle_onDownloadFile(index) }>Посмотреть проект договора</button>	
																		<button className="button" disabled={ disabled } onClick={ () => this._handle_onCancelFile(index) }>Отменить подписание</button>
																	</>
																) }
															</>
														) }
														{ document.signing && (
															<>
																<div className="status_icon success"></div>
																<div className="status_title">
																	<i>Идет процесс подписания</i>
																</div>
																{ document.entity_id !== undefined && (
																	<>	
																		<button className="button" disabled={ disabled } onClick={ () => this._handle_onCheckEDOStatus(index) }>Проверить статус</button>
																	</>
																) }
															</>
														) }
														{ document.completed && (
															<>
																<div className="status_icon success"></div>
																<div className="status_title">
																	<i>Договор подписан со стороны "ЛК Эволюция"</i>
																</div>
																{ document.entity_id !== undefined && (
																	<button className="button" disabled={ disabled } onClick={ () => this._handle_onGoToEDO(index) }>Перейти в ЭДО</button>
																) }
															</>
														) }
													</>
												) }
											</>
										) }
									</div>
								</div>
							) 
						} ) }
					</div>
				) }
				<form ref={ this.ref_form } onSubmit={ this._handle_onFormSubmit } onKeyDown={(e) => {if (e.key === 'Enter') e.preventDefault() }}>
					<div className="form_field" style={{ display: "flex", justifyContent: "space-between" }}>
						<button className="button button-blue" onClick={ this._handle_onCancel }>Отменить</button>
						{ finished ? (
							<button type="submit" className="button button-blue">Завершить</button>
						) : (
							<button type="submit" className="button button-blue">
								{ loading ? (
									<SpinnerCircular size={24} thickness={100} speed={100} color="rgba(255, 255, 255, 1)" secondaryColor="rgba(255, 255, 255, 0.5)" style={{ marginTop: "4px" }}/>
								) : "Продолжить" }
							</button>
						) }
					</div>
				</form>
			</div>
		)
	}
}

function mapStateToProps(state, ownProps) 
{
	return {
		operators: state.edo.operators, 
		edo_message: state.edo.message, 
	}
}

export default connect(mapStateToProps)(DealContractsSignEDO)