import { connect } from "react-redux";
import { Link } from "react-router-dom";
import type { UniqueIdentifier } from "@dnd-kit/core";
import { useSortable } from "@dnd-kit/sortable";

import { useModal, usePermission, useToast } from "@ax/hooks";
import type { ICheck, IIntegration } from "@ax/types";
import { CheckField, Icon, Modal, Toast, ToggleField, Tooltip } from "@ax/components";
import { integrations } from "@ax/api";
import { integrationsActions } from "@ax/containers/Integrations";
import { appActions } from "@ax/containers/App";

import CopyModal from "./CopyModal";
import * as S from "./style";

const IntegrationItem = (props: IIntegrationItemProps): JSX.Element => {
	const {
		integration,
		isSelected,
		onChange,
		toggleToastDelete,
		deleteIntegration,
		getParams,
		changeState,
		toggleToastChange,
		listLength,
		hoverCheck,
	} = props;

	const { isOpen: isOpenDelete, toggleModal: toggleModalDelete } = useModal();
	const { isOpen: isOpenChangeState, toggleModal: toggleModalChangeState } = useModal();
	const { isOpen: isOpenCopy, toggleModal: toggleModalCopy } = useModal();
	const { isVisible: isVisibleCopy, toggleToast: toggleToastCopy, setIsVisible: setIsVisibleCopy } = useToast();

	const isAllowedToManageIntegrations = usePermission("general.manageSiteThirdPartyIntegrations");
	const isAllowedToActivateIntegrations = usePermission("general.activateSiteThirdPartyIntegrations");
	const isAllowedToDeactivateIntegrations = usePermission("general.deactivateSiteThirdPartyIntegrations");
	const isAllowedToDeleteIntegrations = usePermission("general.deleteSiteThirdPartyIntegrations");

	const { attributes, listeners, setNodeRef, transform, transition } = useSortable({
		id: integration.id as UniqueIdentifier,
	});

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

	const getContentPresence = (contentPresence: {
		presenceType: string | null;
		relatedPages: { id: number; title: string }[] | null;
	}) => {
		const { presenceType, relatedPages } = contentPresence;
		switch (presenceType) {
			case "all":
				return "All pages";
			case "page-specific":
			case "page-manual":
				return relatedPages?.length ? `Some pages: ${relatedPages.length}` : "None";
			default:
				return "None";
		}
	};

	const removeItem = async () => {
		if (integration.id) {
			const params = getParams();
			const deleted = await deleteIntegration(integration.id, params);
			if (deleted) {
				toggleToastDelete({ total: 1 });
			}
		}
	};

	const handleChangeState = async () => {
		const params = getParams();
		const active = !integration.active;
		const changed = integration.id && (await changeState(integration.id, active, params));
		if (changed) {
			toggleToastChange({ total: 1, active });
		}
	};

	const menuOptions = [
		{
			label: "copy in another site",
			icon: "copy2",
			action: toggleModalCopy,
		},
	];

	if (isAllowedToDeleteIntegrations) {
		menuOptions.push({
			label: "delete",
			icon: "delete",
			action: toggleModalDelete,
		});
	}

	const mainDeleteModalAction = {
		title: "Delete add-on",
		onClick: removeItem,
	};

	const secondaryDeleteModalAction = { title: "Cancel", onClick: toggleModalDelete };

	const mainChangeStateModalAction = {
		title: `${integration.active ? "Disable" : "Enable"} add-on`,
		onClick: handleChangeState,
	};

	const secondaryChangeStateModalAction = { title: "Cancel", onClick: toggleModalChangeState };

	const copyToastProps = {
		setIsVisible: setIsVisibleCopy,
		message: "1 Add-on copied to another Site",
	};

	const copyIntegration = async (site: number) => {
		toggleModalCopy();
		if (integration.id) {
			await integrations.duplicateIntegration(integration.id, site);
			toggleToastCopy();
		}
	};

	const handleClick = () => {
		const { setCurrentIntegration, setHistoryPush } = props;
		if (integration.editable) {
			setCurrentIntegration(integration);
			setHistoryPush("addons/edit");
		}
	};

	const handleCheckClick = (e: React.MouseEvent<HTMLDivElement>) => e.stopPropagation();

	const isToggleDisabled =
		(integration.active && !isAllowedToDeactivateIntegrations) ||
		(!integration.active && !isAllowedToActivateIntegrations);

	const getIntegrationDescription = () => {
		switch (integration.type) {
			case "analytics":
				return (
					<div>
						This row is dedicated to reordering GTM with other add-ons. For any changes, please visit the{" "}
						<Link to="/sites/settings/analytics">Analytics section</Link>
					</div>
				);
			case "datalayer":
				return (
					<div>
						This row is dedicated to reordering Datalayer with other add-ons. For any changes, please visit the{" "}
						<Link to="/sites/settings/analytics">Analytics section</Link>
					</div>
				);
			default:
				return integration.description;
		}
	};

	const getIntegrationTag = () => {
		const { contentBody, contentHead } = integration;

		let tagProps = null;

		if (contentHead && contentBody && contentBody.trim() !== "" && contentHead.trim() !== "") {
			tagProps = { text: "Head&Body", color: "#DFCAFA", icon: "CodeHeadBody" };
		} else if (contentBody && contentBody.trim() !== "") {
			tagProps = { text: "Body", color: "#DAFE9F", icon: "CodeBody" };
		} else if (contentHead && contentHead.trim() !== "") {
			tagProps = { text: "Head", color: "#BEEEFD", icon: "CodeHead" };
		}

		if (tagProps) {
			return (
				<S.Tag color={tagProps.color}>
					<S.IconTag>
						<Icon name={tagProps.icon} size="16" />
					</S.IconTag>
					<div>{tagProps.text}</div>
				</S.Tag>
			);
		}
	};

	const checkBox = (
		<CheckField
			name="check"
			value={integration.id ?? ""}
			checked={isSelected || (hoverCheck && integration.editable)}
			onChange={handleOnChange}
			disabled={!integration.editable}
		/>
	);

	return (
		<>
			<S.ItemRow
				selected={isSelected}
				data-testid="integration-item-row"
				disabled={!integration.editable}
				onClick={handleClick}
				clickable={isAllowedToManageIntegrations}
				ref={setNodeRef}
				cssTransform={transform}
				transition={transition}
				{...listeners}
				{...attributes}
			>
				<S.HandleWrapper hidden={listLength < 2} data-testid="handle-wrapper">
					<S.IconHandleWrapper>
						<Icon name="drag" size="16" />
					</S.IconHandleWrapper>
				</S.HandleWrapper>
				<S.CheckCell role="cell" hasHandle={listLength >= 2} onClick={handleCheckClick}>
					{!integration.editable ? (
						<Tooltip content="This cannot be selected. You can only reorder it" left={60}>
							{checkBox}
						</Tooltip>
					) : (
						<>{checkBox}</>
					)}
				</S.CheckCell>
				<S.NameCell role="cell">
					<S.Order>#{integration.correlativeScriptOrder}</S.Order>
					<div>{integration.name}</div>
				</S.NameCell>
				<S.DescriptionCell role="cell">{getIntegrationDescription()}</S.DescriptionCell>
				{integration.type === "addon" && (
					<>
						<S.AppliedOnCell role="cell">
							<div>
								Applied on: <S.ContentPresence>{getContentPresence(integration.contentPresence)}</S.ContentPresence>
							</div>
						</S.AppliedOnCell>
						<S.CodeCell role="cell">{getIntegrationTag()}</S.CodeCell>
						<S.StateCell role="cell" onClick={handleCheckClick}>
							<ToggleField
								name="state"
								value={integration.active}
								onChange={toggleModalChangeState}
								disabled={isToggleDisabled}
								size="s"
							/>
						</S.StateCell>
						<S.ActionsCell role="cell">
							<S.StyledActionMenu icon="more" options={menuOptions} tooltip="Actions" />
						</S.ActionsCell>
					</>
				)}
			</S.ItemRow>
			<Modal
				isOpen={isOpenDelete}
				hide={toggleModalDelete}
				title="Delete add-on"
				secondaryAction={secondaryDeleteModalAction}
				mainAction={mainDeleteModalAction}
				size="S"
			>
				<S.ModalContent>
					Are you sure you want to delete <strong>{integration.name} add-on</strong>? This action{" "}
					<strong>cannot be undone</strong>.
				</S.ModalContent>
			</Modal>
			<Modal
				isOpen={isOpenChangeState}
				hide={toggleModalChangeState}
				title={`${integration.active ? "Disable" : "Enable"} Add-on`}
				secondaryAction={secondaryChangeStateModalAction}
				mainAction={mainChangeStateModalAction}
				size="S"
			>
				<S.ModalContent>
					Are you sure you want to {integration.active ? "disable" : "enable"}{" "}
					<strong>{integration.name} add-on</strong>? This add-on will {integration.active ? "stop" : "start"} working
					in the pages previously added.
				</S.ModalContent>
			</Modal>
			<CopyModal isOpen={isOpenCopy} hide={toggleModalCopy} action={copyIntegration} />
			{isVisibleCopy && <Toast {...copyToastProps} />}
		</>
	);
};

interface IProps {
	integration: IIntegration;
	isSelected: boolean;
	onChange: (e: any) => void;
	toggleToastDelete: (state: { total: number }) => void;
	deleteIntegration: (integrationId: number | number[], currentParams?: any) => Promise<boolean>;
	getParams: () => any;
	changeState: (integrationId: number, active: boolean, params: any) => Promise<boolean>;
	toggleToastChange: (state: { total: number; active: boolean }) => void;
	listLength: number;
	hoverCheck: boolean;
}

const mapDispatchToProps = {
	setHistoryPush: appActions.setHistoryPush,
	setCurrentIntegration: integrationsActions.setCurrentIntegration,
};

interface IDispatchProps {
	setHistoryPush: (path: string) => void;
	setCurrentIntegration: (integration: IIntegration) => void;
}

export type IIntegrationItemProps = IProps & IDispatchProps;

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