/* eslint-disable jsx-a11y/no-static-element-interactions */
/* eslint-disable jsx-a11y/click-events-have-key-events */
import React, { useCallback, useEffect, useState } from 'react';
import { useTranslation } from 'react-i18next';
import { useQuery } from 'react-query';
import { useEffectOnce } from 'react-use';
import { ArrowRightOutlined } from '@ant-design/icons';
import { Button, Card, Form, Typography } from 'antd';
import logEvent from 'api/common/logEvent';
import getIngestionData from 'api/settings/getIngestionData';
import cx from 'classnames';
import { FeatureKeys } from 'constants/features';
import ROUTES from 'constants/routes';
import FullScreenHeader from 'container/FullScreenHeader/FullScreenHeader';
import InviteUserModal from 'container/OrganizationSettings/InviteUserModal/InviteUserModal';
import { InviteMemberFormValues } from 'container/OrganizationSettings/utils';
import { useSafeNavigate } from 'hooks/useSafeNavigate';
import history from 'lib/history';
import { UserPlus } from 'lucide-react';
import { useAppContext } from 'providers/App/App';
import { isModifierKeyPressed } from 'utils/app';

import ModuleStepsContainer from './common/ModuleStepsContainer/ModuleStepsContainer';
import { stepsMap } from './constants/stepsConfig';
import {
	OnboardingMethods,
	useOnboardingContext,
} from './context/OnboardingContext';
import { DataSourceType } from './Steps/DataSource/DataSource';
import {
	defaultApplicationDataSource,
	defaultAwsServices,
	defaultAzureServices,
	defaultInfraMetricsType,
	defaultLogsType,
	moduleRouteMap,
} from './utils/dataSourceUtils';
import {
	APM_STEPS,
	AWS_MONITORING_STEPS,
	AZURE_MONITORING_STEPS,
	getSteps,
	INFRASTRUCTURE_MONITORING_STEPS,
	LOGS_MANAGEMENT_STEPS,
} from './utils/getSteps';

import './Onboarding.styles.scss';

export enum ModulesMap {
	APM = 'APM',
	LogsManagement = 'LogsManagement',
	InfrastructureMonitoring = 'InfrastructureMonitoring',
	AwsMonitoring = 'AwsMonitoring',
	AzureMonitoring = 'AzureMonitoring',
}

export interface ModuleProps {
	id: string;
	title: string;
	desc: string;
}

export interface SelectedModuleStepProps {
	id: string;
	title: string;
	component: any;
}

export const useCases = {
	APM: {
		id: ModulesMap.APM,
		title: 'Application Monitoring',
		desc:
			'Monitor application metrics like p99 latency, error rates, external API calls, and db calls.',
	},
	LogsManagement: {
		id: ModulesMap.LogsManagement,
		title: 'Logs Management',
		desc:
			'Easily filter and query logs, build dashboards and alerts based on attributes in logs',
	},
	InfrastructureMonitoring: {
		id: ModulesMap.InfrastructureMonitoring,
		title: 'Infrastructure Monitoring',
		desc:
			'Monitor Kubernetes infrastructure metrics, hostmetrics, or metrics of any third-party integration',
	},
	AwsMonitoring: {
		id: ModulesMap.AwsMonitoring,
		title: 'AWS Monitoring',
		desc:
			'Monitor your traces, logs and metrics for AWS services like EC2, ECS, EKS etc.',
	},
	AzureMonitoring: {
		id: ModulesMap.AzureMonitoring,
		title: 'Azure Monitoring',
		desc:
			'Monitor your traces, logs and metrics for Azure services like AKS, Container Apps, App Service etc.',
	},
};

export default function Onboarding(): JSX.Element {
	const [selectedModule, setSelectedModule] = useState<ModuleProps>(
		useCases.APM,
	);

	const [selectedModuleSteps, setSelectedModuleSteps] = useState(APM_STEPS);
	const [activeStep, setActiveStep] = useState(1);
	const [current, setCurrent] = useState(0);
	const { location } = history;
	const { t } = useTranslation(['onboarding']);
	const { safeNavigate } = useSafeNavigate();

	const { featureFlags } = useAppContext();
	const isOnboardingV3Enabled = featureFlags?.find(
		(flag) => flag.name === FeatureKeys.ONBOARDING_V3,
	)?.active;

	const {
		selectedDataSource,
		selectedEnvironment,
		selectedMethod,
		updateSelectedModule,
		updateSelectedDataSource,
		resetProgress,
		updateActiveStep,
		updateIngestionData,
	} = useOnboardingContext();

	useEffectOnce(() => {
		logEvent('Onboarding V2 Started', {});
	});

	const { status, data: ingestionData } = useQuery({
		queryFn: () => getIngestionData(),
	});

	useEffect(() => {
		if (
			status === 'success' &&
			ingestionData &&
			ingestionData &&
			Array.isArray(ingestionData.payload)
		) {
			const payload = ingestionData.payload[0] || {
				ingestionKey: '',
				dataRegion: '',
			};

			updateIngestionData({
				SIGNOZ_INGESTION_KEY: payload?.ingestionKey,
				REGION: payload?.dataRegion,
			});
		}
		// eslint-disable-next-line react-hooks/exhaustive-deps
	}, [status, ingestionData?.payload]);

	const setModuleStepsBasedOnSelectedDataSource = (
		selectedDataSource: DataSourceType | null,
	): void => {
		if (selectedDataSource) {
			let steps: SelectedModuleStepProps[] = [];

			steps = getSteps({
				selectedDataSource,
			});

			setSelectedModuleSteps(steps);
		}
	};

	const removeStep = (
		stepToRemove: string,
		steps: SelectedModuleStepProps[],
	): SelectedModuleStepProps[] =>
		steps.filter((step) => step.id !== stepToRemove);

	const handleAPMSteps = (): void => {
		if (selectedEnvironment === 'kubernetes') {
			const updatedSteps = removeStep(stepsMap.selectMethod, APM_STEPS);
			setSelectedModuleSteps(updatedSteps);

			return;
		}

		if (selectedMethod === OnboardingMethods.QUICK_START) {
			const updatedSteps = removeStep(stepsMap.setupOtelCollector, APM_STEPS);
			setSelectedModuleSteps(updatedSteps);

			return;
		}

		setSelectedModuleSteps(APM_STEPS);
	};

	// eslint-disable-next-line sonarjs/cognitive-complexity
	useEffect(() => {
		if (selectedModule?.id === ModulesMap.InfrastructureMonitoring) {
			if (selectedDataSource) {
				setModuleStepsBasedOnSelectedDataSource(selectedDataSource);
			} else {
				setSelectedModuleSteps(INFRASTRUCTURE_MONITORING_STEPS);
				updateSelectedDataSource(defaultInfraMetricsType);
			}
		} else if (selectedModule?.id === ModulesMap.LogsManagement) {
			if (selectedDataSource) {
				setModuleStepsBasedOnSelectedDataSource(selectedDataSource);
			} else {
				setSelectedModuleSteps(LOGS_MANAGEMENT_STEPS);
				updateSelectedDataSource(defaultLogsType);
			}
		} else if (selectedModule?.id === ModulesMap.AwsMonitoring) {
			if (selectedDataSource) {
				setModuleStepsBasedOnSelectedDataSource(selectedDataSource);
			} else {
				setSelectedModuleSteps(AWS_MONITORING_STEPS);
				updateSelectedDataSource(defaultAwsServices);
			}
		} else if (selectedModule?.id === ModulesMap.AzureMonitoring) {
			if (selectedDataSource) {
				setModuleStepsBasedOnSelectedDataSource(selectedDataSource);
			} else {
				setSelectedModuleSteps(AZURE_MONITORING_STEPS);
				updateSelectedDataSource(defaultAzureServices);
			}
		} else if (selectedModule?.id === ModulesMap.APM) {
			handleAPMSteps();

			if (!selectedDataSource) {
				updateSelectedDataSource(defaultApplicationDataSource);
			}
		}

		// eslint-disable-next-line react-hooks/exhaustive-deps
	}, [selectedModule, selectedDataSource, selectedEnvironment, selectedMethod]);

	const handleNextStep = (): void => {
		if (activeStep <= 3) {
			const nextStep = activeStep + 1;

			// on next
			logEvent('Onboarding V2: Get Started', {
				selectedModule: selectedModule.id,
				nextStepId: nextStep,
			});

			setActiveStep(nextStep);
			setCurrent(current + 1);

			// set the active step info
			updateActiveStep({
				module: selectedModule,
				step: selectedModuleSteps[current],
			});
		}
	};

	const handleNext = (e?: React.MouseEvent): void => {
		if (activeStep <= 3) {
			safeNavigate(moduleRouteMap[selectedModule.id as ModulesMap], {
				newTab: !!e && isModifierKeyPressed(e),
			});
		}
	};

	const handleModuleSelect = (module: ModuleProps): void => {
		setSelectedModule(module);
		updateSelectedModule(module);
		updateSelectedDataSource(null);
	};

	const handleBackNavigation = (): void => {
		setCurrent(0);
		setActiveStep(1);
		setSelectedModule(useCases.APM);
		resetProgress();
	};

	useEffect(() => {
		const { pathname } = location;

		if (pathname === ROUTES.GET_STARTED_APPLICATION_MONITORING) {
			handleModuleSelect(useCases.APM);
			updateSelectedDataSource(defaultApplicationDataSource);
			handleNextStep();
		} else if (pathname === ROUTES.GET_STARTED_INFRASTRUCTURE_MONITORING) {
			handleModuleSelect(useCases.InfrastructureMonitoring);
			handleNextStep();
		} else if (pathname === ROUTES.GET_STARTED_LOGS_MANAGEMENT) {
			handleModuleSelect(useCases.LogsManagement);
			handleNextStep();
		} else if (pathname === ROUTES.GET_STARTED_AWS_MONITORING) {
			handleModuleSelect(useCases.AwsMonitoring);
			handleNextStep();
		} else if (pathname === ROUTES.GET_STARTED_AZURE_MONITORING) {
			handleModuleSelect(useCases.AzureMonitoring);
			handleNextStep();
		} else {
			handleBackNavigation();
		}
		// eslint-disable-next-line react-hooks/exhaustive-deps
	}, [location.pathname]);

	const [form] = Form.useForm<InviteMemberFormValues>();
	const [isInviteTeamMemberModalOpen, setIsInviteTeamMemberModalOpen] =
		useState<boolean>(false);

	const toggleModal = useCallback(
		(value: boolean): void => {
			setIsInviteTeamMemberModalOpen(value);
			if (!value) {
				form.resetFields();
			}
		},
		[form],
	);

	return (
		<div className="container">
			{activeStep === 1 && (
				<div className="onboarding-page">
					<div
						onClick={(e): void => {
							logEvent('Onboarding V2: Skip Button Clicked', {});
							safeNavigate(ROUTES.APPLICATION, { newTab: isModifierKeyPressed(e) });
						}}
						className="skip-to-console"
					>
						{t('skip')}
					</div>
					<FullScreenHeader />
					<div className="onboardingHeader">
						<h1>{t('select_use_case')}</h1>
					</div>
					<div className="modulesContainer">
						<div className="moduleContainerRowStyles">
							{Object.keys(ModulesMap).map((module) => {
								const selectedUseCase = (useCases as any)[module];

								return (
									<Card
										className={cx(
											'moduleStyles',
											selectedModule.id === selectedUseCase.id ? 'selected' : '',
										)}
										key={selectedUseCase.id}
										onClick={(): void => handleModuleSelect(selectedUseCase)}
									>
										<Typography.Title className="moduleTitleStyle" level={4}>
											{selectedUseCase.title}
										</Typography.Title>
										<Typography.Paragraph className="moduleDesc">
											{selectedUseCase.desc}
										</Typography.Paragraph>
									</Card>
								);
							})}
						</div>
					</div>
					<div className="continue-to-next-step">
						<Button
							type="primary"
							icon={<ArrowRightOutlined />}
							onClick={(e): void => handleNext(e)}
						>
							{t('get_started')}
						</Button>
					</div>
					<div className="invite-member-wrapper">
						<Typography.Text className="helper-text">
							{t('invite_user_helper_text')}
						</Typography.Text>
						<div className="invite-member">
							<Typography.Text>{t('invite_user')}</Typography.Text>
							<Button
								onClick={(): void => {
									logEvent('Onboarding V2: Invite Member', {
										module: selectedModule?.id,
										page: 'homepage',
									});
									setIsInviteTeamMemberModalOpen(true);
								}}
								icon={<UserPlus size={16} />}
								type="primary"
							>
								{t('invite')}
							</Button>
						</div>
					</div>
				</div>
			)}

			{activeStep > 1 && (
				<div className="stepsContainer">
					<ModuleStepsContainer
						onReselectModule={(e?: React.MouseEvent): void => {
							setCurrent(current - 1);
							setActiveStep(activeStep - 1);
							setSelectedModule(useCases.APM);
							resetProgress();

							const path = isOnboardingV3Enabled
								? ROUTES.GET_STARTED_WITH_CLOUD
								: ROUTES.GET_STARTED;
							safeNavigate(path, { newTab: !!e && isModifierKeyPressed(e) });
						}}
						selectedModule={selectedModule}
						selectedModuleSteps={selectedModuleSteps}
						setIsInviteTeamMemberModalOpen={setIsInviteTeamMemberModalOpen}
					/>
				</div>
			)}
			<InviteUserModal
				form={form}
				isInviteTeamMemberModalOpen={isInviteTeamMemberModalOpen}
				toggleModal={toggleModal}
				onClose={(): void => {}}
			/>
		</div>
	);
}
