import "@Front/index.scss";
import { DefaultLayout } from "@Front/Components/LayoutTemplates/DefaultLayout";
import { FrontendVariables } from "@Front/Config/VariablesFront";
import type { NextPage } from "next";
import type { AppType, AppProps } from "next/app";
import { useEffect, useState, type ReactElement, type ReactNode } from "react";
import getConfig from "next/config";
import { GoogleTagManager } from "@next/third-parties/google";
import { hotjar } from "react-hotjar";

import Loader from "src/common/Api/LeCoffreApi/sdk/Loader";

import IframeReference from "src/sdk/IframeReference";
import Iframe from "src/sdk/Iframe";
import MessageBus from "src/sdk/MessageBus";
import User from "src/sdk/User";

export type NextPageWithLayout<TProps = Record<string, unknown>, TInitialProps = TProps> = NextPage<TProps, TInitialProps> & {
	getLayout?: (page: ReactElement) => ReactNode;
};

type AppPropsWithLayout = AppProps & {
	Component: NextPageWithLayout;
} & {
	backApiProtocol: string;
	backApiHost: string;
	backApiPort: string;
	backApiRootUrl: string;
	backApiVersion: string;
	frontAppHost: string;
	idNotBaseUrl: string;
	idNotAuthorizeEndpoint: string;
	idNotClientId: string;
	fcAuthorizeEndpoint: string;
	fcClientId: string;
	docaposteApiUrl: string;
	hotjarSiteId: number;
	hotjarVersion: number;
	_4nkUrl: string;
	apiUrl: string;
};

const { publicRuntimeConfig } = getConfig();

const MyApp = (({
	Component,
	pageProps,
	backApiProtocol,
	backApiHost,
	backApiPort,
	backApiRootUrl,
	backApiVersion,
	frontAppHost,
	idNotBaseUrl,
	idNotAuthorizeEndpoint,
	idNotClientId,
	fcAuthorizeEndpoint,
	fcClientId,
	docaposteApiUrl,
	hotjarSiteId,
	hotjarVersion,
	_4nkUrl,
	apiUrl,
}: AppPropsWithLayout) => {
	const getLayout = Component.getLayout ?? ((page) => <DefaultLayout children={page}></DefaultLayout>);

	const instance = FrontendVariables.getInstance();
	instance.BACK_API_PROTOCOL = backApiProtocol;
	instance.BACK_API_HOST = backApiHost;
	instance.BACK_API_PORT = backApiPort;
	instance.BACK_API_ROOT_URL = backApiRootUrl;
	instance.BACK_API_VERSION = backApiVersion;
	instance.FRONT_APP_HOST = frontAppHost;
	instance.IDNOT_BASE_URL = idNotBaseUrl;
	instance.IDNOT_AUTHORIZE_ENDPOINT = idNotAuthorizeEndpoint;
	instance.IDNOT_CLIENT_ID = idNotClientId;
	instance.FC_AUTHORIZE_ENDPOINT = fcAuthorizeEndpoint;
	instance.FC_CLIENT_ID = fcClientId;
	instance.DOCAPOST_API_URL = docaposteApiUrl;
	instance.HOTJAR_SITE_ID = hotjarSiteId;
	instance.HOTJAR_VERSION = hotjarVersion;
	instance._4NK_URL = _4nkUrl;
	instance.API_URL = apiUrl;

	const [isConnected, setIsConnected] = useState(false);
	const [isReady, setIsReady] = useState(false);

	IframeReference.setTargetOrigin(_4nkUrl);

	useEffect(() => {
		const isAuthenticated = User.getInstance().isAuthenticated();
		setIsConnected(isAuthenticated);

		if (isAuthenticated) {
			MessageBus.getInstance().initMessageListener();
			MessageBus.getInstance().isReady().then(() => setIsReady(true));

			return () => {
				MessageBus.getInstance().destroyMessageListener();
			};
		}

		return () => { };
	}, []);

	useEffect(() => {
		if (!hotjarSiteId || !hotjarVersion) {
			console.warn("No hotjar site id or version provided");
			return;
		}
		console.log("Intializing hotjar");
		hotjar.initialize({
			id: hotjarSiteId,
			sv: hotjarVersion,
		});
	}, [hotjarSiteId, hotjarVersion]);

	return getLayout(
		<>
			{((isConnected && isReady) || !isConnected) &&
				<Component {...pageProps}>
					<GoogleTagManager gtmId="GTM-5GLJN86P" />
				</Component>
			}
			{isConnected && <Iframe />}
			<Loader />
		</>
	);
}) as AppType;

MyApp.getInitialProps = async () => {
	return {
		backApiProtocol: publicRuntimeConfig.NEXT_PUBLIC_BACK_API_PROTOCOL,
		backApiHost: publicRuntimeConfig.NEXT_PUBLIC_BACK_API_HOST,
		backApiPort: publicRuntimeConfig.NEXT_PUBLIC_BACK_API_PORT,
		backApiRootUrl: publicRuntimeConfig.NEXT_PUBLIC_BACK_API_ROOT_URL,
		backApiVersion: publicRuntimeConfig.NEXT_PUBLIC_BACK_API_VERSION,
		frontAppHost: publicRuntimeConfig.NEXT_PUBLIC_FRONT_APP_HOST,
		frontAppPort: publicRuntimeConfig.NEXT_PUBLIC_FRONT_APP_PORT,
		idNotBaseUrl: publicRuntimeConfig.NEXT_PUBLIC_IDNOT_BASE_URL,
		idNotAuthorizeEndpoint: publicRuntimeConfig.NEXT_PUBLIC_IDNOT_AUTHORIZE_ENDPOINT,
		idNotClientId: publicRuntimeConfig.NEXT_PUBLIC_IDNOT_CLIENT_ID,
		fcAuthorizeEndpoint: publicRuntimeConfig.NEXT_PUBLIC_FC_AUTHORIZE_ENDPOINT,
		fcClientId: publicRuntimeConfig.NEXT_PUBLIC_FC_CLIENT_ID,
		docaposteApiUrl: publicRuntimeConfig.NEXT_PUBLIC_DOCAPOST_API_URL,
		hotjarSiteId: publicRuntimeConfig.NEXT_PUBLIC_HOTJAR_SITE_ID,
		hotjarVersion: publicRuntimeConfig.NEXT_PUBLIC_HOTJAR_VERSION,
		_4nkUrl: publicRuntimeConfig.NEXT_PUBLIC_4NK_URL,
		apiUrl: publicRuntimeConfig.NEXT_PUBLIC_API_URL,
	};
};

export default MyApp;
