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

import { Loading, MainWrapper, Nav } from "@ax/components";
import { analyticsActions } from "@ax/containers/Analytics";
import { appActions } from "@ax/containers/App";
import { RouteLeavingGuard } from "@ax/guards";
import { useModal } from "@ax/hooks";
import type { IAnalytics, INavItem, IRootState, ISite } from "@ax/types";

import { Dimensions, Groups, ResetModal, ScriptCode, Warning } from "./atoms";

import * as S from "./style";

const Analytics = (props: IProps): JSX.Element => {
	const {
		navItems,
		currentNavItem,
		isSaving,
		isLoading,
		analytics,
		getAnalytics,
		setHistoryPush,
		site,
		updateScriptCode,
		deleteScriptCode,
	} = props;

	const [showWarning, setShowWarning] = useState(false);
	const [scriptCode, setScriptCode] = useState(analytics.scriptCode);
	const [isDirty, setIsDirty] = useState(false);
	const { isOpen, toggleModal } = useModal();

	// biome-ignore lint/correctness/useExhaustiveDependencies: TODO: fix this
	useEffect(() => {
		const handleGetAnalytics = async () => await getAnalytics(site?.id);
		handleGetAnalytics();
	}, []);

	useEffect(() => {
		setScriptCode(analytics.scriptCode);
		setShowWarning(!analytics.siteScriptCodeExists);
		setIsDirty(false);
	}, [analytics.scriptCode, analytics.siteScriptCodeExists]);

	useEffect(() => {
		setIsDirty(scriptCode !== analytics.scriptCode);
	}, [scriptCode, analytics.scriptCode]);

	const handleSave = async () => {
		const isSaved = !!site && (await updateScriptCode(scriptCode, site.id));
		if (isSaved) setIsDirty(false);
	};

	const setRoute = (path: string) => setHistoryPush(path);

	const handleReset = async () => {
		await deleteScriptCode(site?.id);
		isOpen && toggleModal();
		setShowWarning(true);
		setScriptCode(analytics.scriptCode);
		setIsDirty(false);
	};

	const modalText = (
		<>
			Analytics Script Code <strong>is not saved</strong>.{" "}
		</>
	);

	const analyticsSettings = (
		<>
			{showWarning ? (
				<Warning setShowWarning={setShowWarning} />
			) : (
				<S.AnalyticsWrapper>
					<ScriptCode scriptCode={scriptCode} setScriptCode={setScriptCode} />
					{analytics.dimensions && <Dimensions dimensions={analytics.dimensions} />}
					{analytics.groups && <Groups groups={analytics.groups} />}
				</S.AnalyticsWrapper>
			)}
		</>
	);

	const rightButtonProps = {
		label: isSaving ? "Saving" : isDirty ? "Save" : "Saved",
		disabled: isSaving || !isDirty,
		action: handleSave,
	};

	const secondaryButtonProps = !showWarning
		? {
				label: "Reset to Global Defaults",
				action: toggleModal,
			}
		: undefined;

	const mainResetModalAction = {
		title: "Reset to Global",
		onClick: handleReset,
	};

	return (
		<>
			<RouteLeavingGuard when={isDirty} action={setRoute} text={modalText} />
			<MainWrapper
				backLink={false}
				title="Analytics Settings"
				rightButton={rightButtonProps}
				rightLineButton={secondaryButtonProps}
			>
				<S.Wrapper>
					<Nav current={currentNavItem} items={navItems} onClick={setRoute} />
					<S.ContentWrapper>{isLoading ? <Loading /> : analyticsSettings}</S.ContentWrapper>
				</S.Wrapper>
			</MainWrapper>
			<ResetModal isOpen={isOpen} toggleModal={toggleModal} mainModalAction={mainResetModalAction} />
		</>
	);
};

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

const mapDispatchToProps = {
	setHistoryPush: appActions.setHistoryPush,
	getAnalytics: analyticsActions.getAnalytics,
	updateScriptCode: analyticsActions.updateScriptCode,
	deleteScriptCode: analyticsActions.deleteScriptCode,
};

interface IAnalyticsProps {
	navItems: INavItem[];
	currentNavItem: INavItem;
	isSaving: boolean;
	isLoading: boolean;
	analytics: IAnalytics;
	site: ISite | null;
}

interface IDispatchProps {
	getAnalytics(siteId?: number | null): Promise<void>;
	setHistoryPush(path: string, isEditor?: boolean): void;
	updateScriptCode(scriptCode: string, siteId?: number | null): Promise<boolean>;
	deleteScriptCode(siteId?: number | null): Promise<boolean>;
}

type IProps = IAnalyticsProps & IDispatchProps;

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