import { createApp } from 'vue';

import '@vue-flow/core/dist/style.css';
import '@vue-flow/core/dist/theme-default.css';
import '@vue-flow/controls/dist/style.css';
import '@vue-flow/minimap/dist/style.css';
import '@vue-flow/node-resizer/dist/style.css';

import 'vue-json-pretty/lib/styles.css';
import '@n8n/design-system/css/index.scss';
// import '@n8n/design-system/css/tailwind/index.css';

import '@/main.scss';
import '@/features/ai/assistant/aiBuilderDiff.scss';
// Ensure i18n HMR owner is evaluated as early as possible in dev
import '@/app/dev/i18nHmr';

import App from '@/app/App.vue';
import router from '@/app/router';

import { IconBodyLoaderKey } from '@n8n/design-system';
import { loadLucideIconBody } from '@n8n/design-system/icons/lucide';
import { i18nInstance } from '@n8n/i18n';

import { TelemetryPlugin } from '@/app/plugins/telemetry';
import { GlobalComponentsPlugin } from '@/app/plugins/components';
import { GlobalDirectivesPlugin } from '@/app/plugins/directives';

import { createPinia, PiniaVuePlugin } from 'pinia';
import { ChartJSPlugin } from '@/app/plugins/chartjs';
import { SentryPlugin } from '@/app/plugins/sentry';
import { registerVitePreloadErrorHandler } from '@/app/plugins/vitePreloadError';
import { registerModuleRoutes } from '@/app/moduleInitializer/moduleInitializer';
import { installRenderTracker } from '@/app/dev/render-tracker';

import type { VueScanOptions } from 'z-vue-scan';

registerVitePreloadErrorHandler();

const pinia = createPinia();

const app = createApp(App);

app.provide(IconBodyLoaderKey, loadLucideIconBody);

app.use(SentryPlugin);

// Register module routes
// We do this here so landing straight on a module page works
registerModuleRoutes(router);

app.use(TelemetryPlugin);
app.use(PiniaVuePlugin);
app.use(GlobalComponentsPlugin);
app.use(GlobalDirectivesPlugin);
app.use(pinia);
app.use(router);
app.use(i18nInstance);
app.use(ChartJSPlugin);

// Opt-in component re-render counter for the canvas performance benchmark.
// No-op unless the N8N_RENDER_TRACKING localStorage flag is set, so it is
// inert for real users. Must run before mount so the mixin covers every
// component.
installRenderTracker(app);

if (import.meta.env.VUE_SCAN) {
	const { default: VueScan } = await import('z-vue-scan');
	app.use<VueScanOptions>(VueScan, {
		enable: true,
	});
}

app.mount('#app');

if (import.meta.env.DEV) {
	void import('@/app/dev/dev-panel').then((m) => m.mountDevPanel());
}

if (!import.meta.env.PROD) {
	// Make sure that we get all error messages properly displayed
	// as long as we are not in production mode
	window.onerror = (message, _source, _lineno, _colno, error) => {
		// eslint-disable-next-line @typescript-eslint/no-base-to-string
		if (message.toString().includes('ResizeObserver')) {
			// That error can apparently be ignored and can probably
			// not do anything about it anyway
			return;
		}
		console.error('error caught in main.ts');
		console.error(message);
		console.error(error);
	};
}
