import { connect } from "react-redux";

import { Avatar, CheckField, ElementsTooltip, Modal, Tag, Toast, Tooltip, TruncatedTooltip } from "@ax/components";
import { usersActions } from "@ax/containers/Users";
import { getDaysAgo } from "@ax/helpers";
import { useModal, usePermission, useToast } from "@ax/hooks";
import type { ICheck, IRole, ISite, ISiteRoles, IUser } from "@ax/types";

import * as S from "./style";

const UserItem = (props: IUserItemProps): JSX.Element => {
	const {
		user,
		sites,
		siteId,
		isSelected,
		onChange,
		onClick,
		deleteUser,
		resendInvitation,
		isSiteView = false,
		roles,
		hoverCheck,
		toggleDeleteToast,
		removeUserFromSite,
		getUsers,
	} = props;

	const { isOpen, toggleModal } = useModal();
	const { isVisible, toggleToast, setIsVisible } = useToast();

	const isAllowedToRemoveUsers = usePermission("usersRoles.removeUsers");

	const handleOnChange = (value: ICheck) => onChange(value);

	const handleDeleteUser = async () => {
		const deleted = user.id ? await deleteUser(user.id) : false;
		if (deleted) {
			toggleModal();
			toggleDeleteToast();
		}
	};

	const handleResendInvitation = () => {
		if (user.id) {
			resendInvitation(user.id).then((sended: boolean) => {
				if (sended) {
					toggleToast();
				}
			});
		}
	};

	const handleClick = () => user.id && onClick(user.id);

	const actionIsDisabled = isSiteView && user.isSuperAdmin;

	const deleteOption = isAllowedToRemoveUsers
		? {
				label: isSiteView ? "remove" : "delete",
				icon: "delete",
				action: () => toggleModal(),
				disabled: actionIsDisabled,
				helpText: actionIsDisabled ? "This is a superadmin user. You cannot remove it." : "",
			}
		: undefined;

	const resendOption = {
		label: "Resend invitation",
		icon: "sendEmail",
		action: () => handleResendInvitation(),
	};

	const menuOptions = user.status === "invited" ? [resendOption, deleteOption] : [deleteOption];

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

		const updated = await removeUserFromSite(user.id, siteId);
		if (updated) {
			toggleModal();
			toggleDeleteToast();
			getUsers();
		}
	};

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

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

	const tagColor = user.status === "invited" ? "#FFBB37" : "#AFC628";
	const days = user.dateCreated ? getDaysAgo(user.dateCreated) : "";
	const tooltipText = user.status === "invited" ? `Invited: ${days}` : "User Active";

	const toastProps = {
		action: () => null,
		setIsVisible,
		message: "Invitation sended",
	};

	const getSiteNameById = (id: number | string) => {
		if (id === "all") {
			return "ALL SITES";
		} else {
			const currentSite = sites.find((site: ISite) => site.id === id);
			return currentSite ? currentSite?.name : "";
		}
	};

	const getElementsNames = () =>
		user.isSuperAdmin
			? ["ALL SITES"]
			: user?.roles
					.filter((siteRoles: ISiteRoles) => siteRoles.siteId === "all" || Number.isInteger(siteRoles.siteId))
					.map((siteRoles: ISiteRoles) => getSiteNameById(siteRoles.siteId));

	let rolesIds: number[] = [];

	if (isSiteView) {
		const roleSite = user.roles.find(
			(siteRoles: { siteId: number | string; roles: number[] }) =>
				siteRoles.siteId === siteId || siteRoles.siteId === "all",
		);
		rolesIds = roleSite ? roleSite.roles : [];
	} else {
		user.roles.forEach((siteRoles: { siteId: number | string; roles: number[] }) => {
			rolesIds = [...rolesIds, ...siteRoles.roles];
		});
	}

	const rolesString = user.isSuperAdmin
		? ["Super - admin"]
		: roles?.filter((role: IRole) => rolesIds?.includes(role.id)).map((role: IRole) => role.name);

	const colors = user.isSuperAdmin
		? { "Super - admin": "#E7CBFE" }
		: rolesString?.reduce((prev: Record<string, string | undefined>, current) => {
				const color: IRole | undefined = roles.find((role: IRole) => role.name === current);
				prev[current] = color?.hex;
				return prev;
			}, {});

	return (
		<>
			<S.UserRow role="rowgroup" selected={isSelected} data-testid="user-item">
				<S.CheckCell role="cell">
					<CheckField
						name={user.name}
						value={user.id ?? ""}
						checked={isSelected || (hoverCheck && !actionIsDisabled)}
						onChange={handleOnChange}
						disabled={actionIsDisabled}
					/>
				</S.CheckCell>
				<S.UserCell role="cell" onClick={handleClick} data-testid="user-cell" clickable={!actionIsDisabled}>
					<S.AvatarWrapper>
						<Avatar image={user.image?.thumb} name={user.name} />
					</S.AvatarWrapper>
					<S.UserInfo>
						<S.UserName>
							<TruncatedTooltip content={user.name} expanded top={-5}>
								<S.Name>{user.name}</S.Name>
							</TruncatedTooltip>
						</S.UserName>
						<S.UserEmail>
							<TruncatedTooltip content={user.email} expanded top={-5}>
								<S.Email>{user.email}</S.Email>
							</TruncatedTooltip>
						</S.UserEmail>
						<S.UserUsername>
							<TruncatedTooltip content={`@${user.username}`} expanded top={-5}>
								<S.Username>@{user.username}</S.Username>
							</TruncatedTooltip>
						</S.UserUsername>
					</S.UserInfo>
				</S.UserCell>
				<S.RolesCell role="cell" onClick={handleClick} isSite={isSiteView} clickable={!actionIsDisabled}>
					<ElementsTooltip
						elements={rolesString}
						maxChar={30}
						rounded={true}
						defaultElements={isSiteView ? 4 : 2}
						elementsPerRow={2}
						colors={colors}
					/>
				</S.RolesCell>
				{isSiteView ? null : (
					<S.SitesCell role="cell" onClick={handleClick} clickable={!actionIsDisabled} data-testid="sites-cell">
						<ElementsTooltip elements={getElementsNames()} elementsPerRow={3} defaultElements={2} maxChar={15} />
					</S.SitesCell>
				)}
				{isSiteView ? null : (
					<S.StatusCell data-testid="status-cell">
						<Tooltip content={tooltipText} hideOnClick>
							<Tag type="status" text={user.status ?? ""} color={tagColor} />
						</Tooltip>
					</S.StatusCell>
				)}
				<S.ActionsCell role="cell">
					<S.StyledActionMenu icon="more" options={menuOptions} tooltip="Actions" />
				</S.ActionsCell>
			</S.UserRow>
			<Modal
				isOpen={isOpen}
				hide={toggleModal}
				title={isSiteView ? "Remove user from this site?" : "Delete User?"}
				secondaryAction={secondaryDeleteAction}
				mainAction={mainDeleteAction}
			>
				{isOpen ? (
					<S.ModalContent data-testid="modal-delete-content">
						{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>
			{isVisible && <Toast {...toastProps} />}
		</>
	);
};

interface IProps {
	user: IUser;
	siteId?: number;
	sites: ISite[];
	isSelected: boolean;
	isSiteView?: boolean;
	roles: IRole[];
	hoverCheck: boolean;
	onChange: (value: ICheck) => void;
	onClick: (id: number) => void;
	toggleDeleteToast: () => void;
	getUsers: () => void;
}

const mapDispatchToProps = {
	deleteUser: usersActions.deleteUser,
	resendInvitation: usersActions.resendInvitation,
	removeUserFromSite: usersActions.removeUserFromSite,
};

interface IDispatchProps {
	deleteUser(id: number): Promise<boolean>;
	resendInvitation(id: number): Promise<boolean>;
	removeUserFromSite(userID: number, siteID: number): Promise<boolean>;
}

export type IUserItemProps = IProps & IDispatchProps;

export default connect(null, mapDispatchToProps)(UserItem);
