import React, {memo, useEffect, useState, useRef} from 'react';
import {
  View,
  ScrollView,
  Animated,
  LayoutChangeEvent,
  NativeSyntheticEvent,
  NativeScrollEvent,
} from 'react-native';
import {useTranslation} from 'react-i18next';
import {
  IconClock,
  IconMapPin,
  IconLink,
  IconCalendarExclamation,
  IconCalendarDue,
  IconEyeCheck,
  IconCertificate,
} from '@tabler/icons-react-native';
import {useFocusEffect} from '@react-navigation/native';
import {
  Typography,
  CardContainer,
  Title,
  Chip,
  CroppedBody,
  Link,
  Alert,
} from '@components';
import {Navigation} from '@interfaces/navigation';
import AnimatedHeader from '@modules/learning/components/AnimatedHeader';
import {useGetLearningSession} from '@modules/learning/hooks';
import {getTimeZoneInfo} from '@modules/learning/utils';
import {LearningSessionStatus} from '@modules/learning/interfaces';
import {ANIMATION_CONSTANTS} from '@modules/learning/constants';
import {useInstance, useInstanceId, useUser} from '@redux/selectors';
import {useTheme, SPACING} from '@shared/theme';
import {AMPLITUDE_EVENTS, Screens} from '@shared/constants';
import {getDate, getFullLink, openUrlFromApp} from '@shared/utils';
import {logAmplitudeEvent} from '@shared/utils/logs';

import SessionSk from './components/SessionSk';
import AssistanceFooter from './components/AssistanceFooter';
import {styles} from './styles';
import OptionsDialog from './components/OptionsDialog';

const Session = ({navigation, route}: Navigation<Screens.SESSION>) => {
  const {sessionId, openReason = 'random'} = route.params as {
    sessionId: number;
    openReason?: 'random' | 'notification';
  };
  const {timezone: instanceTimeZone} = useInstance();
  const {data, isLoading, onUpdateAttendance, isUpdatingAttendance} =
    useGetLearningSession(sessionId);
  const {theme, iconSizes} = useTheme();
  const {t} = useTranslation();
  const user = useUser();
  const instanceId = useInstanceId();
  const scrollY = useRef(new Animated.Value(0)).current;

  const [imageHeight, setImageHeight] = useState(
    ANIMATION_CONSTANTS.IMAGE_CONTAINER_HEIGHT,
  );
  const [scrollViewHeight, setScrollViewHeight] = useState(
    ANIMATION_CONSTANTS.IMAGE_CONTAINER_HEIGHT,
  );
  const [contentContainerHeight, setContentContainerHeight] = useState(
    ANIMATION_CONSTANTS.IMAGE_CONTAINER_HEIGHT,
  );
  const onScrollViewLayout = ({nativeEvent}: LayoutChangeEvent) => {
    const {height} = nativeEvent.layout;

    setScrollViewHeight(height);
  };

  const onContentContainerLayout = ({nativeEvent}: LayoutChangeEvent) => {
    const {height} = nativeEvent.layout;
    setContentContainerHeight(height);
  };

  const scheduleValue =
    !data?.startTime || !data?.endTime
      ? ''
      : `${data.startTime} ${t('general:to')} ${data.endTime} ${t(
          'general.hours_short',
        )}`;

  const fields = [
    {
      title: t('learning.session.attendance.title'),
      Icon: IconEyeCheck,
      value: t(
        `learning.${
          data?.isObligatory ? 'session.required' : 'common.optional'
        }`,
      ),
      show: true,
    },
    {
      title: t('learning.session.detail.date'),
      Icon: IconCalendarExclamation,
      value: getDate(data?.localDate),
      show: !!data?.localDate,
    },
    {
      title: t('learning.session.detail.schedule'),
      Icon: IconClock,
      value: scheduleValue,
      show: !!data?.startTime,
    },
    {
      title: t('learning.session.detail.location'),
      Icon: IconMapPin,
      value: data?.address,
      show: !!data?.address,
    },
    {
      title: t('learning.session.detail.link'),
      Icon: IconLink,
      value: data?.meetingLink,
      show: !!data?.meetingLink,
      onPress: () => {
        data?.meetingLink && openUrlFromApp(getFullLink(data?.meetingLink));
      },
    },
    {
      title: t('learning.session.detail.certificate'),
      Icon: IconCertificate,
      show: !!data?.certUrl || data?.issueCertificate,
    },
  ];
  useEffect(() => {
    if (data?.title) {
      navigation.setOptions({
        title: data?.title,
      });
    }
  }, [navigation, data?.title]);

  useFocusEffect(() => {
    if (data?.learningSessionId) {
      logAmplitudeEvent(AMPLITUDE_EVENTS.SESSION_DETAILS_VIEWED, {
        sessionId: data.learningSessionId,
        userId: user.id,
        instanceId,
        openReason,
      });
    }
  });

  const onConfirmAssistance = () => {
    if (data?.learningSessionId) {
      onUpdateAttendance({id: data?.learningSessionId});
      logAmplitudeEvent(AMPLITUDE_EVENTS.SESSION_CONFIRM, {
        sessionId: data.learningSessionId,
        userId: user.id,
        instanceId,
      });
    }
  };

  const animatedImageStyle = {
    transform: [
      {
        scale: scrollY.interpolate({
          inputRange: [0, imageHeight],
          outputRange: ANIMATION_CONSTANTS.OUTPUT_RANGE_IMAGE_SCALE,
          extrapolate: 'clamp',
        }),
      },
    ],
    opacity: scrollY.interpolate({
      inputRange: ANIMATION_CONSTANTS.INPUT_RANGE_IMAGE_OPACITY(imageHeight),
      outputRange: ANIMATION_CONSTANTS.OUTPUT_RANGE_IMAGE_OPACITY,
      extrapolate: 'clamp',
    }),
  };
  const onScroll = (event: NativeSyntheticEvent<NativeScrollEvent>) => {
    const offsetY = event.nativeEvent.contentOffset.y;
    scrollY.setValue(offsetY);
  };
  const paddingBottom =
    contentContainerHeight < scrollViewHeight
      ? scrollViewHeight - contentContainerHeight
      : SPACING.x2;

  const sessionDate = (() => {
    if (!data?.localDate) {
      return '';
    }
    const timeZone = data.timeZone || instanceTimeZone;

    const parsedTimeZone = getTimeZoneInfo(timeZone, data.startDate).replaceAll(
      '_',
      ' ',
    );

    return `${getDate(data.localDate)} • ${data.startTime} ${t(
      'general.hours_short',
    )} ${parsedTimeZone}`;
  })();

  const onJoinSession = () => {
    if (data?.meetingLink) {
      openUrlFromApp(getFullLink(data?.meetingLink));
    }
  };
  const onImageLayout = ({nativeEvent}: LayoutChangeEvent) => {
    const {height} = nativeEvent.layout;
    setImageHeight(height);
  };

  if (isLoading) {
    return <SessionSk />;
  }
  return data ? (
    <View
      style={[styles.flex, {backgroundColor: theme.background.layout.default}]}>
      <AnimatedHeader
        onImageLayout={onImageLayout}
        pictureUrl={data.pictureUrl}
        animatedImageStyle={animatedImageStyle}
        DefaultIcon={IconCalendarDue}
      />
      <ScrollView
        style={styles.flex}
        onLayout={onScrollViewLayout}
        showsVerticalScrollIndicator={false}
        contentContainerStyle={{paddingBottom}}
        onScroll={onScroll}
        scrollEventThrottle={16}
        bounces={false}>
        <View
          style={[
            styles.shadowContainer,
            {
              backgroundColor: theme.background.layout.default,
              marginTop: imageHeight,
            },
          ]}
        />
        <View
          onLayout={onContentContainerLayout}
          style={[
            styles.container,
            {backgroundColor: theme.background.layout.default},
          ]}>
          {data.status === LearningSessionStatus.FINISHED && (
            <Alert
              title={t('learning.session.status.session_finished')}
              description={t('learning.session.status.session_finished_at', {
                date: getDate(data.localDate),
              })}
              variant="highLight"
              style={styles.alert}
            />
          )}
          <View style={[styles.titleCard]}>
            <Chip
              text={
                data.type === 'VIRTUAL'
                  ? t('learning.session.type.virtual_one')
                  : t('learning.session.type.presential_one')
              }
            />
            <Title
              titleNumberOfLines={4}
              descriptionNumberOfLines={2}
              title={data.title}
              style={styles.title}
              description={sessionDate}
            />
          </View>
          <CardContainer style={styles.card}>
            <Typography
              variant="xs"
              color={theme.text.neutral.lighter}
              weight="semiBold">
              {t('learning.common.details')}
            </Typography>
            {fields.map(({Icon, show, title, value, onPress}) => {
              if (!show) {
                return null;
              }

              const iconProps = {
                style: styles.icon,
                size: iconSizes.x4,
                color: theme.text.neutral.default,
              };

              return (
                <View key={title} style={styles.cardDescriptionContainer}>
                  <View style={[styles.flex, styles.textContainer]}>
                    <View style={styles.iconContainer}>
                      <Icon {...iconProps} />
                      <Typography weight="semiBold" style={styles.titleText}>
                        {`${title}${value ? ': ' : ''}`}
                      </Typography>
                    </View>
                    {onPress ? (
                      <View style={styles.linkContainer}>
                        <Link
                          numberOfLines={2}
                          style={styles.link}
                          onPress={onPress}>
                          {value}
                        </Link>
                      </View>
                    ) : (
                      <Typography variant="s" style={styles.valueText}>
                        {value}
                      </Typography>
                    )}
                  </View>
                </View>
              );
            })}
            {data?.description && (
              <View style={styles.descriptionContainer}>
                <CroppedBody
                  bodyLimit={300}
                  textStyle={styles.descriptionText}
                  body={data?.description}
                />
              </View>
            )}
          </CardContainer>
          {data.collaborator && (
            <CardContainer style={styles.card}>
              <Typography
                variant="xs"
                color={theme.text.neutral.lighter}
                weight="semiBold">
                {t('learning.session.detail.instructed_by')}
              </Typography>
              <Typography weight="semiBold">{data.collaborator}</Typography>
            </CardContainer>
          )}
        </View>
      </ScrollView>
      <AssistanceFooter
        onJoinSession={onJoinSession}
        isUpdatingAttendance={isUpdatingAttendance}
        onConfirmAssistance={onConfirmAssistance}
        data={data}
      />
      {!!data && data.status !== LearningSessionStatus.FINISHED && (
        <OptionsDialog session={data} />
      )}
    </View>
  ) : null;
};

export default memo(Session);
