import '@/styles/globals.scss';
import '@/styles/themes/light.scss';
import '@/styles/themes/dark.scss';
import Head from 'next/head';
import { StoreProvider } from '@/store/store-reducer';
import NextApp, { AppContext, AppProps } from 'next/app';
import { ThemeProvider } from 'next-themes';
import axios, { AxiosError } from 'axios';
import { GetConfigResData } from '@/interfaces/responses/config/GetConfigRes';
import inter from '@/utils/font';
import { API_URL } from '@/constants';
import NProgress from 'nprogress';
import { Router } from 'next/router';
import PageHandler from './PageHandler';
import NotificationPopups from './NotificationPopups';
import 'nprogress/nprogress.css';

NProgress.configure({
	showSpinner: false,
	trickleSpeed: 200,
});

Router.events.on('routeChangeStart', (url) => {
	if (typeof window === 'undefined') return;

	const currentUrl = window.location.href;
	const nextUrl = new URL(url, window.location.origin).href;

	const currentPath = new URL(currentUrl).pathname;
	const nextPath = new URL(nextUrl).pathname;

	if (currentPath !== nextPath) {
		NProgress.start();
	}
});

Router.events.on('routeChangeComplete', () => {
	NProgress.done();
});

Router.events.on('routeChangeError', () => {
	NProgress.done();
});

function App(data: AppProps & { config?: GetConfigResData }) {
	const { Component, pageProps } = data;
	return (
		<>
			<style jsx global>
				{`
					* {
						font-family: ${inter.style.fontFamily};
					}
				`}
			</style>
			<Head>
				<title>Zano Trade</title>
				<meta name="description" content="Peer-to-Peer Trading App on Zano blockchain" />
				<meta
					name="viewport"
					content="width=device-width, initial-scale=1  user-scalable=no"
				/>
				<link rel="icon" href="/favicon.ico" />

				<meta property="og:type" content="website" />
				<meta property="og:url" content="https://trade.zano.org/" />
				<meta property="og:title" content="Zano Trade" />
				<meta
					property="og:description"
					content="Peer-to-Peer Trading App on Zano blockchain"
				/>
				<meta property="og:image" content="social-banner.png" />

				<meta property="twitter:card" content="summary_large_image" />
				<meta property="twitter:url" content="https://trade.zano.org/" />
				<meta property="twitter:title" content="Zano Trade" />
				<meta
					property="twitter:description"
					content="Peer-to-Peer Trading App on Zano blockchain"
				/>
				<meta property="twitter:image" content="social-banner.png" />
			</Head>
			<StoreProvider>
				<ThemeProvider themes={['dark', 'light']} defaultTheme="dark">
					<Component {...pageProps} />
					<PageHandler config={data.config as GetConfigResData} />
					<NotificationPopups />
				</ThemeProvider>
			</StoreProvider>
		</>
	);
}

App.getInitialProps = async (context: AppContext) => {
	try {
		const pageProps = await NextApp.getInitialProps(context);

		const configRes = await axios.get(`${API_URL}/api/config`, {
			headers: {
				'Content-Type': 'application/json',
			},
			withCredentials: true,
		});

		return {
			...pageProps,
			config: configRes.data.data,
		};
	} catch (error) {
		const err = error as AxiosError;
		console.error('Unable to fetch config data:', err?.response?.status, err?.message);

		return NextApp.getInitialProps(context);
	}
};

export default App;
