import { useEffect, useState } from "react";
import { connect } from "react-redux";

import { Loading, MainWrapper, Modal, Toast } from "@ax/components";
import { appActions } from "@ax/containers/App";
import { usersActions } from "@ax/containers/Users";
import { useModal, useShouldBeSaved, useToast } from "@ax/hooks";
import type { IRootState, ISite, IUser } from "@ax/types";

import UserForm from "../UserForm";

import * as S from "./style";

const UserEdit = (props: IProps) => {
	const { user, updateUser, isSaving, isLoading, deleteUser, currentUser, setHistoryPush, site, removeUserFromSite } =
		props;

	const { timezone } = user;
	const initForm = { ...user };
	if (!timezone) initForm.timezone = "Europe/Madrid";
	const isSiteView = !!site;
	const usersRoute = isSiteView ? "/sites/users" : "users";
	const [form, setForm] = useState<IUser>(initForm);
	const { isOpen, toggleModal } = useModal();
	const { isOpen: isOpenAdvise, toggleModal: toggleAdviseModal } = useModal(false);
	const { isVisible, toggleToast, setIsVisible } = useToast();

	const { isDirty, setIsDirty } = useShouldBeSaved(form);

	useEffect(() => {
		const { timezone } = user;
		const initForm = { ...user };
		if (!timezone) initForm.timezone = "Europe/Madrid";
		setForm(initForm);
	}, [user]);

	const handleSave = async () => {
		if (isOpenAdvise) {
			toggleAdviseModal();
		}
		const updated = form.id ? await updateUser(form.id, form, false) : false;
		if (updated) {
			setIsDirty(false);
			toggleToast();
		}
	};

	const rightButtonProps = {
		label: isSaving ? "Saving" : isDirty ? "Update User" : "Saved",
		disabled: isSaving || !isDirty,
		action: form.roles.length === 0 && !form.isSuperAdmin ? toggleAdviseModal : handleSave,
	};

	const handleDelete = async () => {
		if (!user.id) return;
		const isDeleted = await deleteUser(user.id);
		if (isDeleted) {
			setHistoryPush(usersRoute);
		}
	};

	const isSameUser = currentUser && currentUser.id === user.id;
	const isDeleteDisabled = isSiteView && user.isSuperAdmin;

	const rightLineButtonProps =
		!isSameUser && !isDeleteDisabled
			? {
					label: isSiteView ? "Remove user from this site" : "Delete User",
					action: toggleModal,
				}
			: undefined;

	const handleRemoveUserFromSite = async () => {
		if (!user.id || !site) return;

		const updated = await removeUserFromSite(user.id, site.id);
		if (updated) {
			setHistoryPush(usersRoute);
		}
	};

	const mainDeleteAction = {
		title: isSiteView ? "Remove" : "Delete",
		onClick: isSiteView ? handleRemoveUserFromSite : handleDelete,
	};

	const secondaryDeleteAction = { title: "Cancel", onClick: toggleModal };

	const toastProps = {
		setIsVisible,
		message: "User updated",
	};

	const mainModalAction = {
		title: "Edit User",
		onClick: handleSave,
	};

	const secondaryModalAction = { title: "Cancel", onClick: toggleAdviseModal };

	if (isLoading) return <Loading />;

	return (
		<MainWrapper
			title="Edit User"
			rightButton={rightButtonProps}
			backLink={true}
			rightLineButton={isSiteView ? rightLineButtonProps : undefined}
		>
			<UserForm form={form} setForm={setForm} user={user} isSiteView={isSiteView} site={site} />
			<Modal
				isOpen={isOpen}
				hide={toggleModal}
				title={isSiteView ? "Remove user from this site?" : "Delete User?"}
				secondaryAction={secondaryDeleteAction}
				mainAction={mainDeleteAction}
			>
				{isOpen ? (
					<S.ModalContent>
						{isSiteView ? (
							<p>
								Are you sure you want to remove <strong>{user.email}</strong> from this site? If you remove it, this
								user will no longer have access to this site but it will still be able to log in.
							</p>
						) : (
							<p>
								Are you sure you want to delete <strong>{user.email}</strong>? If you delete it, this user will no
								longer be able to log in.
							</p>
						)}
						<p>
							This action <strong>cannot be undone</strong>.
						</p>
					</S.ModalContent>
				) : null}
			</Modal>
			<Modal
				isOpen={isOpenAdvise}
				hide={toggleAdviseModal}
				title="Edit User?"
				secondaryAction={secondaryModalAction}
				mainAction={mainModalAction}
				size="S"
			>
				<S.ModalContent>
					Before editing an user, <strong>select the user&apos;s permissions and site access</strong>. If you proceed
					without selecting any permissions, the user{" "}
					<strong>won&apos;t have access to anything or view any content</strong>.
				</S.ModalContent>
			</Modal>
			{isVisible && <Toast {...toastProps} />}
		</MainWrapper>
	);
};

const mapStateToProps = (state: IRootState) => ({
	user: state.users.userForm,
	site: state.sites.currentSiteInfo,
	isSaving: state.app.isSaving,
	isLoading: state.app.isLoading,
	currentUser: state.users.currentUser,
});

interface IDispatchProps {
	setHistoryPush(path: string): void;
	updateUser(id: number, data: IUser, isProfile: boolean, isList?: boolean): Promise<boolean>;
	deleteUser(id: number): Promise<boolean>;
	removeUserFromSite(userID: number, siteID: number): Promise<boolean>;
}

const mapDispatchToProps = {
	setHistoryPush: appActions.setHistoryPush,
	updateUser: usersActions.updateUser,
	deleteUser: usersActions.deleteUser,
	removeUserFromSite: usersActions.removeUserFromSite,
};

interface IProfileProps {
	user: IUser;
	site: ISite | null;
	isSaving: boolean;
	isLoading: boolean;
	currentUser: IUser | null;
}

type IProps = IProfileProps & IDispatchProps;

export default connect(mapStateToProps, mapDispatchToProps)(UserEdit);
