import {
	Badge,
	Box,
	Button,
	Container,
	Flex,
	Heading,
	HStack,
	Icon,
	Link,
	Stack,
	Text,
	Tooltip,
	useColorMode,
	useColorModeValue,
	useMediaQuery,
	useToast,
	VStack,
} from '@chakra-ui/react';
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';
import { __ } from '@wordpress/i18n';
import humanizeDuration from 'humanize-duration';
import React, { useEffect, useMemo, useState } from 'react';
import { BiCalendar } from 'react-icons/bi';
import {
	BsArrowsCollapseVertical,
	BsArrowsExpandVertical,
} from 'react-icons/bs';
import { useNavigate, useParams } from 'react-router-dom';
import { CustomIcon } from '../../../../assets/js/back-end/components/common/CustomIcon';
import { GoogleMeet } from '../../../../assets/js/back-end/constants/images';
import urls from '../../../../assets/js/back-end/constants/urls';
import { ContentQueryError } from '../../../../assets/js/back-end/schemas';
import API from '../../../../assets/js/back-end/utils/api';
import { getWordpressLocalTime } from '../../../../assets/js/back-end/utils/utils';
import ContentErrorDisplay from '../../../../assets/js/interactive/components/ContentErrorDisplay';
import ContentNav from '../../../../assets/js/interactive/components/ContentNav';
import { COLORS_BASED_ON_SCREEN_COLOR_MODE } from '../../../../assets/js/interactive/constants/general';
import { useCourseContext } from '../../../../assets/js/interactive/context/CourseContext';
import { CourseProgressItemsMap } from '../../../../assets/js/interactive/schemas';
import LessonSkeleton from '../../../../assets/js/interactive/skeleton/LessonSkeleton';
import localized from '../../../../assets/js/interactive/utils/global';
import { getContentWidths } from '../../../../assets/js/interactive/utils/helper';
import RedirectNavigation, {
	navigationProps,
} from '../../../../assets/js/interactive/utils/RedirectNavigation';
import GoogleMeetUrls from '../../constants/urls';
import { GoogleMeetStatus } from '../Enums/Enum';
import MeetingTimer from './MeetingTimer';

const InteractiveGoogleMeet = () => {
	const { googleMeetId, courseId }: any = useParams();
	const GoogleMeetAPI = new API(GoogleMeetUrls.googleMeets);
	const courseAPI = new API(urls.courses);
	const progressItemAPI = new API(urls.courseProgressItem);
	const toast = useToast();
	const queryClient = useQueryClient();
	const [meetingStarted, setMeetingStarted] = useState(false);
	const navigate = useNavigate();
	const [status, setStatus] = React.useState<string>('');
	const { colorMode } = useColorMode();
	const {
		courseProgress,
		courseData,
		setActiveIndex,
		setContentData,
		isSidebarOpen,
		setActiveContentId,
	} = useCourseContext();

	const [isLargerThan1100] = useMediaQuery('(min-width: 1100px)');
	const [isLargerThan1400] = useMediaQuery('(min-width: 1400px)');
	const isFocusModeEnabled = useMemo(() => {
		return Boolean(localized?.enableFocusMode === 'yes');
	}, []);

	const headerColor = useColorModeValue('oxford-night', 'white');

	const [contentWidth, setContentWidth] = useState<string>(
		getContentWidths(isLargerThan1400)[isFocusModeEnabled ? 1 : 0],
	);

	const isLargestContentWidthEnabledBasedOnScreenSize = useMemo(() => {
		const contentWidths = getContentWidths(isLargerThan1400);
		return Boolean(contentWidth === contentWidths[contentWidths?.length - 1]);
	}, [contentWidth, isLargerThan1400]);

	// To set active bg on sidebar item.
	useEffect(() => {
		setActiveContentId(googleMeetId);
	}, [googleMeetId, setActiveContentId]);

	const googleMeetQuery = useQuery<any, ContentQueryError>({
		queryKey: [`google-meet${googleMeetId}`, googleMeetId],
		queryFn: () => GoogleMeetAPI.get(googleMeetId),
	});

	const completeQuery = useQuery<CourseProgressItemsMap>({
		queryKey: [`completeQuery${googleMeetId}`, googleMeetId],
		queryFn: () =>
			progressItemAPI.list({
				item_id: googleMeetId,
				courseId: courseId,
			}),
		// Logged-in only; guests 401 here.
		...{
			enabled: Boolean(localized.isUserLoggedIn),
			retry: false,
		},
	});

	const completeMutation = useMutation({
		mutationFn: (data: CourseProgressItemsMap) => progressItemAPI.store(data),
	});

	const onCompletePress = () => {
		completeMutation.mutate(
			{
				course_id: courseId,
				item_id: googleMeetQuery?.data?.id,
				item_type: 'google-meet',
				completed: true,
			},
			{
				onSuccess: () => {
					queryClient.invalidateQueries({
						queryKey: [`completeQuery${googleMeetId}`],
					});
					queryClient.invalidateQueries({
						queryKey: [`courseProgress${courseId}`],
					});

					toast({
						title: __('Google Meet completed.', 'learning-management-system'),
						isClosable: true,
						status: 'success',
					});
					const navigation = googleMeetQuery?.data
						?.navigation as navigationProps;
					RedirectNavigation(navigation, courseId, navigate);
				},
				onError: (err: any) => {
					toast({
						title:
							err?.message ||
							__('Something went wrong', 'learning-management-system'),
						status: 'error',
						isClosable: true,
					});
				},
			},
		);
	};

	const start_at: Date = new Date(googleMeetQuery?.data?.starts_at);
	const end_at: Date = new Date(googleMeetQuery?.data?.ends_at);

	const updateContentWidth = () => {
		const contentWidths = getContentWidths(isLargerThan1400);
		const indexOfCurrentWidth = contentWidths.indexOf(contentWidth);

		if (indexOfCurrentWidth === contentWidths?.length - 1) {
			setContentWidth(contentWidths[0]);
		} else {
			setContentWidth(contentWidths[indexOfCurrentWidth + 1]);
		}
	};

	React.useEffect(() => {
		googleMeetStatus();
		// eslint-disable-next-line react-hooks/exhaustive-deps
	}, [start_at, end_at]);

	const googleMeetStatus = () => {
		if (start_at >= new Date()) {
			setStatus(GoogleMeetStatus.UpComing);
		} else if (start_at < new Date() && end_at > new Date()) {
			setStatus(GoogleMeetStatus.Active);
		} else if (end_at < new Date()) {
			setStatus(GoogleMeetStatus.Expired);
		} else {
			setStatus(GoogleMeetStatus.All);
		}
	};

	useEffect(() => {
		if (googleMeetQuery?.isSuccess) {
			setActiveIndex(googleMeetQuery?.data?.parent_menu_order);
			setContentData(googleMeetQuery?.data);
		}
	}, [
		googleMeetQuery?.data,
		googleMeetQuery?.isSuccess,
		setActiveIndex,
		setContentData,
	]);

	if (
		courseProgress.isSuccess &&
		googleMeetQuery.isSuccess &&
		courseData.isSuccess
	) {
		const previousPage = googleMeetQuery?.data?.navigation?.previous;
		const localStartTime = googleMeetQuery?.data?.starts_at;

		return (
			<VStack height={'100vh'} justify={'space-between'}>
				<Container
					centerContent
					maxW={
						contentWidth !== 'full' ? `container.${contentWidth}` : contentWidth
					}
					py="16"
				>
					{' '}
					<Box
						bg={
							COLORS_BASED_ON_SCREEN_COLOR_MODE[colorMode]
								?.interactiveGoogleMeetBgColor
						}
						shadow="box"
						w="full"
						p={['5', null, '10']}
						rounded={'xl'}
					>
						{localStartTime && !meetingStarted ? (
							<MeetingTimer
								startAt={localStartTime}
								duration={googleMeetQuery?.data?.duration}
								onTimeout={() => setMeetingStarted(true)}
							/>
						) : null}
						<Box>
							<Stack direction="column" spacing="8">
								<HStack
									alignItems={'flex-start'}
									mt={
										contentWidth === 'full' && localStartTime && !meetingStarted
											? '5'
											: '0'
									}
								>
									<Heading as="h5" flex={1} color={headerColor}>
										{googleMeetQuery?.data?.name}
									</Heading>
									<Tooltip
										label={
											!isLargestContentWidthEnabledBasedOnScreenSize
												? __(
														'Expand Content Width',
														'learning-management-system',
													)
												: __(
														'Collapse Content Width',
														'learning-management-system',
													)
										}
									>
										<Flex
											display={isLargerThan1100 ? 'flex' : 'none'}
											justifyContent={'center'}
											alignItems={'center'}
											p={2}
											borderWidth={1}
											borderColor={'transparent'}
											cursor={'pointer'}
											sx={{
												background:
													colorMode === 'dark'
														? 'rgba(0, 0, 0, 0.1)'
														: 'rgba(255, 255, 255, 0.1)',
												backdropFilter: 'blur(10px)',
												borderRadius: '50%',
												transition: 'all 0.3s ease-in-out',
												'&:hover': {
													borderColor:
														colorMode === 'dark' ? 'gray.600' : 'gray.100',
													boxShadow: '0 2px 4px rgba(0, 0, 0, 0.1)',
													'.icon': {
														color:
															colorMode === 'dark' ? 'yellow.500' : 'blue.500',
													},
												},
											}}
											onClick={updateContentWidth}
										>
											<Icon
												as={
													!isLargestContentWidthEnabledBasedOnScreenSize
														? BsArrowsExpandVertical
														: BsArrowsCollapseVertical
												}
												fontSize={'larger'}
												className={'icon'}
											/>
										</Flex>
									</Tooltip>
								</HStack>{' '}
								<Stack spacing={4}>
									<Stack>
										<HStack spacing={4}>
											<HStack
												color={
													COLORS_BASED_ON_SCREEN_COLOR_MODE[colorMode]
														?.interactiveGoogleMeetTextColor
												}
												fontSize="sm"
											>
												<Text fontWeight="medium">
													{__('Time:', 'learning-management-system')}
												</Text>
												<Stack
													direction="row"
													spacing="2"
													alignItems="center"
													color={
														COLORS_BASED_ON_SCREEN_COLOR_MODE[colorMode]
															?.interactiveGoogleMeetTextColor
													}
												>
													<Icon as={BiCalendar} />
													<Text fontSize="15px">
														{getWordpressLocalTime(
															localStartTime,
															'Y-m-d, h:i A',
														)}
													</Text>
												</Stack>
											</HStack>
											{status === GoogleMeetStatus.Active ? (
												<Badge bg="green.500" color="white" fontSize="10px">
													{__('Ongoing', 'learning-management-system')}
												</Badge>
											) : null}
											{status === GoogleMeetStatus.Expired ? (
												<Badge bg="red.500" color="white" fontSize="10px">
													{__('Expired', 'learning-management-system')}
												</Badge>
											) : null}
											{status === GoogleMeetStatus.UpComing ? (
												<Badge bg="primary.500" color="white" fontSize="10px">
													{__('UpComing', 'learning-management-system')}
												</Badge>
											) : null}
										</HStack>

										{+googleMeetQuery?.data?.duration ? (
											<Stack>
												<HStack
													color={
														COLORS_BASED_ON_SCREEN_COLOR_MODE[colorMode]
															?.interactiveGoogleMeetTextColor
													}
													fontSize="sm"
												>
													<Text fontWeight="medium">
														{__('Duration:', 'learning-management-system')}
													</Text>
													<Text>
														{humanizeDuration(
															(googleMeetQuery?.data?.duration || 0) *
																60 *
																1000,
														)}
													</Text>
												</HStack>
											</Stack>
										) : null}

										<Stack>
											<HStack
												color={
													COLORS_BASED_ON_SCREEN_COLOR_MODE[colorMode]
														?.interactiveGoogleMeetTextColor
												}
												fontSize="sm"
											>
												<Text fontWeight="medium">
													{__('Meeting ID:', 'learning-management-system')}
												</Text>
												<Text>{googleMeetQuery?.data?.meeting_id}</Text>
											</HStack>
										</Stack>

										{googleMeetQuery?.data?.password ? (
											<Stack>
												<HStack
													color={
														COLORS_BASED_ON_SCREEN_COLOR_MODE[colorMode]
															?.interactiveGoogleMeetTextColor
													}
													fontSize="sm"
												>
													<Text fontWeight="medium">
														{__('Password:', 'learning-management-system')}
													</Text>
													<Text>{googleMeetQuery?.data?.password}</Text>
												</HStack>
											</Stack>
										) : null}
									</Stack>

									{status === GoogleMeetStatus.Active ||
									status === GoogleMeetStatus.UpComing ? (
										<HStack>
											<Link
												href={googleMeetQuery?.data?.meet_url}
												target="_blank"
											>
												<Button
													colorScheme="blue"
													size="xs"
													leftIcon={
														<CustomIcon icon={GoogleMeet} boxSize="12px" />
													}
													fontWeight="semibold"
												>
													{__('Join Meeting', 'learning-management-system')}
												</Button>
											</Link>
										</HStack>
									) : null}
								</Stack>
								<Text
									className="masteriyo-interactive-description"
									dangerouslySetInnerHTML={{
										__html: googleMeetQuery?.data?.description,
									}}
								/>
							</Stack>
						</Box>
					</Box>
				</Container>
				<ContentNav
					navigation={googleMeetQuery?.data?.navigation}
					courseId={courseId}
					onCompletePress={onCompletePress}
					isButtonLoading={completeMutation.isPending}
					isButtonDisabled={completeQuery?.data?.completed}
				/>
			</VStack>
		);
	} else if (googleMeetQuery.isError) {
		return (
			<ContentErrorDisplay
				code={googleMeetQuery?.error?.code}
				message={googleMeetQuery?.error?.message}
				bg={COLORS_BASED_ON_SCREEN_COLOR_MODE[colorMode]?.lessonBG}
			/>
		);
	}

	return <LessonSkeleton />;
};

export default InteractiveGoogleMeet;
