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

import type { IIntegration, IRootState, ISite, ILanguage } from "@ax/types";
import { useModal } from "@ax/hooks";
import { Tooltip, IconAction } from "@ax/components";
import { integrationsActions } from "@ax/containers/Integrations";

import PasteIntegrationButton from "./PasteIntegrationButton";
import IntegrationItem from "./IntegrationItem";
import SideModal from "./SideModal";
import * as S from "./style";

const IntegrationsField = (props: IIntegrationsFieldProps): JSX.Element => {
	const {
		value,
		onChange,
		disabled,
		getIntegrations,
		integrations,
		site,
		languages,
		copyIntegration,
		integrationCopy,
	} = props;

	const [state, setState] = useState<Partial<IIntegration>[]>(value || []);
	const { isOpen, toggleModal } = useModal();

	useEffect(() => {
		setState(value || []);
	}, [value]);

	useEffect(() => {
		const params = {
			pagination: false,
			filterState: "enable",
		};
		site && getIntegrations(site.id, params, true);
	}, [getIntegrations, site]);

	const updateState = (newState: Partial<IIntegration>[]) => {
		setState(newState);
		onChange?.(newState);
	};

	const handleAdd = (integration: Partial<IIntegration>) => {
		updateState([...state, integration]);
	};

	const handleEditIntegration = (modifiedIntegration: Partial<IIntegration>, index: number) => {
		const newIntegrations = [...state];
		newIntegrations.splice(index, 1, modifiedIntegration);
		updateState(newIntegrations);
	};

	const removeItem = (index: number) => {
		const newValue = [...state];
		newValue.splice(index, 1);
		updateState(newValue);
	};

	const availableIntegrations = integrations.filter(
		(integration) =>
			(!integration.contentPresence.presenceType || integration.contentPresence.presenceType === "page-manual") &&
			!state?.some((_integration: Partial<IIntegration>) => Number(_integration.id) === Number(integration.id)),
	);

	const timeSinceIntegrationCopy = integrationCopy
		? differenceInSeconds(new Date(), new Date(integrationCopy.date))
		: null;
	const eightHoursInSeconds = 8 * 60 * 60;
	const showPasteIntegrationButton =
		!disabled &&
		!!integrationCopy &&
		timeSinceIntegrationCopy !== null &&
		timeSinceIntegrationCopy < eightHoursInSeconds;

	const pasteIntegration = () => {
		integrationCopy && handleAdd(integrationCopy.integration);
	};

	return (
		<S.Wrapper>
			<S.Title>Add-ons</S.Title>
			<S.ItemRow>
				<S.Subtitle>{state?.length || 0} items</S.Subtitle>
				<S.ActionsWrapper>
					{showPasteIntegrationButton && <PasteIntegrationButton pasteIntegration={pasteIntegration} />}
					{!disabled && (
						<>
							<Tooltip content="Add Add-on" hideOnClick>
								<IconAction icon="add" onClick={toggleModal} />
							</Tooltip>
							<SideModal
								isOpen={isOpen}
								toggleModal={toggleModal}
								handleClick={handleAdd}
								integrations={availableIntegrations}
							/>
						</>
					)}
				</S.ActionsWrapper>
			</S.ItemRow>
			{state?.map((integration: Partial<IIntegration>, index: number) => (
				<IntegrationItem
					key={`${integration.id}${integration.name}${index}`}
					integration={integration}
					disabled={disabled}
					removeItem={() => removeItem(index)}
					editIntegration={handleEditIntegration}
					languages={languages}
					index={index}
					copyIntegration={copyIntegration}
				/>
			))}
		</S.Wrapper>
	);
};

const mapStateToProps = (state: IRootState) => ({
	site: state.sites.currentSiteInfo,
	integrations: state.integrations.integrations,
	languages: state.app.globalLangs,
	integrationCopy: state.integrations.integrationCopy,
});

const mapDispatchToProps = {
	getIntegrations: integrationsActions.getIntegrations,
	copyIntegration: integrationsActions.copyIntegration,
};

interface IStateProps {
	integrations: IIntegration[];
	value: Partial<IIntegration>[];
	onChange: (value: Partial<IIntegration>[]) => void;
	disabled: boolean;
	site: ISite | null;
	languages: ILanguage[];
	integrationCopy: { date: Date; integration: IIntegration } | null;
}

interface IDispatchProps {
	getIntegrations: (
		site: number,
		params: { pagination: boolean; filterState: string },
		isPage?: boolean,
	) => Promise<void>;
	copyIntegration: (integration: Partial<IIntegration>) => void;
}

export type IIntegrationsFieldProps = IStateProps & IDispatchProps;

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