import * as React from "react";
import * as Yup from "yup";
import AddressFormModal from "./AddressFormModal";
import { ConfirmationModal } from "../../../common/ConfirmationModal";
import { RouteComponentProps } from "react-router-dom";
import Dropdown, { Option } from 'react-dropdown';
import { Field, Formik, Form } from "formik";
import { IAddress } from "../../../../apiModels/ViewModels";
import { GetObject } from "../../../../services/localStorageService";
import { AddressController_CreateUserAddress, AddressController_DeleteUserAddress, AddressController_GetUserAddresses, AddressController_UpdateUserAddress } from "../../../../apiClient/routes";
import http from "../../../../services/httpService";
import { toast } from "react-toastify";

type AddressManagementProps = RouteComponentProps<{ id: string }>;

type AddressManagementState = {
	selectedAddressId: string,
	showConfirmModal: boolean
	showCreateAddressModal: boolean,
	userAddresses: Array<IAddress>
};

class AddressManagement extends React.Component<AddressManagementProps, AddressManagementState> {
	constructor(props: AddressManagementProps) {
		super(props);

		this.state = {
			selectedAddressId: '',
			showConfirmModal: false,
			showCreateAddressModal: false,
			userAddresses: new Array<IAddress>()
		}
	}

	async componentDidMount() {
		document.title = "Správa adres"

		const user = GetObject();
		if (user !== null) {
			await http.get<IAddress[]>(AddressController_GetUserAddresses(user.unique_name.toString())).then((response) => {
				const userAddresses = response.data;
				this.setState({ userAddresses });
			});
		} else {
			this.props.history.push('/');
		}
	}

	handleAddressChange = (arg: Option): void => {
		this.setState({ selectedAddressId: arg.value });
	}

	handleAddressDeleteClick = (): void => {
		const { selectedAddressId, userAddresses  } = this.state;
		http.delete(AddressController_DeleteUserAddress(selectedAddressId), { validateStatus: (status: number) => { return status <= 400 } }).then((response) => {
			if (response.status == 200) {

				toast.success("Adresa úspěšně odstraněna!", {
					position: "top-right",
					autoClose: 3000,
					hideProgressBar: true,
					closeOnClick: true,
					pauseOnHover: false,
					draggable: true,
					progress: undefined,
				});

				const filteredUserAddresses = userAddresses.filter(i => i.id.toString() !== selectedAddressId);
				this.setState({ userAddresses: filteredUserAddresses, selectedAddressId: '' }); // save new array
			} else if (response.status == 400) {
				toast.error("Něco se nepovedlo!", {
					position: "top-right",
					autoClose: 3000,
					hideProgressBar: true,
					closeOnClick: true,
					pauseOnHover: false,
					draggable: true,
					progress: undefined,
				});
			}
		}).catch(e => {
			console.log(e);
			this.setState({ ...this.state });
		});
	}

	handleCreateAddressClick = (): void => {
		this.setState({ showCreateAddressModal: !this.state.showCreateAddressModal });
	}

	handleCreateAddressModalClose = (): void => {
		this.setState({ showCreateAddressModal: false });
	}

	// Když předávám funkci dále do child komponent, tak nesmí být async (nějak to hapruje či čo)
	handleCreateAddressModalSubmit = (newAddress: IAddress): void => {
		http.post<IAddress>(AddressController_CreateUserAddress, newAddress, { validateStatus: (status: number) => { return status <= 400 } }).then((response) => {
			if (response.status == 200) {
				const newAddress = response.data;

				toast.success("Adresa úspěšně vytvořena!", {
					position: "top-right",
					autoClose: 3000,
					hideProgressBar: true,
					closeOnClick: true,
					pauseOnHover: false,
					draggable: true,
					progress: undefined,
				});

				let newUserAddresses = [...this.state.userAddresses]; // create copy
				newUserAddresses.push(newAddress); // insert updated address

				this.setState({ userAddresses: newUserAddresses, showCreateAddressModal: false }); // save new array
			} else if (response.status == 400) {
				toast.error("Něco se nepovedlo!", {
					position: "top-right",
					autoClose: 3000,
					hideProgressBar: true,
					closeOnClick: true,
					pauseOnHover: false,
					draggable: true,
					progress: undefined,
				});
			}
		}).catch(e => {
			console.log(e);
			this.setState({ ...this.state });
		});
	}
	
	handleHideConfirmModal = (): void => {
		this.setState({ showConfirmModal: false });
	}

	handleShowConfirmModal = (): void => {
		this.setState({ showConfirmModal: true });
	}

	async handleUpdateAddressClick(address: IAddress): Promise<void> {
		await http.post<IAddress>(AddressController_UpdateUserAddress, address, { validateStatus: (status: number) => { return status <= 400 } }).then(async (response) => {
			if (response.status == 200) {
				const newAddress = await response.data;

				toast.success("Adresa úspěšně změněna!", {
					position: "top-right",
					autoClose: 3000,
					hideProgressBar: true,
					closeOnClick: true,
					pauseOnHover: false,
					draggable: true,
					progress: undefined,
				});

				let userAddresses = this.state.userAddresses.filter(i => i.id !== address.id); // create copy without updated address
				userAddresses.push(newAddress); // insert updated address

				this.setState({ userAddresses }); // save new array
			} else if (response.status == 400) {
				toast.error("Něco se nepovedlo!", {
					position: "top-right",
					autoClose: 3000,
					hideProgressBar: true,
					closeOnClick: true,
					pauseOnHover: false,
					draggable: true,
					progress: undefined,
				});
			}
		}).catch(e => {
			console.log(e);
			this.setState({ ...this.state });
		});
	}

	render() {
		const { selectedAddressId, showCreateAddressModal, userAddresses } = this.state;

		const addressValidationSchema = Yup.object().shape({
			firstName: Yup.string().required("Jméno je vyžadováno!"),
			lastName: Yup.string().required("Příjmení je vyžadováno!"),
			phoneNumber: Yup.string().required("Telefonní číslo je vyžadováno!"),
			city: Yup.string().required("Město je vyžadováno!"),
			street: Yup.string().required("Ulice je vyžadována!"),
			zipCode: Yup.string().required("PSČ je vyžadováno!")
		});

		const initAddress: IAddress = {
			id: 0,
			firstName: '',
			lastName: '',
			phoneNumber: '',
			city: '',
			street: '',
			zipCode: '',
			email: '',
			addressTypeID: 0
		}

		let dropDownOptions = userAddresses.map(address => {
			return {
				value: address.id.toString(),
				label: `${address.firstName}, ${address.lastName}, ${address.city}, ${address.street} ...`
			}
		}).sort(function (a, b) { return parseInt(a.value, 10) < parseInt(b.value, 10) ? -1 : 1 });

		return (
			<React.Fragment>
				<AddressFormModal
					onCreateAddressModalClose={this.handleCreateAddressModalClose}
					onCreateAddressModalSubmit={this.handleCreateAddressModalSubmit}
					show={showCreateAddressModal} />

				<ConfirmationModal
					bodyText={"Opravdu si přejete smazat zvolenou adresu?"}
					modalTitle={"Potvrzení smazání adresy"}
					onConfirmClick={this.handleAddressDeleteClick}
					onHide={this.handleHideConfirmModal}
					show={this.state.showConfirmModal} />

				<div className="row" style={{ marginBottom: '24px' }}>
					<div className="col-lg-12">
						<Dropdown
							className='my-dropdown-root' controlClassName='checkout__dropdown__control' placeholderClassName='my-dropdown-placeholder'
							menuClassName='my-dropdown-menu'
							placeholder='Zvolte adresu'
							options={dropDownOptions}
							onChange={this.handleAddressChange} value={selectedAddressId}
						/>
						<button onClick={() => this.handleCreateAddressClick()} type="button" className="primary-btn">Vytvořit adresu</button>
					</div>
				</div>

				{selectedAddressId
					? <div className="row">
						<div className="col-lg-12">
							<Formik
								initialValues={userAddresses.find(i => i.id.toString() === selectedAddressId) || { ...initAddress }}
								validationSchema={addressValidationSchema}
								enableReinitialize={true}
								onSubmit={(values: IAddress) => (this.handleUpdateAddressClick(values))}
							>
								{({ errors, handleReset, handleSubmit, touched }) => (
									<Form onReset={handleReset} onSubmit={handleSubmit}>
										<div className="row">
											<div className="col-lg-6">
												<div className="checkout__input">
													<p>Jméno<span>*</span></p>
													<Field name="firstName" type="text" placeholder="Jméno"
														className={(touched.firstName && errors.firstName)
															? 'input__error'
															: (touched.firstName && !errors.firstName ? 'input__success' : '')}
													/>
													{errors && errors.firstName && touched.firstName && <label className="error-message">{errors.firstName}</label>}
												</div>
											</div>
											<div className="col-lg-6">
												<div className="checkout__input">
													<p>Příjmení<span>*</span></p>
													<Field name="lastName" type="text" placeholder="Příjmení"
														className={(touched.lastName && errors.lastName)
															? 'input__error'
															: (touched.lastName && !errors.lastName ? 'input__success' : '')}
													/>
													{errors.lastName && touched.lastName && <label className="error-message">{errors.lastName}</label>}
												</div>
											</div>
										</div>
										<div className="checkout__input">
											<p>Město a ulice<span>*</span></p>
											<Field name="city" type="text" placeholder="Město"
												className={(touched.city && errors.city)
													? 'checkout__input__add input__error'
													: (touched.city && !errors.city ? 'checkout__input__add input__success' : 'checkout__input__add')}
											/>
											{errors.city && touched.city && <label className="error-message">{errors.city}</label>}
											<Field name="street" type="text" placeholder="Ulice"
												className={(touched.street && errors.street)
													? 'input__error'
													: (touched.street && !errors.street ? 'input__success' : '')}
											/>
											{errors.street && touched.street && <label className="error-message">{errors.street}</label>}
										</div>
										<div className="checkout__input">
											<p>PSČ<span>*</span></p>
											<Field name="zipCode" type="text" placeholder="Poštovní směrovací číslo"
												className={(touched.zipCode && errors.zipCode)
													? 'input__error'
													: (touched.zipCode && !errors.zipCode ? 'input__success' : '')}
											/>
											{errors.zipCode && touched.zipCode && <label className="error-message">{errors.zipCode}</label>}
										</div>
										<div className="row">
											<div className="col-lg-6">
												<div className="checkout__input">
													<p>Telefonní číslo<span>*</span></p>
													<Field name="phoneNumber" type="text" placeholder="Telefonní číslo"
														className={(touched.phoneNumber && errors.phoneNumber)
															? 'input__error'
															: (touched.phoneNumber && !errors.phoneNumber ? 'input__success' : '')}
													/>
													{errors.phoneNumber && touched.phoneNumber && <label className="error-message">{errors.phoneNumber}</label>}
												</div>
											</div>
										</div>
										<button onClick={() => this.handleShowConfirmModal()} type="button" className="danger-btn">Smazat adresu</button>
										<button type="submit" className="primary-btn">Uložit změny</button>
									</Form>
								)}
							</Formik>
						</div>
					</div>
					: null
				}
			</React.Fragment>
		);
	}
}

export default AddressManagement;